⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sxskincheckbox.pas

📁 skin components for design of your applicastions
💻 PAS
📖 第 1 页 / 共 4 页
字号:
    AATextOffset:Integer;
      FTextWidth:Integer;
     FTextHeight:Integer;
           TH,TW:Integer;
        NewWidth:Integer;
       NewHeight:Integer;

 procedure DoSetCBState;
 begin
  if not SetCBState then
   GetCurrentCBState(CBState);
 end;

begin
 if Parent=nil then exit;
 OldGlyphRect:=FGlyphRect;
 OldTextRect:=FTextRect;
 GlyphChanged:=False;
 TextChanged:=False;
 SetCBState:=False;
 if Params*[cbrpGlyph,cbrpGlyphOnStyleChange,cbrpGlyphOnSizeChange]<>[] then
  begin
   DoSetCBState;
   //
   FGlyphWidth:=CBState.GlyphWidth;
   FGlyphHeight:=CBState.GlyphHeight;
   if (CBState.GlyphStyle<>'') and ((FGlyphWidth=0) or (FGlyphHeight=0)) then
    begin
     A:=SkinLibrary.Styles.GetGStyleIndex(CBState.GlyphStyle,0,0);
     if A>=0 then
      begin
       GlyphStyle:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
       for B:=0 to GlyphStyle.Elements.Count-1 do
        if GlyphStyle.Elements[B] is TSXSkinStyleImageElement then
         begin
          Image:=TSXSkinStyleImageElement(GlyphStyle.Elements[B]);
          Image.ValidateBitmap(SkinLibrary);
          if Image.Bitmap<>nil then
           begin
            if FGlyphWidth=0 then FGlyphWidth:=Image.Bitmap.Width;
            if FGlyphHeight=0 then FGlyphHeight:=Image.Bitmap.Height;
           end;
         end;
      end;
    end;
   //
   if cbrpGlyph in Params then GlyphChanged:=True else
    begin
     if cbrpGlyphOnSizeChange in Params then
      GlyphChanged:=(FGlyphWidth<>FGlyphRect.Right-FGlyphRect.Left) or
                    (FGlyphHeight<>FGlyphRect.Bottom-FGlyphRect.Top);
     if not GlyphChanged and (cbrpGlyphOnStyleChange in Params) then
      GlyphChanged:=(FLastGlyphStyle<>CBState.GlyphStyle);
    end;
   if GlyphChanged then
    FGlyphRect:=Rect(0,0,FGlyphWidth,FGlyphHeight);
   FLastGlyphStyle:=CBState.GlyphStyle;
  end;
 if Params*[cbrpText,cbrpTextOnFontChange,cbrpTextIfWordWrap]<>[] then
  begin
   DoSetCBState;
   if cbrpText in Params then TextChanged:=True else
    if FWordWrap and (cbrpTextIfWordWrap in Params) then TextChanged:=True else
    if cbrpTextOnFontChange in Params then
     TextChanged:=not SameFontData(CBState.FD,FLastFontData);
   if TextChanged then
    begin
     if FTextBitmap<>nil then
      begin
       FTextBitmap.Free;
       FTextBitmap:=nil;
      end;
     FLastFontData:=CBState.FD;
     Canvas.Font.Name:=CBState.FD.FontName;
     Canvas.Font.Size:=CBState.FD.FontSize;
     Canvas.Font.Style:=CBState.FD.FontStyle;
     FTextRect:=Rect(0,0,Width,Height);
     if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed then
      begin
       A:=SkinLibrary.Styles.GetIndexByName(SkinStyle);
       if (A>=0) and (SkinLibrary.Styles[A] is TSXSkinCheckBoxStyle) then
        begin
         case FGlyphPosition of
          gpLeftTop,
          gpLeft,
          gpLeftBottom,
          gpRightTop,
          gpRight,
          gpRightBottom: begin
                          Dec(FTextRect.Right,FGlyphRect.Right-FGlyphRect.Left);
                          if (FLastGlyphStyle<>'') and (Caption<>'') then
                           Dec(FTextRect.Right,FTextOffset);
                          Dec(FTextRect.Right,CBState.CaptionLeftOffset);
                          Dec(FTextRect.Right,CBState.CaptionRightOffset);
                          //
                          Dec(FTextRect.Bottom,CBState.CaptionTopOffset);
                          Dec(FTextRect.Bottom,CBState.CaptionBottomOffset);
                         end;
          gpTop,
          gpBottom:      begin
                          Dec(FTextRect.Right,CBState.CaptionLeftOffset);
                          Dec(FTextRect.Right,CBState.CaptionRightOffset);
                          //
                          Dec(FTextRect.Right,FGlyphRect.Bottom-FGlyphRect.Top);
                          if (FLastGlyphStyle<>'') and (Caption<>'') then
                           Dec(FTextRect.Right,FTextOffset);
                          Dec(FTextRect.Bottom,CBState.CaptionTopOffset);
                          Dec(FTextRect.Bottom,CBState.CaptionBottomOffset);
                         end;
         end;
         Flags:=DT_NOPREFIX or DT_NOCLIP or DT_TOP or DT_CALCRECT;
         case FAlignment of
          taLeftJustify:  Flags:=Flags or DT_LEFT;
          taRightJustify: Flags:=Flags or DT_RIGHT;
          taCenter:       Flags:=Flags or DT_CENTER;
         end;
         if FWordWrap then Flags:=Flags or DT_WORDBREAK;
         Dec(FTextRect.Right,CBState.TextLeftOffset+CBState.TextRightOffset);
         Dec(FTextRect.Bottom,CBState.TextTopOffset+CBState.TextBottomOffset);
         if CBState.FD.SmoothLevel=0 then
          DrawText(Canvas.Handle,PChar(Caption),-1,FTextRect,Flags) else
           DrawSmoothText(Canvas,Caption,FTextRect,Flags,CBState.FD.SmoothLevel);
         Inc(FTextRect.Right,CBState.TextLeftOffset+CBState.TextRightOffset);
         Inc(FTextRect.Bottom,CBState.TextTopOffset+CBState.TextBottomOffset);
         FLastTextLeftOffset:=CBState.TextLeftOffset;
         FLastTextTopOffset:=CBState.TextTopOffset;
         FLastTextRightOffset:=CBState.TextRightOffset;
         FLastTextBottomOffset:=CBState.TextBottomOffset;
        end;
      end;
    end;
   FLastFontData:=CBState.FD;
  end;
 //
 if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed then
  begin
   A:=SkinLibrary.Styles.GetIndexByName(SkinStyle);
   if (A>=0) and (SkinLibrary.Styles[A] is TSXSkinCheckBoxStyle) then
    begin
     DoSetCBState;
     FTextWidth:=FTextRect.Right-FTextRect.Left;
     FTextHeight:=FTextRect.Bottom-FTextRect.Top;
     AATextOffset:=0;
     AAGlyphOffset:=0;
     if FAutoAlignFirstLine and (FGlyphPosition in [gpLeftTop,gpRightTop]) and
        not IsRectEmpty(FGlyphRect) then
      begin
       if CBState.FD.SmoothLevel=0 then
        TH:=Canvas.TextHeight(Caption) else
         GetRenderedTextSize(Canvas,Caption,CBState.FD.SmoothLevel,TW,TH);
       AATextOffset:=(FGlyphHeight-TH) div 2-CBState.TextTopOffset;
       if (FGlyphHeight-TH) mod 2<>0 then Inc(AATextOffset);
       if AATextOffset<0 then
        begin
         AAGlyphOffset:=-AATextOffset;
         AATextOffset:=0;
        end;
      end else
     if FGlyphPosition in [gpLeft,gpRight] then
      begin
       AAGlyphOffset:=(FTextHeight-FGlyphHeight) div 2;
       if AAGlyphOffset<0 then
        begin
         AATextOffset:=-AAGlyphOffset;
         AAGlyphOffset:=0;
        end;
      end else
     if FGlyphPosition in [gpLeftBottom,gpRightBottom] then
      begin
       AAGlyphOffset:=FTextHeight-FGlyphHeight;
       if AAGlyphOffset<0 then
        begin
         AATextOffset:=-AAGlyphOffset;
         AAGlyphOffset:=0;
        end;
      end;
     //
     NewWidth:=Width; NewHeight:=Height;
     if FAutoSizeWidth or FAutoSizeHeight then
      begin
       case FGlyphPosition of
        gpLeftTop,
        gpLeft,
        gpLeftBottom,
        gpRightTop,
        gpRight,
        gpRightBottom: begin
                        NewWidth:=FGlyphWidth+FTextWidth+FTextOffset+
                                  CBState.CaptionLeftOffset+
                                  CBState.CaptionRightOffset;
                        NewHeight:=CBState.CaptionTopOffset+
                                   CBState.CaptionBottomOffset+
                                   Max(FGlyphHeight+AAGlyphOffset,FTextHeight+AATextOffset);
                       end;
        gpTop,
        gpBottom:      begin
                        NewWidth:=CBState.CaptionLeftOffset+
                                  CBState.CaptionRightOffset+
                                  Max(FGlyphWidth,FTextWidth);
                        NewHeight:=CBState.CaptionTopOffset+
                                   CBState.CaptionBottomOffset+FTextOffset+
                                   FGlyphHeight+FTextHeight;
                       end;
       end;
       if not FAutoSizeWidth then NewWidth:=Width;
       if not FAutoSizeHeight then NewHeight:=Height;
      end;
     //
     case FGlyphPosition of
      gpLeftTop,
      gpLeft,
      gpLeftBottom:  begin
                      FGlyphRect.Left:=CBState.CaptionLeftOffset;
                      FGlyphRect.Top:=CBState.CaptionTopOffset+AAGlyphOffset;
                      //
                      FTextRect.Left:=FGlyphRect.Left+FGlyphWidth+FTextOffset;
                      FTextRect.Top:=CBState.CaptionTopOffset+AATextOffset;
                     end;
      gpTop:         begin
                      FGlyphRect.Left:=(NewWidth-FGlyphWidth+CBState.CaptionLeftOffset-CBState.CaptionRightOffset) div 2;
                      FGlyphRect.Top:=CBState.CaptionTopOffset;
                      //
                      FTextRect.Left:=(NewWidth-FTextWidth+CBState.CaptionLeftOffset-CBState.CaptionRightOffset) div 2;
                      FTextRect.Top:=FGlyphRect.Top+FGlyphHeight+FTextOffset;
                     end;
      gpRightTop,
      gpRight,
      gpRightBottom: begin
                      FTextRect.Left:=CBState.CaptionLeftOffset;
                      FTextRect.Top:=CBState.CaptionTopOffset+AATextOffset;
                      //
                      FGlyphRect.Left:=FTextRect.Left+FTextWidth+FTextOffset;
                      FGlyphRect.Top:=CBState.CaptionTopOffset+AAGlyphOffset;
                     end;
      gpBottom:      begin
                      FTextRect.Left:=(NewWidth-FTextWidth+CBState.CaptionLeftOffset-CBState.CaptionRightOffset) div 2;
                      FTextRect.Top:=CBState.CaptionTopOffset;
                      //
                      FGlyphRect.Left:=(NewWidth-FGlyphWidth+CBState.CaptionLeftOffset-CBState.CaptionRightOffset) div 2;
                      FGlyphRect.Top:=FTextRect.Top+FTextHeight+FTextOffset;
                     end;
     end;
     FGlyphRect.Right:=FGlyphRect.Left+FGlyphWidth;
     FGlyphRect.Bottom:=FGlyphRect.Top+FGlyphHeight;
     FTextRect.Right:=FTextRect.Left+FTextWidth;
     FTextRect.Bottom:=FTextRect.Top+FTextHeight;
     //
     if (Width<>NewWidth) or (Height<>NewHeight) then
      InternalSetBounds(Left,Top,NewWidth,NewHeight);
     if not FAutoSizeHeight and (FVerticalAlignment<>taAlignTop) then
      begin
       Offset:=0;
       case FVerticalAlignment of
        taVerticalCenter: Offset:=(Height-Max(FGlyphRect.Bottom,FTextRect.Bottom)-
                                   Min(FGlyphRect.Top,FTextRect.Top)) div 2;
        taAlignBottom:    Offset:=Height-Max(FGlyphRect.Bottom,FTextRect.Bottom)-
                                  2*Min(FGlyphRect.Top,FTextRect.Top);
       end;
       Inc(FGlyphRect.Top,Offset);
       Inc(FGlyphRect.Bottom,Offset);
       Inc(FTextRect.Top,Offset);
       Inc(FTextRect.Bottom,Offset);
      end;
    end;
  end;
 //Invalidating Regions
 if GlyphChanged or not EqualRect(OldGlyphRect,FGlyphRect) then
  begin
   if HandleAllocated then
    begin
     InvalidateRect(Handle,@OldGlyphRect,False);
     InvalidateRect(Handle,@FGlyphRect,False);
    end;
  end;
 if TextChanged or not EqualRect(OldTextRect,FTextRect) then
  begin
   if HandleAllocated then
    begin
     InvalidateRect(Handle,@OldTextRect,False);
     InvalidateRect(Handle,@FTextRect,False);
    end;
  end;
 //
 if cbrpInvalidateOnStyleChange in Params then
  begin
   DoSetCBState;
   if (CBState.Style<>FLastStyle) or (CBState.OverStyle<>FLastOverStyle) then
    begin
     if HandleAllocated then
      InvalidateRect(Handle,nil,False);
     FLastStyle:=CBState.Style;
     FLastOverStyle:=CBState.OverStyle;
    end;
  end;
end;

function TSXSkinCustomCheckBox.IsTransparent(X,Y:Integer;Limit:Integer=10):Boolean;
var    A:Integer;
   Style:TSXSkinGeneralStyle;
 CBState:TSXSkinCheckBoxStateParam;
begin
 Result:=True;
 if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed then
  begin
   GetCurrentCBState(CBState);
   A:=SkinLibrary.Styles.GetGStyleIndex(CBState.Style,Width,Height);
   if A>=0 then
    begin
     Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
     Result:=Style.IsTransparent(Self,CEID_Back,X,Y,Width,Height,SkinLibrary,Limit,VComparer);
    end;
   if Result then
    begin
     A:=SkinLibrary.Styles.GetGStyleIndex(CBState.OverStyle,Width,Height);
     if A>=0 then
      begin
       Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
       Result:=Style.IsTransparent(Self,CEID_Back,X,Y,Width,Height,SkinLibrary,Limit,VComparer);
      end;
    end;
   if Result then
    begin
     A:=SkinLibrary.Styles.GetGStyleIndex(CBState.GlyphStyle,Width,Height);
     if A>=0 then
      begin
       Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
       Result:=Style.IsTransparent(Self,CEID_Glyph,X,Y,Width,Height,SkinLibrary,Limit);
      end;
    end;
  end;
end;

function TSXSkinCustomCheckBox.CapturesMouseAt(X,Y:Integer):Boolean;
var    A:Integer;
   Style:TSXSkinGeneralStyle;
 CBState:TSXSkinCheckBoxStateParam;
begin
 Result:=True;
 if (SkinLibrary<>nil) and SkinLibrary.CanBeUsed then
  begin
   GetCurrentCBState(CBState);
   A:=SkinLibrary.Styles.GetGStyleIndex(CBState.Style,Width,Height);
   if A>=0 then
    begin
     Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
     Result:=Style.CapturesMouseAt(Self,CEID_Back,X,Y,Width,Height,SkinLibrary,VComparer);
    end;
   if not Result then
    begin
     A:=SkinLibrary.Styles.GetGStyleIndex(CBState.OverStyle,Width,Height);
     if A>=0 then
      begin
       Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
       Result:=Style.CapturesMouseAt(Self,CEID_Back,X,Y,Width,Height,SkinLibrary,VComparer);
      end;
    end;
   if not Result then
    begin
     A:=SkinLibrary.Styles.GetGStyleIndex(CBState.GlyphStyle,FGlyphRect.Right-FGlyphRect.Left,FGlyphRect.Bottom-FGlyphRect.Top);
     if A>=0 then
      begin
       Style:=TSXSkinGeneralStyle(SkinLibrary.Styles[A]);
       Result:=Style.CapturesMouseAt(Self,CEID_Glyph,X-FGlyphRect.Left,Y-FGlyphRect.Top,
          FGlyphRect.Right-FGlyphRect.Left,FGlyphRect.Bottom-FGlyphRect.Top,
          SkinLibrary);
      end;
    end;
  end;
end;

constructor TSXSkinCustomCheckBox.Create(AOwner:TComponent);
begin
 inherited Create(AOwner);
 CEID_Back:=GetNewCElementID;
 CEID_Glyph:=GetNewCElementID;
 VComparer:=TSXCheckBoxVariableComparer.Create;
 VComparer.Control:=Self;
 VComparer.OnGetVariable:=OnGetVariable;
 ControlStyle:=ControlStyle+[csSetCaption]-[csDoubleClicks];
 FAutoSizeWidth:=True;
 FAutoSizeHeight:=True;
 FAutoAlignFirstLine:=True;
 FTextOffset:=2;
 FGlyphPosition:=gpLeftTop;
 SkinStyle:='_CheckBox';
 TabStop:=True;
end;

destructor TSXSkinCustomCheckBox.Destroy;
begin
 FThread.Free;
 FTextBitmap.Free;
 FLastGlyph.Free;
 FLastCheckBox.Free;
 inherited;
 VComparer.Free; 
end;

end.

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -