From e90a4cab8b3d0580b2275b425cfee0d139c7e7bc Mon Sep 17 00:00:00 2001 From: marc Date: Thu, 3 Jul 2008 23:47:36 +0000 Subject: [PATCH] * fixed transparency of speedbutton glyph (issue #11571) git-svn-id: trunk@15668 - --- lcl/buttons.pp | 16 +++++++++-- lcl/include/buttonglyph.inc | 49 ++++++++++++++++++++++++++++++-- lcl/include/rasterimage.inc | 56 +++++++++++++++++-------------------- lcl/include/speedbutton.inc | 32 +++++++++++++-------- 4 files changed, 107 insertions(+), 46 deletions(-) diff --git a/lcl/buttons.pp b/lcl/buttons.pp index 053a836f2b..6713afd58c 100644 --- a/lcl/buttons.pp +++ b/lcl/buttons.pp @@ -74,6 +74,12 @@ type TButton = StdCtrls.TButton; { TButtonGlyph } + TGlyphTransparencyMode = ( + gtmGlyph, // transparency is defined by the glyph itself (bitbtn) + gtmOpaque, // transparent = false is defined by the owner (speedbutton) + gtmTransparent // transparent = true + ); + TButtonGlyph = class(TObject, IUnknown, IImageCacheListener) private @@ -83,6 +89,7 @@ type FNumGlyphs: TNumGlyphs; FOnChange: TNotifyEvent; FImagesCache: TImageListCache; + FTransparentMode: TGlyphTransparencyMode; // set by our owner to indicate that the glyphbitmap should be transparent function GetHeight: Integer; function GetWidth: Integer; procedure SetGlyph(Value: TBitmap); @@ -99,6 +106,9 @@ type procedure CacheSetImageIndex(AIndex, AImageIndex: Integer); procedure GlyphChanged(Sender: TObject); + procedure SetTransparentMode(AValue: TGlyphTransparencyMode); + + property TransparentMode: TGlyphTransparencyMode read FTransparentMode; public constructor Create; destructor Destroy; override; @@ -232,7 +242,6 @@ type FShortcut: TShortCut; FShowAccelChar: boolean; FShowCaption: boolean; - FTransparent: Boolean; FAllowAllUp: Boolean; FDown: Boolean; FDownLoaded : Boolean;// value of Down set during loading @@ -242,11 +251,12 @@ type function GetGlyph: TBitmap; procedure SetShowCaption(const AValue: boolean); procedure UpdateExclusive; + function GetTransparent: Boolean; procedure SetAllowAllUp(Value: Boolean); procedure SetGlyph(Value: TBitmap); procedure SetLayout(const Value: TButtonLayout); procedure SetShowAccelChar(Value: boolean); - procedure SetTransparent(const Value: boolean); + procedure SetTransparent(const AValue: boolean); procedure CMButtonPressed(var Message: TLMessage); message CM_BUTTONPRESSED; procedure CMEnabledChanged(var Message: TLMessage); message CM_ENABLEDCHANGED; private @@ -307,7 +317,7 @@ type property ShowAccelChar: boolean read FShowAccelChar write SetShowAccelChar default true; property ShowCaption: boolean read FShowCaption write SetShowCaption default true; property Spacing: integer read FSpacing write SetSpacing default 4; - property Transparent: Boolean read FTransparent write SetTransparent default true; + property Transparent: Boolean read GetTransparent write SetTransparent default true; end; diff --git a/lcl/include/buttonglyph.inc b/lcl/include/buttonglyph.inc index b516359a29..361eb40c87 100644 --- a/lcl/include/buttonglyph.inc +++ b/lcl/include/buttonglyph.inc @@ -15,13 +15,50 @@ ***************************************************************************** } +type + + { TGlyphBitmap } + + TGlyphBitmap = class(TBitmap) + private + FOwner: TButtonGlyph; + protected + procedure SetTransparent(AValue: Boolean); override; + public + procedure Assign(ASource: TPersistent); override; + constructor Create(AOwner: TButtonGlyph); + end; + +procedure TGlyphBitmap.Assign(ASource: TPersistent); +begin + inherited Assign(ASource); + if FOwner.FTransparentMode = gtmGlyph then Exit; + inherited SetTransparent(FOwner.FTransparentMode = gtmTransparent); +end; + +constructor TGlyphBitmap.Create(AOwner: TButtonGlyph); +begin + FOwner := AOwner; + inherited Create; + inherited SetTransparent(True); +end; + +procedure TGlyphBitmap.SetTransparent(AValue: Boolean); +begin + if FOwner.FTransparentMode = gtmGlyph + then inherited SetTransparent(AValue) + else inherited SetTransparent(FOwner.FTransparentMode = gtmTransparent); +end; + + + {------------------------------------------------------------------------------} { TButtonGlyph Constructor } {------------------------------------------------------------------------------} constructor TButtonGlyph.Create; begin FImagesCache := nil; - FOriginal := TBitmap.Create; + FOriginal := TGlyphBitmap.Create(Self); FOriginal.OnChange := @GlyphChanged; end; @@ -86,7 +123,7 @@ begin if FOriginal = Value then exit; if FOriginal = nil then - FOriginal := TBitmap.Create; + FOriginal := TGlyphBitmap.Create(Self); FOriginal.OnChange := nil; FOriginal.Assign(Value); FOriginal.OnChange := @GlyphChanged; @@ -180,6 +217,14 @@ begin end; end; +procedure TButtonGlyph.SetTransparentMode(AValue: TGlyphTransparencyMode); +begin + if AValue = FTransparentMode then Exit; + FTransparentMode := AValue; + if FTransparentMode = gtmGlyph then Exit; + FOriginal.Transparent := FTransparentMode = gtmTransparent; +end; + procedure TButtonGlyph.ClearImages; var i: TButtonState; diff --git a/lcl/include/rasterimage.inc b/lcl/include/rasterimage.inc index 867411c242..30318ff7bf 100644 --- a/lcl/include/rasterimage.inc +++ b/lcl/include/rasterimage.inc @@ -31,35 +31,31 @@ begin then begin // TRasterImage can share image data - // -> check if already shared - if SrcImage.FSharedImage = FSharedImage then Exit;// already sharing - - // MWE: dont call ChangingAll, since it will create a new image, - // which we will replace anyway. - // ChangingAll(Self); - - //DebugLn(['TRasterImage.Assign Self=',ClassName,' Source=',Source.ClassName,' HandleAllocated=',HandleAllocated,' Canvas=',DbgSName(FCanvas)]); FTransparent := SrcImage.Transparent; + FTransparentMode := SrcImage.TransparentMode; + FTransparentColor := SrcImage.TransparentColor; - //DebugLn('TRasterImage.Assign A RefCount=',FImage.RefCount); - // image is not shared => new image data - // -> free canvas (interface handles) - FreeCanvasContext; - // release old FImage - FSharedImage.Release; - // share FImage with assigned graphic - FSharedImage := SrcImage.FSharedImage; - FSharedImage.Reference; - - // We only can share images of the same type. - // Since we "share" it first, the unshare code will create a copy - if not CanShareImage(SrcImage.GetSharedImageClass) + // -> check if already shared + if SrcImage.FSharedImage <> FSharedImage then begin - UnshareImage(True); - FreeSaveStream; + // image is not shared => new image data + // -> free canvas (interface handles) + FreeCanvasContext; + // release old FImage + FSharedImage.Release; + // share FImage with assigned graphic + FSharedImage := SrcImage.FSharedImage; + FSharedImage.Reference; + + // We only can share images of the same type. + // Since we "share" it first, the unshare code will create a copy + if not CanShareImage(SrcImage.GetSharedImageClass) + then begin + UnshareImage(True); + FreeSaveStream; + end; end; - //DebugLn(['TRasterImage.Assign B ',Width,',',Height,' ',HandleAllocated,' RefCount=',FImage.RefCount]); Changed(Self); Exit; @@ -303,9 +299,9 @@ end; procedure TRasterImage.SetTransparentColor(AValue: TColor); begin - if FTransparentColor = AValue then exit; + if TransparentColor = AValue then exit; FTransparentColor := AValue; - if FTransparentMode <> tmFixed then Exit; + if TransparentMode <> tmFixed then Exit; CreateMask; end; @@ -571,8 +567,8 @@ begin if (Width = 0) or (Height = 0) or (AColor = clNone) - or ( (FTransparentMode = tmFixed) - and (FTransparentColor = clNone) + or ( (TransparentMode = tmFixed) + and (TransparentColor = clNone) and (AColor = clDefault) ) then begin @@ -597,8 +593,8 @@ begin if AColor = clDefault then begin - if (FTransparentMode = tmFixed) and (FTransparentColor <> clDefault) - then TransColor := ColorToRGB(FTransparentColor) + if (TransparentMode = tmFixed) and (TransparentColor <> clDefault) + then TransColor := ColorToRGB(TransparentColor) else TransColor := FPColorToTColor(IntfImage.Colors[0, stopy]); end else TransColor := ColorToRGB(AColor); diff --git a/lcl/include/speedbutton.inc b/lcl/include/speedbutton.inc index 5ea9192a72..a1194b3d37 100644 --- a/lcl/include/speedbutton.inc +++ b/lcl/include/speedbutton.inc @@ -42,10 +42,11 @@ constructor TCustomSpeedButton.Create(AOwner: TComponent); begin inherited Create(AOwner); FGlyph := TButtonGlyph.Create; + FGlyph.SetTransparentMode(gtmTransparent); FGlyph.OnChange := @GlyphChanged; SetInitialBounds(0,0,GetControlClassDefaultSize.X,GetControlClassDefaultSize.Y); - ControlStyle := ControlStyle + [csCaptureMouse]-[csSetCaption, csClickEvents]; + ControlStyle := ControlStyle + [csCaptureMouse]-[csSetCaption, csClickEvents, csOpaque]; FLayout:= blGlyphLeft; FAllowAllUp:= false; @@ -54,7 +55,6 @@ begin FShowAccelChar:=true; FSpacing := 4; FMargin := -1; - FTransparent := true; Color := clBtnFace; FShowCaption := true; end; @@ -811,16 +811,19 @@ end; Returns: nothing ------------------------------------------------------------------------------} -procedure TCustomSpeedButton.SetTransparent(const Value : boolean); +procedure TCustomSpeedButton.SetTransparent(const AValue : boolean); +const + MODE: array[Boolean] of TGlyphTransparencyMode = (gtmOpaque, gtmTransparent); begin - if Value <> FTransparent then begin - FTransparent:= Value; - if Value then - ControlStyle:= ControlStyle - [csOpaque] - else - ControlStyle:= ControlStyle + [csOpaque]; - Invalidate; - end; + if AValue = Transparent then Exit; + + if AValue then + ControlStyle := ControlStyle - [csOpaque] + else + ControlStyle := ControlStyle + [csOpaque]; + + FGlyph.SetTransparentMode(MODE[AValue]); + Invalidate; end; {------------------------------------------------------------------------------ @@ -930,6 +933,13 @@ begin end; end; +function TCustomSpeedButton.GetTransparent: Boolean; +begin + if FGlyph.TransparentMode = gtmGlyph + then Result := FGlyph.FOriginal.Transparent + else Result := FGlyph.TransparentMode = gtmTransparent; +end; + function TCustomSpeedButton.DrawGlyph(ACanvas: TCanvas; const AClient: TRect; const AOffset: TPoint; AState: TButtonState; ATransparent: Boolean; BiDiFlags: Longint): TRect;