lazarus/lcl/include/buttonglyph.inc
paul d27b65a627 ButtonGlyph:
- allow setting bigger glyphcount than 4 (limited by High(TGlyphCount)). current limit is 5
- clear imagelist and imageindexes after glyph change to prevent possible garbage drawing

git-svn-id: trunk@13295 -
2007-12-12 14:19:25 +00:00

222 lines
6.1 KiB
PHP

{%MainUnit ../buttons.pp}
{
*****************************************************************************
* *
* This file is part of the Lazarus Component Library (LCL) *
* *
* See the file COPYING.modifiedLGPL, included in this distribution, *
* for details about the copyright. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. *
* *
*****************************************************************************
}
{------------------------------------------------------------------------------}
{ TButtonGlyph Constructor }
{------------------------------------------------------------------------------}
constructor TButtonGlyph.Create;
begin
FImagesCache := nil;
FOriginal := TBitmap.Create;
FOriginal.OnChange := @GlyphChanged;
end;
{------------------------------------------------------------------------------
TButtonGlyph destructor
------------------------------------------------------------------------------}
destructor TButtonGlyph.Destroy;
begin
if FImagesCache <> nil then
begin
FImagesCache.UnregisterListener(Self);
FImagesCache := nil; // cache can free on unregister
end;
FOriginal.Free;
FOriginal := nil;
inherited Destroy;
end;
procedure TButtonGlyph.GetImageIndexAndEffect(State: TButtonState;
var AIndex: Integer; var AEffect: TGraphicsDrawEffect);
var
AStoredState: TButtonState;
begin
AStoredState := bsUp;
AEffect := gdeNormal;
case State of
bsDisabled:
begin
if NumGlyphs > 1 then
AStoredState := State
else
AEffect := gdeDisabled;
end;
bsDown:
begin
if NumGlyphs > 2 then
AStoredState := State
else
AEffect := gdeShadowed;
end;
bsExclusive:
if NumGlyphs > 3 then
AStoredState := State
else
AEffect := gdeNormal;
bsHot:
if NumGlyphs > 4 then
AStoredState := State
else
AEffect := gdeHighlighted;
end;
AIndex := FImageIndexes[AStoredState];
end;
{------------------------------------------------------------------------------
TButtonGlyph SetGlyph
------------------------------------------------------------------------------}
procedure TButtonGlyph.SetGlyph(Value : TBitmap);
var
GlyphCount : integer;
begin
if FOriginal = Value then
exit;
if FOriginal = nil then
FOriginal := TBitmap.Create;
FOriginal.OnChange := nil;
FOriginal.Assign(Value);
FOriginal.OnChange := @GlyphChanged;
FNumGlyphs := 1;
if (FOriginal <> nil) and (FOriginal.Height > 0) then
begin
if FOriginal.Width mod FOriginal.Height = 0 then
begin
GlyphCount := FOriginal.Width div FOriginal.Height;
if GlyphCount > High(TNumGlyphs) then
GlyphCount := Low(TNumGlyphs);
FNumGlyphs := TNumGlyphs(GlyphCount);
end;
end;
GlyphChanged(FOriginal);
end;
function TButtonGlyph.GetHeight: Integer;
begin
if FImages <> nil then
Result := FImages.Height
else
Result := 0;
end;
function TButtonGlyph.GetWidth: Integer;
begin
if FImages <> nil then
Result := FImages.Width
else
Result := 0;
end;
procedure TButtonGlyph.GlyphChanged(Sender: TObject);
begin
if FImagesCache <> nil then
begin
FImagesCache.UnregisterListener(Self);
FImagesCache := nil; // cache can free on unregister
ClearImages;
end;
if (FOriginal.Width > 0) and (FOriginal.Height > 0) then
begin
FImagesCache := GetImageListCache;
FImagesCache.RegisterListener(Self);
FImagesCache.RegisterBitmap(Self, FOriginal, Max(1, NumGlyphs));
end;
if Sender = FOriginal then
if Assigned(FOnChange) then
FOnChange(Self);
end;
{------------------------------------------------------------------------------
TButtonGlyph Draw
------------------------------------------------------------------------------}
function TButtonGlyph.Draw(Canvas: TCanvas; const Client: TRect;
const Offset: TPoint; State: TButtonState; Transparent: Boolean;
BiDiFlags: Longint): TRect;
var
ImgID: integer;
AEffect: TGraphicsDrawEffect;
begin
Result := Client;
if (FOriginal = nil) then
exit;
if (Width = 0) or (Height = 0) or
(Client.Left >= Client.Right) or (Client.Top >= Client.Bottom) then
Exit;
GetImageIndexAndEffect(State, ImgID, AEffect);
FImages.Draw(Canvas, Client.Left + Offset.X, Client.Top + Offset.y, ImgID,
AEffect);
// ToDo: VCL returns the text rectangle
end;
{------------------------------------------------------------------------------
TButtonGlyph SetNumGlyphs
------------------------------------------------------------------------------}
procedure TButtonGlyph.SetNumGlyphs(Value : TNumGlyphs);
begin
if Value <> FNumGlyphs then
begin
FNumGlyphs := Value;
GlyphChanged(FOriginal);
end;
end;
procedure TButtonGlyph.ClearImages;
var
i: TButtonState;
begin
FImages := nil;
for i := Low(TButtonState) to High(TButtonState) do
FImageIndexes[i] := -1;
end;
function TButtonGlyph.QueryInterface(const iid: tguid; out obj): longint; stdcall;
begin
if GetInterface(iid, obj) then
Result := 0
else
Result := E_NOINTERFACE;
end;
function TButtonGlyph._AddRef: longint; stdcall;
begin
Result := -1;
end;
function TButtonGlyph._Release: longint; stdcall;
begin
Result := -1;
end;
procedure TButtonGlyph.CacheSetImageList(AImageList: TCustomImageList);
begin
FImages := AImageList;
end;
procedure TButtonGlyph.CacheSetImageIndex(AIndex, AImageIndex: Integer);
begin
if (AIndex >= ord(Low(TButtonState))) and (AIndex <= Ord(High(TButtonState))) then
FImageIndexes[TButtonState(AIndex)] := AImageIndex;
end;
// included by buttons.pp