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

📄 spcategorybuttons.pas

📁 DynamicSkinForm.v9.15.For.Delphi.BCB 很好的皮肤控件
💻 PAS
📖 第 1 页 / 共 5 页
字号:
      GetObject(Canvas.Font.Handle, SizeOf(F), @F);
      F.lfEscapement := round(0);
      Buffer.Canvas.Font.Handle := CreateFontIndirect(F);
    end;

  if (spboBoldCaptions in ButtonOptions) then
    Buffer.Canvas.Font.Style := Canvas.Font.Style - [fsBold];

  if not Category.Collapsed then
  begin
    { Draw the buttons }
    if (FButtonFlow = bscbfVertical) and (spboFullSize in ButtonOptions) then
      ActualWidth := ClientWidth - FSideBufferSize - GetScrollSize - 5
    else
      ActualWidth := FButtonWidth;

    ButtonStart := ButtonBounds.Left;
    ButtonTop := ButtonBounds.Top;
    ButtonLeft := ButtonStart;
    for I := 0 to Category.Items.Count - 1 do
    begin
      { Don't waste time painting clipped things }
      if (FButtonFlow = bscbfVertical) and (ButtonTop > ClientHeight) then
        Break; { Done drawing }

      { Don't waste time drawing what is offscreen }
      ButtonBottom := ButtonTop + FButtonHeight;
      ButtonRight := ButtonLeft + ActualWidth;
      if (ButtonBottom >= 0) and (ButtonRight >= 0) then
      begin
        ButtonRect := Rect(ButtonLeft, ButtonTop, ButtonRight, ButtonBottom);

        Button := Category.Items[I];
        DrawState := [];
        if Button = FHotButton then
        begin
          Include(DrawState, spbdsHot);
          if Button = FDownButton then
            Include(DrawState, spbdsDown);
        end;
        if Button = FSelectedItem then
          Include(DrawState, spbdsSelected)
        else if (Button = FFocusedItem) and Focused and (FDownButton = nil) then
          Include(DrawState, spbdsFocused);

        if Button = FInsertTop then
          Include(DrawState, spbdsInsertTop)
        else if Button = FInsertBottom then
          Include(DrawState, spbdsInsertBottom)
        else if Button = FInsertRight then
          Include(DrawState, spbdsInsertRight)
        else if Button = FInsertLeft then
          Include(DrawState, spbdsInsertLeft);

        BR := ButtonRect;
        OffsetRect(BR, -CategoryRealBounds.Left, -CategoryRealBounds.Top);
        DrawButton(Button, Buffer.Canvas, BR, DrawState);
      end;
      Inc(ButtonLeft, ActualWidth);

      if (ButtonLeft + ActualWidth) > ButtonBounds.Right then
      begin
        ButtonLeft := ButtonStart;
        Inc(ButtonTop, FButtonHeight);
      end;
    end;
  end;

  Canvas.Draw(CategoryRealBounds.Left, CategoryRealBounds.Top, Buffer);
  Buffer.Free;
end;

procedure TspSkinCategoryButtons.Paint;

procedure DrawSkinBGRect(R: TRect);
var
  PanelData: TspDataSkinPanelControl;
  w, h, X, Y, XCnt, YCnt: Integer;
  Buffer, Buffer2: TBitMap;
  FSkinPicture: TBitMap;
begin
  if (RectWidth(R) <= 0) or (RectHeight(R) <= 0) then Exit;
  PanelData := TspDataSkinPanelControl(SkinData.CtrlList[SkinData.GetControlIndex('panel')]);
  Buffer := TBitMap.Create;
  with PanelData do
  begin
    FSkinPicture := TBitMap(SkinData.FActivePictures.Items[PictureIndex]);
    Buffer.Width := RectWidth(ClRect);
    Buffer.Height := RectHeight(ClRect);
    Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height),
        FSkinPicture.Canvas,
          Rect(SkinRect.Left + ClRect.Left, SkinRect.Top + ClRect.Top,
               SkinRect.Left + ClRect.Right,
               SkinRect.Top + ClRect.Bottom));
    w := RectWidth(ClRect);
    h := RectHeight(ClRect);
    XCnt := RectWidth(R) div w;
    YCnt := RectHeight(R) div h;
    if StretchEffect
      then
        begin
          case StretchType of
            spstFull:
              Canvas.StretchDraw(R, Buffer);
            spstHorz:
              begin
                Buffer2 := TBitMap.Create;
                Buffer2.Width := Buffer.Width;
                Buffer2.Height := RectHeight(R);
                Buffer2.Canvas.StretchDraw(Rect(0, 0, Buffer2.Width, Buffer2.Height), Buffer);
                XCnt := Width div Buffer2.Width;
                 for X := 0 to XCnt do
                   Canvas.Draw(R.Left + X * Buffer2.Width, R.Top, Buffer2);
                 Buffer2.Free;
              end;
            spstVert:
              begin
                Buffer2 := TBitMap.Create;
                Buffer2.Width := RectWidth(R);
                Buffer2.Height := Buffer.Height;
                Buffer2.Canvas.StretchDraw(Rect(0, 0, Buffer2.Width, Buffer2.Height), Buffer);
                YCnt := RectHeight(R) div Buffer2.Height;
                for Y := 0 to YCnt do
                  Canvas.Draw(R.Left, R.Top + Y * Buffer2.Height, Buffer2);
                Buffer2.Free;
              end;
          end;
        end
     else
    for X := 0 to XCnt do
    for Y := 0 to YCnt do
      Canvas.Draw(X * w + R.Left, Y * h + R.Top, Buffer);
  end;
  Buffer.Free;
end;

var
  TopCategory: Integer;
  CatIndex: Integer;
  StartingPos: Integer;
  EndingPos: Integer;
  Category: TspButtonCategory;
  DrawRect: TRect;
begin
  StartingPos := 0;
  TopCategory := GetIndexOfFirstCategory;
  if (TopCategory > -1) and (TopCategory < FButtonCategories.Count) then
  begin
    { Calculate the virtual position and ending position }
    StartingPos := FButtonCategories[TopCategory].FStart - GetScrollOffset;
    if FButtonFlow = bscbfVertical then
      EndingPos := ClientHeight
    else
      EndingPos := ClientWidth;
    for CatIndex := TopCategory to FButtonCategories.Count - 1 do
    begin
      Category := FButtonCategories[CatIndex];
      DrawCategory(Category, Canvas, StartingPos);
      StartingPos := StartingPos + Category.FEnd - Category.FStart;
      { Stop drawing early, if we can }
      if StartingPos > EndingPos then
        Break;
    end;
  end;
  //
  Canvas.Brush.Color := clBtnFace;
  //
  if (FButtonFlow = bscbfVertical) and
     (StartingPos < ClientHeight)
  then
    begin
      DrawRect := Rect(0, StartingPos, ClientWidth,
        ClientHeight);
      if (SkinData <> nil) and (not Skindata.Empty) and
            (SkinData.GetControlIndex('panel') <> -1)
      then
        DrawSkinBGRect(DrawRect)
      else
        Canvas.FillRect(DrawRect);
    end
  else
  if (FButtonFlow = bscbfHorizontal) and
     (StartingPos < ClientWidth)
  then
    begin
      DrawRect := Rect(StartingPos, 0, ClientWidth,
        ClientHeight);
      if (SkinData <> nil) and (not Skindata.Empty) and
            (SkinData.GetControlIndex('panel') <> -1)
      then
        DrawSkinBGRect(DrawRect)
      else
        Canvas.FillRect(DrawRect);
    end
end;


function TspSkinCategoryButtons.CalcButtonsPerRow: Integer;
begin
  if spboFullSize in ButtonOptions
  then
    Result := 1
  else
  begin
    Result := (ClientWidth - GetScrollSize - FSideBufferSize - 1) div FButtonWidth;
    if Result * FButtonWidth > ClientWidth - GetScrollSize - FSideBufferSize - 1
    then
      Dec(Result)
    else
    if (Result + 1) * FButtonWidth < ClientWidth - GetScrollSize - FSideBufferSize - 1
    then
      Inc(Result);
    if Result <= 0 then Result := 1;
  end;
end;

function TspSkinCategoryButtons.CalcButtonsPerCol: Integer;
begin
  Result := (ClientHeight - FSideBufferSize - GetScrollSize - 1) div FButtonHeight;
  if Result * FButtonHeight > ClientHeight - FSideBufferSize - GetScrollSize
  then
    Dec(Result)
  else
  if (Result + 1) * FButtonHeight < ClientHeight - FSideBufferSize - GetScrollSize
  then
    Inc(Result);
  if Result = 0 then
    Result := 1;
end;

const
  cScrollBarKind: array[TspCatButtonFlow] of Integer = (SB_VERT, SB_HORZ);

procedure TspSkinCategoryButtons.Resize;

  function CalcCategoryHeights: Integer;
  var
    I: Integer;
    Category: TspButtonCategory;
    Y: Integer;
    ButtonsPerRow: Integer;
  begin
    ButtonsPerRow := CalcButtonsPerRow;
    Y := 0;
    for I := 0 to FButtonCategories.Count - 1 do
    begin
      Category := FButtonCategories[I];
      Category.FStart := Y;
      Category.FEnd := Y + CalcCategoryHeight(Category, ButtonsPerRow);
      Y := Category.FEnd;
    end;
    Result := Y;
  end;

  function CalcCategoryWidths: Integer;
  var
    I: Integer;
    Category: TspButtonCategory;
    X: Integer;
    ButtonsPerCol: Integer;
  begin
    ButtonsPerCol := CalcButtonsPerCol;
    X := 0;
    for I := 0 to FButtonCategories.Count - 1 do
    begin
      Category := FButtonCategories[I];
      Category.FStart := X;
      Category.FEnd := X + CalcCategoryWidth(Category, ButtonsPerCol);
      X := Category.FEnd;
    end;
    Result := X;
  end;

var
  ScrollInfo: TScrollInfo;
  TotalAmount: Integer;
  AmountSeen: Integer;
begin
  inherited;
  if (not HandleAllocated) or (FGutterSize = 0) then
    Exit;

  if FButtonFlow = bscbfVertical then
  begin
    TotalAmount := CalcCategoryHeights;
    AmountSeen := ClientHeight;
  end
  else
  begin
    TotalAmount := CalcCategoryWidths;
    AmountSeen := ClientWidth;
  end;

  { Do we have to take the scrollbar into consideration? }
  if (TotalAmount > AmountSeen) then
  begin
    { The max size is the number of "rows of buttons" that are hidden }
    FScrollBarMax := TotalAmount div FGutterSize;
    ScrollInfo.nMax := FScrollBarMax;

    AmountSeen := AmountSeen div FGutterSize;
    if FScrollBarMax > AmountSeen then
      FPageAmount := AmountSeen
    else
      FPageAmount := FScrollBarMax;

    { Adjust the max to NOT contain the page amount }
    FScrollBarMax := FScrollBarMax - FPageAmount + 1;

    if FScrollBarPos > FScrollBarMax then
      FScrollBarPos := FScrollBarMax;

    ScrollInfo.cbSize := SizeOf(TScrollInfo);
    ScrollInfo.fMask := SIF_RANGE or SIF_POS or SIF_PAGE;
    ScrollInfo.nMin := 0;
    ScrollInfo.nPos := FScrollBarPos;
    ScrollInfo.nPage := FPageAmount;
    if FSkinScrollBar = nil
    then
      begin
        ShowSkinScrollBar(True);
      end;
    FSkinScrollBar.SetRange(ScrollInfo.nMin, ScrollInfo.nMax,
        FScrollBarPos, ScrollInfo.nPage);
  end
  else
  begin
    FScrollBarPos := 0;
    FScrollBarMax := 0;
    if FSkinScrollBar <> nil
    then
      begin
        ShowSkinScrollBar(False);
      end;
  end;
end;

procedure TspSkinCategoryButtons.SetButtonHeight(const Value: Integer);
begin
  if FButtonHeight <> Value then
  begin
    FButtonHeight := Value;
    Resize;
    UpdateAllButtons;
  end;
end;

procedure TspSkinCategoryButtons.SetButtonCategories(const Value: TspButtonCategories);
begin
  FButtonCategories.Assign(Value);
end;

procedure TspSkinCategoryButtons.SetCatButtonOptions(const Value: TspCatButtonOptions);
begin
  if FButtonOptions <> Value then
  begin
    FButtonOptions := Value;
    CalcBufferSizes;
    Resize;
    UpdateAllButtons;
  end;
end;

procedure TspSkinCategoryButtons.SetButtonWidth(const Value: Integer);
begin
  if FButtonWidth <> Value then
  begin
    FButtonWidth := Value;
    Resize;
    UpdateAllButtons;
  end;
end;

procedure TspSkinCategoryButtons.SBChange(Sender: TObject);
var
  ScrollCode: TScrollCode;
begin
  ScrollCode := scPosition;
  ScrollPosChanged(TScrollCode(ScrollCode), FSkinScrollBar.Position);
end;

procedure TspSkinCategoryButt

⌨️ 快捷键说明

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