SkinCtrls.pas
上传用户:hylc_2004
上传日期:2014-01-23
资源大小:46800k
文件大小:456k
源码类别:

Delphi控件源码

开发平台:

Delphi

  1.         Self.HRollButtonRect := HRollButtonRect;
  2.         Self.HRollButtonActiveRect := HRollButtonActiveRect;
  3.         if IsNullRect(Self.HRollButtonActiveRect)
  4.         then Self.HRollButtonActiveRect := Self.HRollButtonRect;
  5.         Self.HRollButtonDownRect := HRollButtonDownRect;
  6.         if IsNullRect(Self.HRollButtonDownRect)
  7.         then Self.HRollButtonDownRect := Self.HRollButtonActiveRect;
  8.         Self.HRestoreButtonRect := HRestoreButtonRect;
  9.         Self.HRestoreButtonActiveRect := HRestoreButtonActiveRect;
  10.         if IsNullRect(Self.HRestoreButtonActiveRect)
  11.         then Self.HRestoreButtonActiveRect := Self.HRestoreButtonRect;
  12.         Self.HRestoreButtonDownRect := HRestoreButtonDownRect;
  13.         if IsNullRect(Self.HRestoreButtonDownRect)
  14.         then Self.HRestoreButtonDownRect := Self.HRestoreButtonActiveRect;
  15.         Self.VRollButtonRect := VRollButtonRect;
  16.         Self.VRollButtonActiveRect := VRollButtonActiveRect;
  17.         if IsNullRect(Self.VRollButtonActiveRect)
  18.         then Self.VRollButtonActiveRect := Self.VRollButtonRect;
  19.         Self.VRollButtonDownRect := VRollButtonDownRect;
  20.         if IsNullRect(Self.VRollButtonDownRect)
  21.         then Self.VRollButtonDownRect := Self.VRollButtonActiveRect;
  22.         Self.VRestoreButtonRect := VRestoreButtonRect;
  23.         Self.VRestoreButtonActiveRect := VRestoreButtonActiveRect;
  24.         if IsNullRect(Self.VRestoreButtonActiveRect)
  25.         then Self.VRestoreButtonActiveRect := Self.VRestoreButtonRect;
  26.         Self.VRestoreButtonDownRect := VRestoreButtonDownRect;
  27.         if IsNullRect(Self.VRestoreButtonDownRect)
  28.         then Self.VRestoreButtonDownRect := Self.VRestoreButtonActiveRect;
  29.       end;
  30. end;
  31. procedure TspSkinExPanel.SetBounds(ALeft, ATop, AWidth, AHeight: Integer);
  32. begin
  33.   if FRollState and not StopCheckSize
  34.   then
  35.     begin
  36.       if (FRollKind = rkRollHorizontal) and (AWidth <> GetRollWidth)
  37.       then AWidth := GetRollWidth
  38.       else
  39.       if (FRollKind = rkRollVertical) and (AHeight <> GetRollHeight)
  40.       then AHeight := GetRollHeight
  41.     end;
  42.   inherited;
  43. end;
  44. procedure TspSkinExPanel.CMTextChanged;
  45. begin
  46.   inherited;
  47.   RePaint;
  48. end;
  49. procedure TspSkinExPanel.SetShowRollButton(Value: Boolean);
  50. begin
  51.   FShowRollButton := Value;
  52.   RePaint;
  53. end;
  54. procedure TspSkinExPanel.SetShowCloseButton(Value: Boolean);
  55. begin
  56.   FShowCloseButton := Value;
  57.   RePaint;
  58. end;
  59. function TspSkinExPanel.GetRollWidth: Integer;
  60. begin
  61.   if FIndex = -1
  62.   then
  63.     Result := FDefaultCaptionHeight
  64.   else
  65.     Result := RectWidth(RollHSkinRect);
  66. end;
  67. function TspSkinExPanel.GetRollHeight: Integer;
  68. begin
  69.   if FIndex = -1
  70.   then
  71.     Result := FDefaultCaptionHeight
  72.   else
  73.     Result := RectHeight(RollVSkinRect);
  74. end;
  75. procedure TspSkinExPanel.SetRollKind(Value: TspExPanelRollKind);
  76. begin
  77.   FRollKind := Value;
  78.   RePaint;
  79. end;
  80. procedure TspSkinExPanel.SetDefaultCaptionHeight;
  81. begin
  82.   FDefaultCaptionHeight := Value;
  83.   if FIndex = -1
  84.   then
  85.     begin
  86.       RePaint;
  87.       ReAlign;
  88.     end
  89. end;
  90. procedure TspSkinExPanel.CreateControlDefaultImage(B: TBitMap);
  91. var
  92.   R, CR: TRect;
  93.   BW, CROffset, TX, TY: Integer;
  94.   F: TLogFont;
  95. begin
  96.   BW := FDefaultCaptionHeight - 6;
  97.   R := Rect(0, 0, Width, Height);
  98.   if FRollState and (FRollKind = rkRollHorizontal)
  99.   then
  100.     with B.Canvas do
  101.     begin
  102.       Brush.Color := clBtnFace;
  103.       FillRect(R);
  104.       CR := R;
  105.       Frame3D(B.Canvas, R, clBtnShadow, clBtnShadow, 1);
  106.       Frame3D(B.Canvas, R, clBtnHighLight, clBtnFace, 1);
  107.       CROffset := 0;
  108.       if FShowCloseButton
  109.       then
  110.         begin
  111.           begin
  112.             Buttons[0].R := Rect(3, 3, 3 + BW, 3 + BW);
  113.             CROffset := CROffset + RectHeight(Buttons[0].R);
  114.           end;
  115.         end
  116.       else
  117.         Buttons[0].R := Rect(0, 0, 0, 3);
  118.       if FShowRollButton
  119.       then
  120.         begin
  121.           Buttons[1].R := Rect(3, Buttons[0].R.Bottom, 3 + BW, Buttons[0].R.Bottom + BW);
  122.           CROffset := CROffset + RectHeight(Buttons[1].R);
  123.         end
  124.       else
  125.         Buttons[1].R := Rect(0, 0, 0, 0);
  126.       //
  127.       Font := DefaultFont;
  128.       GetObject(Font.Handle, SizeOf(F), @F);
  129.       F.lfEscapement := round(900);
  130.       Font.Handle := CreateFontIndirect(F);
  131.       Inc(CR.Top, CROffset + 2);
  132.       TX := CR.Left + RectWidth(CR) div 2 - TextHeight(Caption) div 2;
  133.       TY := CR.Top + RectHeight(CR) div 2 + TextWidth(Caption) div 2;
  134.       if TY > CR.Bottom - 2 then TY := CR.Bottom - 2;
  135.       Brush.Style := bsClear;
  136.       TextRect(CR, TX, TY, Caption);
  137.       //
  138.     end
  139.   else
  140.     with B.Canvas do
  141.     begin
  142.       Frame3D(B.Canvas, R, clBtnShadow, clBtnShadow, 1);
  143.       Brush.Color := clBtnFace;
  144.       FillRect(R);
  145.       CR := Rect(0, 0, Width, FDefaultCaptionHeight);
  146.       CROffset := 0;
  147.       Frame3D(B.Canvas, CR, clBtnShadow, clBtnShadow, 1);
  148.       Frame3D(B.Canvas, CR, clBtnHighLight, clBtnFace, 1);
  149.       if FShowCloseButton
  150.       then
  151.         begin
  152.           Buttons[0].R := Rect(Width - BW - 2, 3, Width - 2, 3 + BW);
  153.           CROffset := CROffset + RectWidth(Buttons[1].R);
  154.         end
  155.       else
  156.         Buttons[0].R := Rect(Width - 2, 0, 0, 0);
  157.       if FShowRollButton
  158.       then
  159.         begin
  160.           Buttons[1].R := Rect(Buttons[0].R.Left - BW, 3, Buttons[0].R.Left, 3 + BW);
  161.           CROffset := CROffset + RectWidth(Buttons[1].R);
  162.         end
  163.       else
  164.         Buttons[1].R := Rect(0, 0, 0, 0);
  165.       //
  166.       Inc(CR.Left, 2);
  167.       Dec(CR.Right, CROffset + 2);
  168.       //
  169.       Brush.Style := bsClear;
  170.       Font := DefaultFont;
  171.       //
  172.       SPDrawText2(B.Canvas, Caption, CR);
  173.      end;
  174.   if FShowCloseButton then DrawButton(B.Canvas, 0);
  175.   if FShowRollButton then DrawButton(B.Canvas, 1);
  176. end;
  177. procedure TspSkinExPanel.CreateControlSkinImage(B: TBitMap);
  178. var
  179.   CR: TRect;
  180.   F: TLogFont;
  181.   CROffset, BO, TX, TY: Integer;
  182. begin
  183.   with B.Canvas.Font do
  184.   begin
  185.     Name := FontName;
  186.     Style := FontStyle;
  187.     Color := FontColor;
  188.     Height := FontHeight;
  189.   end;
  190.   B.Canvas.Brush.Style := bsClear;
  191.   if FRollState and (FRollKind = rkRollHorizontal)
  192.   then
  193.     begin
  194.       CreateVSkinImage(RollTopOffset, RollBottomOffset,
  195.         B, Picture, RollHSkinRect, GetRollWidth, Height);
  196.       CR := RollHCaptionRect;
  197.       Inc(CR.Bottom, Height - RectHeight(RollHSkinRect));
  198.       CROffset := 0;
  199.       BO := 0;
  200.       if FShowCloseButton
  201.       then
  202.         begin
  203.           begin
  204.             Buttons[0].R := Rect(CR.Left, CR.Top,
  205.               CR.Left + RectWidth(Self.CloseButtonRect),
  206.               CR.Top + RectHeight(Self.CloseButtonRect));
  207.             CROffset := CROffset + RectHeight(Buttons[0].R);
  208.             BO := 2;
  209.           end;
  210.         end
  211.       else
  212.         Buttons[0].R := Rect(0, 0, 0, CR.Top);
  213.       if FShowRollButton
  214.       then
  215.         begin
  216.           Buttons[1].R := Rect(CR.Left, Buttons[0].R.Bottom + BO,
  217.             CR.Left + RectWidth(Self.HRollButtonRect),
  218.             Buttons[0].R.Bottom + RectHeight(Self.HRollButtonRect) + BO);
  219.           CROffset := CROffset + RectHeight(Buttons[1].R) + BO;
  220.         end
  221.       else
  222.         Buttons[1].R := Rect(0, 0, 0, 0);
  223.       Inc(CR.Top, CROffset);
  224.       GetObject(B.Canvas.Font.Handle, SizeOf(F), @F);
  225.       F.lfEscapement := round(900);
  226.       B.Canvas.Font.Handle := CreateFontIndirect(F);
  227.       TX := CR.Left + RectWidth(CR) div 2 - B.Canvas.TextHeight(Caption) div 2;
  228.       TY := CR.Top + RectHeight(CR) div 2 + B.Canvas.TextWidth(Caption) div 2;
  229.       if TY > CR.Bottom - 2 then TY := CR.Bottom - 2;
  230.       B.Canvas.TextRect(CR, TX, TY, Caption);
  231.     end
  232.   else
  233.     if FRollState and (FRollKind = rkRollVertical)
  234.     then
  235.       begin
  236.         CreateHSkinImage(RollLeftOffset, RollRightOffset,
  237.           B, Picture, RollVSkinRect, Width, GetRollHeight);
  238.         CR := RollVCaptionRect;
  239.         Inc(CR.Right, Width - RectWidth(RollVSkinRect));
  240.         CROffset := 0;
  241.         BO := 0;
  242.         if FShowCloseButton
  243.         then
  244.          begin
  245.            Buttons[0].R := Rect(CR.Right - RectWidth(CloseButtonRect), CR.Top,
  246.              CR.Right, CR.Top + RectHeight(CloseButtonRect));
  247.            CROffset := CROffset + RectWidth(Buttons[1].R);
  248.            BO := 2;
  249.          end
  250.         else
  251.           Buttons[0].R := Rect(CR.Right, 0, 0, 0);
  252.         if FShowRollButton
  253.         then
  254.           begin
  255.             Buttons[1].R := Rect(Buttons[0].R.Left - RectWidth(VRollButtonRect) - BO,
  256.             CR.Top, Buttons[0].R.Left - BO, CR.Top + RectHeight(VRollButtonRect));
  257.             CROffset := CROffset + RectWidth(Buttons[1].R) + BO;
  258.           end
  259.         else
  260.           Buttons[1].R := Rect(0, 0, 0, 0);
  261.         Dec(CR.Right, CROffset);
  262.         SPDrawText2(B.Canvas, Caption, CR);
  263.       end
  264.    else
  265.      begin
  266.        inherited;
  267.        CR := CaptionRect;
  268.        Inc(CR.Right, Width - RectWidth(SkinRect));
  269.        CROffset := 0;
  270.        BO := 0;
  271.        if FShowCloseButton
  272.        then
  273.         begin
  274.           Buttons[0].R := Rect(CR.Right - RectWidth(CloseButtonRect), CR.Top,
  275.            CR.Right, CR.Top + RectHeight(CloseButtonRect));
  276.           CROffset := CROffset + RectWidth(Buttons[1].R);
  277.           BO := 2;
  278.         end
  279.        else
  280.          Buttons[0].R := Rect(CR.Right, 0, 0, 0);
  281.        if FShowRollButton
  282.        then
  283.          begin
  284.            Buttons[1].R := Rect(Buttons[0].R.Left - RectWidth(VRollButtonRect) - BO,
  285.            CR.Top, Buttons[0].R.Left - BO, CR.Top + RectHeight(VRollButtonRect));
  286.            CROffset := CROffset + RectWidth(Buttons[1].R) + BO;
  287.          end
  288.        else
  289.          Buttons[1].R := Rect(0, 0, 0, 0);
  290.        Dec(CR.Right, CROffset);
  291.        SPDrawText2(B.Canvas, Caption, CR);
  292.      end;
  293.   if FShowCloseButton then DrawButton(B.Canvas, 0);
  294.   if FShowRollButton then DrawButton(B.Canvas, 1);
  295. end;
  296. procedure TspSkinExPanel.AdjustClientRect(var Rect: TRect);
  297. begin
  298.   inherited AdjustClientRect(Rect);
  299.   if (FIndex <> -1) and not (csDesigning in ComponentState)
  300.   then
  301.     Rect := NewClRect
  302.   else
  303.     begin
  304.       Rect.Top := Rect.Top + FDefaultCaptionHeight;
  305.       Inc(Rect.Left, 1);
  306.       Dec(Rect.Right, 1);
  307.       Dec(Rect.Bottom, 1);
  308.     end;
  309. end;
  310. procedure TspSkinExPanel.ShowControls;
  311. var
  312.   i: Integer;
  313. begin
  314.   if VisibleControls = nil then Exit;
  315.   for i := 0 to VisibleControls.Count - 1 do
  316.     TControl(VisibleControls.Items[i]).Visible := True;
  317.   VisibleControls.Clear;
  318.   VisibleControls.Free;
  319.   VisibleControls := nil;
  320. end;
  321. procedure TspSkinExPanel.HideControls;
  322. var
  323.   i: Integer;
  324. begin
  325.   if VisibleControls <> nil then VisibleControls.Free;
  326.   VisibleControls := TList.Create;
  327.   VisibleControls.Clear;
  328.   for i := 0 to ControlCount - 1 do
  329.   begin
  330.     if Controls[i].Visible
  331.     then
  332.       begin
  333.         VisibleControls.Add(Controls[i]);
  334.         Controls[i].Visible := False;
  335.       end;
  336.   end;
  337. end;
  338. procedure TspSkinExPanel.SetRollState;
  339. begin
  340.   if FRollState = Value then Exit;
  341.   FRollState := Value;
  342.   StopCheckSize := True;
  343.   if FRollState
  344.   then
  345.     begin
  346.       HideControls;
  347.       case FRollKind of
  348.         rkRollVertical:
  349.           begin
  350.             FRealHeight := Height;
  351.             Height := GetRollHeight;
  352.           end;
  353.         rkRollHorizontal:
  354.           begin
  355.             FRealWidth := Width;
  356.             Width := GetRollWidth;
  357.           end;
  358.       end;
  359.     end
  360.   else
  361.     begin
  362.       case FRollKind of
  363.         rkRollVertical:
  364.           Height := FRealHeight;
  365.         rkRollHorizontal:
  366.           Width := FRealWidth;
  367.       end;
  368.       ShowControls;
  369.     end;
  370.   StopCheckSize := False;
  371.   if not (csDesigning in ComponentState) and
  372.     Assigned(FOnChangeRollState)
  373.   then
  374.     FOnChangeRollState(Self);
  375. end;
  376. procedure TspSkinExPanel.CMMouseEnter;
  377. begin
  378.   inherited;
  379.   TestActive(-1, -1);
  380. end;
  381. procedure TspSkinExPanel.CMMouseLeave;
  382. var
  383.   i: Integer;
  384. begin
  385.   inherited;
  386.   for i := 0 to 1 do
  387.     if Buttons[i].MouseIn
  388.     then
  389.        begin
  390.          Buttons[i].MouseIn := False;
  391.          DrawButton(Canvas, i);
  392.        end;
  393. end;
  394. procedure TspSkinExPanel.MouseDown;
  395. begin
  396.   TestActive(X, Y);
  397.   if ActiveButton <> -1
  398.   then
  399.     begin
  400.       CaptureButton := ActiveButton;
  401.       ButtonDown(ActiveButton, X, Y);
  402.     end;
  403.   inherited;
  404. end;
  405. procedure TspSkinExPanel.MouseUp;
  406. begin
  407.   inherited;
  408.   if CaptureButton <> -1
  409.   then ButtonUp(CaptureButton, X, Y);
  410.   CaptureButton := -1;
  411. end;
  412. procedure TspSkinExPanel.MouseMove;
  413. begin
  414.   inherited;
  415.   TestActive(X, Y);
  416. end;
  417. procedure TspSkinExPanel.TestActive(X, Y: Integer);
  418. var
  419.   i, j: Integer;
  420.   i1, i2: Integer;
  421. begin
  422.   if FShowCloseButton then i1 := 0 else i1 := 1;
  423.   if FShowRollButton then i2 := 1 else i2 := 0;
  424.   if i1 > i2 then Exit;
  425.   j := -1;
  426.   OldActiveButton := ActiveButton;
  427.   for i := i1 to i2 do
  428.   begin
  429.     if PtInRect(Buttons[i].R, Point(X, Y))
  430.     then
  431.       begin
  432.         j := i;
  433.         Break;
  434.       end;
  435.   end;
  436.   ActiveButton := j;
  437.   if (CaptureButton <> -1) and
  438.      (ActiveButton <> CaptureButton) and (ActiveButton <> -1)
  439.   then
  440.     ActiveButton := -1;
  441.   if (OldActiveButton <> ActiveButton)
  442.   then
  443.     begin
  444.       if OldActiveButton <> - 1
  445.       then
  446.         ButtonLeave(OldActiveButton);
  447.       if ActiveButton <> -1
  448.       then
  449.         ButtonEnter(ActiveButton);
  450.     end;
  451. end;
  452. procedure TspSkinExPanel.ButtonDown;
  453. begin
  454.   Buttons[i].MouseIn := True;
  455.   Buttons[i].Down := True;
  456.   DrawButton(Canvas, i);
  457. end;
  458. procedure TspSkinExPanel.ButtonUp;
  459. begin
  460.   Buttons[i].Down := False;
  461.   if ActiveButton <> i then Buttons[i].MouseIn := False;
  462.   DrawButton(Canvas, i);
  463.   if Buttons[i].MouseIn
  464.   then
  465.   case i of
  466.     0:  Close;
  467.     1:
  468.         begin
  469.           RollState := not RollState;
  470.           TestActive(X, Y);
  471.           RePaint;
  472.         end;
  473.   end;
  474. end;
  475. procedure TspSkinExPanel.ButtonEnter(I: Integer);
  476. begin
  477.   Buttons[i].MouseIn := True;
  478.   DrawButton(Canvas, i);
  479. end;
  480. procedure TspSkinExPanel.ButtonLeave(I: Integer);
  481. begin
  482.   Buttons[i].MouseIn := False;
  483.   DrawButton(Canvas, i);
  484. end;
  485. procedure TspSkinExPanel.DrawButton;
  486. var
  487.   C: TColor;
  488.   R1: TRect;
  489.   SR, AR, DR: TRect;
  490. begin
  491.   if FIndex = -1
  492.   then
  493.     begin
  494.     with Buttons[i] do
  495.     if not IsNullRect(R) then
  496.     begin
  497.       R1 := R;
  498.       Cnvs.Brush.Color := clBtnface;
  499.       Cnvs.FillRect(R);
  500.       if Down and MouseIn
  501.       then
  502.         begin
  503.           Frame3D(Cnvs, R1, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  504.           Cnvs.Brush.Color := SP_XP_BTNDOWNCOLOR;
  505.           Cnvs.FillRect(R1);
  506.         end
  507.       else
  508.         if MouseIn
  509.         then
  510.           begin
  511.             Frame3D(Cnvs, R1, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  512.             Cnvs.Brush.Color := SP_XP_BTNACTIVECOLOR;
  513.             Cnvs.FillRect(R1);
  514.           end
  515.         else
  516.           begin
  517.             Cnvs.Brush.Color := clBtnFace;
  518.             Cnvs.FillRect(R1);
  519.           end;
  520.       C := clBlack;
  521.       R1 := R;
  522.       if Down and MouseIn
  523.       then
  524.         begin
  525.           Inc(R1.Left, 2);
  526.           Inc(R1.Top, 2);
  527.         end;
  528.       case i of
  529.         1:
  530.           if FRollKind = rkRollVertical
  531.           then
  532.             begin
  533.               if FRollState
  534.               then
  535.                 DrawArrowImage(Cnvs, R1, C, 4)
  536.               else
  537.                 DrawArrowImage(Cnvs, R1, C, 3);
  538.             end
  539.           else
  540.             begin
  541.               if FRollState
  542.               then
  543.                 DrawArrowImage(Cnvs, R1, C, 2)
  544.               else
  545.                 DrawArrowImage(Cnvs, R1, C, 1);
  546.             end;
  547.         0: DrawRCloseImage(Cnvs, R1, C);
  548.       end;
  549.     end
  550.     end
  551.   else
  552.   if not IsNullRect(Buttons[i].R)
  553.   then 
  554.     with Buttons[i] do
  555.     begin
  556.       if i = 0
  557.       then
  558.         begin
  559.           SR := CloseButtonRect;
  560.           AR := CloseButtonActiveRect;
  561.           DR := CloseButtonDownRect;
  562.         end
  563.       else
  564.         if not FRollState
  565.         then
  566.           begin
  567.             case RollKind of
  568.               rkRollHorizontal:
  569.                 begin
  570.                   SR := HRollButtonRect;
  571.                   AR := HRollButtonActiveRect;
  572.                   DR := HRollButtonDownRect;
  573.                 end;
  574.               rkRollVertical:
  575.                 begin
  576.                   SR := VRollButtonRect;
  577.                   AR := VRollButtonActiveRect;
  578.                   DR := VRollButtonDownRect;
  579.                 end;
  580.             end;
  581.           end
  582.         else
  583.           begin
  584.             case RollKind of
  585.               rkRollHorizontal:
  586.                 begin
  587.                   SR := HRestoreButtonRect;
  588.                   AR := HRestoreButtonActiveRect;
  589.                   DR := HRestoreButtonDownRect;
  590.                 end;
  591.               rkRollVertical:
  592.                 begin
  593.                   SR := VRestoreButtonRect;
  594.                   AR := VRestoreButtonActiveRect;
  595.                   DR := VRestoreButtonDownRect;
  596.                 end;
  597.             end;
  598.           end;
  599.       if Down and MouseIn
  600.       then
  601.         Cnvs.CopyRect(R, Picture.Canvas, DR)
  602.       else
  603.       if MouseIn
  604.       then
  605.         Cnvs.CopyRect(R, Picture.Canvas, AR)
  606.       else
  607.         Cnvs.CopyRect(R, Picture.Canvas, SR);
  608.    end;
  609. end;
  610. constructor TspSkinHeaderControl.Create(AOwner: TComponent);
  611. begin
  612.   inherited;
  613.   FOldActiveSection := -1;
  614.   FActiveSection := -1;
  615.   FIndex := -1;
  616.   FDefaultFont := TFont.Create;
  617.   FDefaultHeight := 0;
  618.   with FDefaultFont do
  619.   begin
  620.     Name := 'Arial';
  621.     Style := [];
  622.     Height := 14;
  623.   end;
  624.   FSkinDataName := 'resizebutton';
  625.   FUseSkinFont := True;
  626. end;
  627. destructor TspSkinHeaderControl.Destroy;
  628. begin
  629.   FDefaultFont.Free;
  630.   inherited;
  631. end;
  632. procedure TspSkinHeaderControl.SetDefaultHeight;
  633. begin
  634.   FDefaultHeight := Value;
  635.   if (FIndex = -1) and (FDefaultHeight > 0) then Height := FDefaultHeight;
  636. end;
  637. procedure TspSkinHeaderControl.SetBounds;
  638. var
  639.   UpDate: Boolean;
  640. begin
  641.   GetSkinData;
  642.   UpDate := Height <> AHeight;
  643.   if UpDate
  644.   then
  645.     begin
  646.       if (FIndex <> -1) and (LBPt.X = 0) and (LBPt.Y = 0)
  647.       then
  648.         AHeight := RectHeight(SkinRect)
  649.       else
  650.       if (FIndex = -1) and (FDefaultHeight <> 0)
  651.       then
  652.         AHeight := FDefaultHeight;
  653.     end;
  654.   inherited;
  655. end;
  656. procedure TspSkinHeaderControl.Notification;
  657. begin
  658.   inherited Notification(AComponent, Operation);
  659.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  660. end;
  661. procedure TspSkinHeaderControl.GetSkinData;
  662. begin
  663.   if (FSD = nil) or FSD.Empty
  664.   then
  665.     FIndex := -1
  666.   else
  667.     FIndex := FSD.GetControlIndex(FSkinDataName);
  668.   if FIndex <> -1
  669.   then
  670.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinButtonControl
  671.     then
  672.       with TspDataSkinButtonControl(FSD.CtrlList.Items[FIndex]) do
  673.       begin
  674.         LTPt := LTPoint;
  675.         RTPt := RTPoint;
  676.         LBPt := LBPoint;
  677.         RBPt := RBPoint;
  678.         Self.SkinRect := SkinRect;
  679.         Self.ClRect := ClRect;
  680.         if (PictureIndex <> -1) and (PictureIndex < FSD.FActivePictures.Count)
  681.         then
  682.           Picture := TBitMap(FSD.FActivePictures.Items[PictureIndex])
  683.         else
  684.           Picture := nil;
  685.         //
  686.         Self.FontName := FontName;
  687.         Self.FontColor := FontColor;
  688.         Self.ActiveFontColor := ActiveFontColor;
  689.         Self.DownFontColor := DownFontColor;
  690.         Self.FontStyle := FontStyle;
  691.         Self.FontHeight := FontHeight;
  692.         Self.ActiveSkinRect := ActiveSkinRect;
  693.         Self.DownSkinRect := DownSkinRect;
  694.         if IsNullRect(ActiveSkinRect) then Self.ActiveSkinRect := SkinRect;
  695.         if IsNullRect(DownSkinRect) then Self.DownSkinRect := Self.ActiveSkinRect;
  696.       end
  697.     else
  698.       Picture := nil;
  699. end;
  700. procedure TspSkinHeaderControl.ChangeSkinData;
  701. begin
  702.   GetSkinData;
  703.   if (FIndex <> -1) and (LBPt.X = 0) and (LBPt.Y = 0)
  704.   then
  705.     Height := RectHeight(SkinRect)
  706.   else
  707.     if (FIndex = -1) and (FDefaultHeight <> 0)
  708.     then
  709.       Height := FDefaultHeight;
  710.   RePaint;
  711. end;
  712. procedure TspSkinHeaderControl.SetDefaultFont;
  713. begin
  714.   FDefaultFont.Assign(Value);
  715.   if FIndex =  -1 then Font.Assign(Value);
  716. end;
  717. procedure TspSkinHeaderControl.SetSkinData;
  718. begin
  719.   FSD := Value;
  720.   if (FSD <> nil) then
  721.   if not FSD.Empty and not (csDesigning in ComponentState)
  722.   then
  723.     ChangeSkinData;
  724. end;
  725. function TspSkinHeaderControl.GetSkinItemRect;
  726. var
  727.   SectionOrder: array of Integer;
  728.   R: TRect;
  729. begin
  730.   if Self.DragReorder
  731.   then
  732.     begin
  733.       SetLength(SectionOrder, Sections.Count);
  734.       Header_GetOrderArray(Handle, Sections.Count, PInteger(SectionOrder));
  735.       Header_GETITEMRECT(Handle, SectionOrder[Index] , @R);
  736.     end
  737.   else
  738.     Header_GETITEMRECT(Handle, Index, @R);
  739.   Result := R;
  740. end;
  741. procedure TspSkinHeaderControl.DrawSkinSectionR;
  742. var
  743.   BR, SR: TRect;
  744.   S: String;
  745.   B: TBitMap;
  746.   W, H, TX, TY, GX, GY, XO, YO: Integer;
  747. begin
  748.   GetSkinData;
  749.   if (RectWidth(R) <= 0) or (RectHeight(R) <= 0) then Exit;
  750.   S := Section.Text;
  751.   B := TBitMap.Create;
  752.   W := RectWidth(R);
  753.   if (LBPt.X = 0) and (LBPt.Y = 0) and (FIndex <> -1)
  754.   then
  755.     H := RectHeight(SkinRect)
  756.   else
  757.     H := RectHeight(R);
  758.   B.Width := W;
  759.   B.Height := H;
  760.   BR := Rect(0, 0, B.Width, B.Height);
  761.   if FIndex = -1
  762.   then
  763.     with B.Canvas do
  764.     begin
  765.       //
  766.       if Pressed
  767.       then
  768.         begin
  769.           Frame3D(B.Canvas, BR, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  770.           Brush.Color := SP_XP_BTNDOWNCOLOR;
  771.         end
  772.       else
  773.       if Active
  774.       then
  775.         begin
  776.           Frame3D(B.Canvas, BR, SP_XP_BTNFRAMECOLOR, SP_XP_BTNFRAMECOLOR, 1);
  777.           Brush.Color := SP_XP_BTNACTIVECOLOR;
  778.         end
  779.       else
  780.         begin
  781.           Frame3D(B.Canvas, BR, clBtnShadow, clBtnShadow, 1);
  782.           Brush.Color := clBtnFace;
  783.         end;
  784.       //
  785.       FillRect(BR);
  786.       Font := FDefaultFont;
  787.     end
  788.   else
  789.     with B.Canvas do
  790.     begin
  791.       if FUseSkinFont
  792.       then
  793.         with Font do
  794.         begin
  795.           Name := FontName;
  796.           Height := FontHeight;
  797.           Style := FontStyle;
  798.           CharSet := FDefaultFont.Charset;
  799.         end
  800.       else
  801.         Font := FDefaultFont;
  802.       if Pressed
  803.       then
  804.         begin
  805.           SR := DownSkinRect;
  806.           Font.Color := DownFontColor;
  807.         end
  808.       else
  809.       if Active
  810.       then
  811.         begin
  812.           SR := ActiveSkinRect;
  813.           Font.Color := ActiveFontColor;
  814.         end
  815.       else
  816.         begin
  817.           SR := SkinRect;
  818.           Font.Color := FontColor;
  819.         end;
  820.       //
  821.       XO := RectWidth(BR) - RectWidth(SkinRect);
  822.       if (LBPt.X = 0) and (LBPt.Y = 0)
  823.       then
  824.         begin
  825.           CreateHSkinImage(LTPt.X, RectWidth(SkinRect) - RTPt.X,
  826.           B, Picture, SR, B.Width, B.Height);
  827.         end
  828.       else
  829.         begin
  830.           YO := RectHeight(BR) - RectHeight(SkinRect);
  831.           NewLTPoint := LTPt;
  832.           NewRTPoint := Point(RTPt.X + XO, RTPt.Y);
  833.           NewLBPoint := Point(LBPt.X, LBPt.Y + YO);
  834.           NewRBPoint := Point(RBPt.X + XO, RBPt.Y + YO);
  835.           NewClRect := Rect(CLRect.Left, ClRect.Top,
  836.           CLRect.Right + XO, ClRect.Bottom + YO);
  837.           //
  838.           CreateSkinImage(LTPt, RTPt, LBPt, RBPt, CLRect,
  839.             NewLtPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewCLRect,
  840.             B, Picture, SR, B.Width, B.Height, True);
  841.         end;
  842.     end;
  843.   if Assigned(FOnDrawSkinSection)
  844.   then
  845.     begin
  846.       FOnDrawSkinSection(Self, Section, BR, Active, Pressed, B.Canvas)
  847.     end
  848.   else
  849.     with B.Canvas do
  850.     begin
  851.       Brush.Style := bsClear;
  852.       Inc(BR.Left, 5); Dec(BR.Right, 5);
  853.       if (Images <> nil) and (Section.ImageIndex >= 0) and
  854.       (Section.ImageIndex < Images.Count)
  855.         then
  856.           begin
  857.            CorrectTextbyWidth(B.Canvas, S, RectWidth(BR) - 10 - Images.Width);
  858.            GX := BR.Left;
  859.            if S = Section.Text then
  860.            case Section.Alignment of
  861.              taRightJustify: GX := BR.Right - TextWidth(S) - Images.Width - 10;
  862.              taCenter: GX := BR.Left + RectWidth(BR) div 2 -
  863.                           (TextWidth(S) + Images.Width + 10) div 2;
  864.            end;
  865.            TX := GX + Images.Width + 10;
  866.            TY := BR.Top + RectHeight(BR) div 2 - TextHeight(S) div 2;
  867.            GY := BR.Top + RectHeight(BR) div 2 - Images.Height div 2;
  868.            Images.Draw(B.Canvas, GX, GY, Section.ImageIndex, True);
  869.          end
  870.        else
  871.          begin
  872.            CorrectTextbyWidth(B.Canvas, S, RectWidth(BR));
  873.            TX := BR.Left;
  874.            case Section.Alignment of
  875.              taRightJustify: TX := BR.Right - TextWidth(S) - 10;
  876.              taCenter: TX := BR.Left + RectWidth(BR) div 2 - TextWidth(S) div 2;
  877.            end;
  878.            TY := BR.Top + RectHeight(BR) div 2 - TextHeight(S) div 2;
  879.          end;
  880.       TextRect(BR, TX, TY, S);
  881.     end;
  882.   Cnvs.Draw(R.Left, R.Top, B);
  883.   B.Free;
  884. end;
  885. function TspSkinHeaderControl.DrawSkinSection;
  886. var
  887.   R: TRect;
  888. begin
  889.   R := GetSkinItemRect(Index);
  890.   Result := R;
  891.   DrawSkinSectionR(Cnvs, Sections[Index], Active, Pressed, R);
  892. end;
  893. procedure TspSkinHeaderControl.PaintWindow(DC: HDC);
  894. var
  895.   i, SaveIndex: Integer;
  896.   RightOffset, XO, YO: Integer;
  897.   R1, BGR: TRect;
  898.   B: TBitMap;
  899. begin
  900.   GetSkinData;
  901.   if not HandleAllocated or (Handle = 0) then Exit;
  902.   if (Width <= 0) or (Height <=0) then Exit;
  903.   SaveIndex := SaveDC(DC);
  904.   try
  905.     Canvas.Handle := DC;
  906.     RightOffset := 0;
  907.     for I := 0 to Sections.Count - 1 do
  908.     begin
  909.       R1 := DrawSkinSection(Canvas, I, (I = FActiveSection) and not FDown,
  910.        (I = FActiveSection) and FDown);
  911.       if RightOffset < R1.Right then RightOffset := R1.Right;
  912.     end;
  913.     BGR := Rect(RightOffset, 0, Width + 1, Height);
  914.     if BGR.Left < BGR.Right then
  915.     if FIndex = -1
  916.     then
  917.       with Canvas do
  918.       begin
  919.         Brush.Color := clBtnFace;
  920.         Fillrect(BGR);
  921.         Frame3D(Canvas, BGR, clBtnShadow, clBtnShadow, 1);
  922.       end
  923.     else
  924.       begin
  925.         //
  926.         B := TBitMap.Create;
  927.         B.Width := RectWidth(BGR);
  928.         if (LBPt.X = 0) and (LBPt.Y = 0)
  929.         then
  930.           B.Height := RectHeight(SkinRect)
  931.         else
  932.           B.Height := RectHeight(BGR);
  933.         XO := RectWidth(BGR) - RectWidth(SkinRect);
  934.         if (LBPt.X = 0) and (LBPt.Y = 0)
  935.         then
  936.           begin
  937.             CreateHSkinImage2(LTPt.X, RectWidth(SkinRect) - RTPt.X,
  938.             B, Picture, SkinRect, B.Width, B.Height);
  939.           end
  940.         else
  941.           begin
  942.             YO := RectHeight(BGR) - RectHeight(SkinRect);
  943.             NewLTPoint := LTPt;
  944.             NewRTPoint := Point(RTPt.X + XO, RTPt.Y);
  945.             NewLBPoint := Point(LBPt.X, LBPt.Y + YO);
  946.             NewRBPoint := Point(RBPt.X + XO, RBPt.Y + YO);
  947.             NewClRect := Rect(CLRect.Left, ClRect.Top,
  948.             CLRect.Right + XO, ClRect.Bottom + YO);
  949.             //
  950.             CreateSkinImage2(LTPt, RTPt, LBPt, RBPt, CLRect,
  951.               NewLtPoint, NewRTPoint, NewLBPoint, NewRBPoint, NewCLRect,
  952.               B, Picture, SkinRect, B.Width, B.Height, True);
  953.           end;
  954.         Canvas.Draw(BGR.Left, BGR.Top, B);
  955.         B.Free;  
  956.       end;
  957.     Canvas.Handle := 0;
  958.   finally
  959.     RestoreDC(DC, SaveIndex);
  960.   end;
  961. end;
  962. procedure TspSkinHeaderControl.WMPaint;
  963. begin
  964.   PaintHandler(Msg);
  965. end;
  966. procedure TspSkinHeaderControl.WMEraseBkgnd(var Message: TWMEraseBkgnd);
  967. begin
  968.   Message.Result := 1;
  969. end;
  970. procedure TspSkinHeaderControl.CreateParams(var Params: TCreateParams);
  971. begin
  972.   inherited CreateParams(Params);
  973. end;
  974. procedure TspSkinHeaderControl.TestActive(X, Y: Integer);
  975. var
  976.   i: Integer;
  977.   R: TRect;
  978. begin
  979.   FOldActiveSection := FActiveSection;
  980.   FActiveSection := -1;
  981.   for i := 0 to Sections.Count - 1 do
  982.   begin
  983.     R := GetSkinItemRect(i);
  984.     if PtInRect(R, Point(X, Y))
  985.     then
  986.       begin
  987.         FActiveSection := i;
  988.         Break;
  989.       end;
  990.   end;
  991.   if (FOldActiveSection <> FActiveSection)
  992.   then
  993.     begin
  994.       if (FOldActiveSection <> - 1) and not FInTracking
  995.       then
  996.         DrawSkinSection(Canvas, FOldActiveSection, False, False);
  997.       if (FActiveSection <> -1) and not FInTracking
  998.       then
  999.         DrawSkinSection(Canvas, FActiveSection, True, False);
  1000.     end;
  1001. end;
  1002. procedure TspSkinHeaderControl.MouseMove;
  1003. begin
  1004.  inherited;
  1005.  if FDown and DragReOrder then FInTracking := True else FInTracking := False;
  1006.  if not (csDesigning in ComponentState) and not FInTracking
  1007.  then
  1008.    TestActive(X, Y);
  1009. end;
  1010. procedure TspSkinHeaderControl.MouseDown(Button: TMouseButton; Shift: TShiftState;
  1011.       X, Y: Integer);
  1012. begin
  1013.   if (Button = mbLeft) and not InDivider and (Style = hsButtons)
  1014.   then
  1015.     begin
  1016.       FDown := True;
  1017.       Invalidate;
  1018.     end;
  1019.   inherited;
  1020. end;
  1021. procedure TspSkinHeaderControl.MouseUp;
  1022. var
  1023.   FTempTracking: Boolean;
  1024. begin
  1025.   inherited;
  1026.   FTempTracking := FInTracking;
  1027.   FInTracking := False;
  1028.   FActiveSection := -1;
  1029.   FOldActiveSection := -1;
  1030.   if (Button = mbLeft) and not (csDesigning in ComponentState) and (Style = hsButtons)
  1031.   then
  1032.     begin
  1033.       TestActive(X, Y);
  1034.       Invalidate;
  1035.       FDown := False;
  1036.       if (FActiveSection <> -1) and not InDivider and not FTempTracking and
  1037.          Assigned(FOnSkinSectionClick)
  1038.       then
  1039.         FOnSkinSectionClick(Self, Sections[FActiveSection]);
  1040.     end;
  1041. end;
  1042. procedure TspSkinHeaderControl.CMMouseEnter;
  1043. begin
  1044.   if not FDown then Invalidate;
  1045. end;
  1046. procedure TspSkinHeaderControl.CMMouseLeave;
  1047. begin
  1048.   FActiveSection := -1;
  1049.   FOldActiveSection := -1;
  1050.   if not FDown then Invalidate;
  1051. end;
  1052. procedure TspSkinHeaderControl.WndProc;
  1053. begin
  1054.   inherited;
  1055.   case Message.Msg of
  1056.      HDM_HITTEST:
  1057.         begin
  1058.           if PHDHitTestInfo(Message.LParam)^.Flags = HHT_ONDIVIDER
  1059.           then
  1060.             InDivider := True
  1061.           else
  1062.             InDivider := False;
  1063.         end;
  1064.     end;
  1065. end;
  1066. procedure TspSkinHeaderControl.CreateWnd;
  1067. var
  1068.   i: Integer;
  1069. begin
  1070.   inherited;
  1071.   for i := 0 to Sections.Count - 1 do Sections[i].Style := hsOwnerDraw;
  1072. end;
  1073. procedure TspSkinHeaderControl.DrawSection(Section: THeaderSection; const Rect: TRect;
  1074.                                            Pressed: Boolean);
  1075. var
  1076.   SectionOrder: array of Integer;
  1077.   i, Index: Integer;
  1078. begin
  1079.   inherited;
  1080.   if Self.DragReorder
  1081.   then
  1082.     begin
  1083.       SetLength(SectionOrder, Sections.Count);
  1084.       Header_GetOrderArray(Handle, Sections.Count, PInteger(SectionOrder));
  1085.       for i := 0 to Sections.Count - 1 do
  1086.        if SectionOrder[i] = Section.Index then Break;
  1087.       Index := i;
  1088.     end
  1089.   else
  1090.     Index := Section.Index;
  1091.   Self.DrawSkinSectionR(Canvas, Sections[Index], False, Pressed, Rect);
  1092. end;
  1093. // ======================== TspSkinCustomSlider ======================= //
  1094. constructor TspSkinCustomSlider.Create(AOwner: TComponent);
  1095. begin
  1096.   inherited Create(AOwner);
  1097.   ControlState := ControlState + [csCreating];
  1098.   ControlStyle := [csClickEvents, csCaptureMouse, csAcceptsControls,
  1099.     csDoubleClicks, csOpaque];
  1100.   Width := 150;
  1101.   Height := 40;
  1102.   FNumThumbStates := 2;
  1103.   FBevelWidth := 1;
  1104.   FOrientation := soHorizontal;
  1105.   FOptions := [soShowFocus, soShowPoints, soSmooth];
  1106.   FEdgeSize := 2;
  1107.   FMinValue := 0;
  1108.   FMaxValue := 100;
  1109.   FIncrement := 10;
  1110.   TabStop := True;
  1111.   CreateElements;
  1112.   FSkinDataName := 'slider';
  1113.   Picture := nil;
  1114.   FUseSkinThumb := True;
  1115.   ControlState := ControlState - [csCreating];
  1116. end;
  1117. destructor TspSkinCustomSlider.Destroy;
  1118. var
  1119.   I: TspSliderImage;
  1120. begin
  1121.   FOnChange := nil;
  1122.   FOnChanged := nil;
  1123.   FOnDrawPoints := nil;
  1124.   FRuler.Free;
  1125.   for I := Low(FImages) to High(FImages) do begin
  1126.     FImages[I].OnChange := nil;
  1127.     FImages[I].Free;
  1128.   end;
  1129.   inherited Destroy;
  1130. end;
  1131. procedure TspSkinCustomSlider.GetSkinData;
  1132. begin
  1133.   inherited;
  1134.   if FIndex <> -1
  1135.   then
  1136.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinSlider
  1137.     then
  1138.       with TspDataSkinSlider(FSD.CtrlList.Items[FIndex]) do
  1139.       begin
  1140.         if (PictureIndex <> -1) and (PictureIndex < FSD.FActivePictures.Count)
  1141.         then
  1142.           Picture := TBitMap(FSD.FActivePictures.Items[PictureIndex])
  1143.         else
  1144.           Picture := nil;
  1145.         Self.HRulerRect := HRulerRect;
  1146.         Self.HThumbRect := HThumbRect;
  1147.         Self.VRulerRect := VRulerRect;
  1148.         Self.VThumbRect := VThumbRect;
  1149.         Self.SkinEdgeSize := EdgeSize;
  1150.         Self.BGColor := BGColor;
  1151.         Self.PointsColor := PointsColor;
  1152.       end;
  1153. end;
  1154. procedure TspSkinCustomSlider.ChangeSkinData;
  1155. begin
  1156.   AdjustElements;
  1157. end;
  1158. procedure TspSkinCustomSlider.WMMOVE(var Msg: TWMMOVE);
  1159. begin
  1160.   inherited;
  1161.   if FTransparent then Invalidate;
  1162. end;
  1163. procedure TspSkinCustomSlider.SetTransparent(Value: Boolean);
  1164. begin
  1165.   FTransparent := Value;
  1166.   Invalidate;
  1167. end;
  1168. procedure TspSkinCustomSlider.Loaded;
  1169. var
  1170.   I: TspSliderImage;
  1171. begin
  1172.   inherited Loaded;
  1173.   for I := Low(FImages) to High(FImages) do
  1174.     if I in FUserImages then SetImage(Ord(I), FImages[I]);
  1175. end;
  1176. procedure TspSkinCustomSlider.AlignControls(AControl: TControl; var Rect: TRect);
  1177. begin
  1178.   inherited AlignControls(AControl, Rect);
  1179. end;
  1180. procedure TspSkinCustomSlider.WMPaint(var Message: TWMPaint);
  1181. var
  1182.   DC, MemDC: HDC;
  1183.   MemBitmap, OldBitmap: HBITMAP;
  1184.   PS: TPaintStruct;
  1185. begin
  1186.   if FPaintBuffered then inherited
  1187.   else begin
  1188.     Canvas.Lock;
  1189.     try
  1190.       MemDC := GetDC(0);
  1191.       MemBitmap := CreateCompatibleBitmap(MemDC, ClientWidth, ClientHeight);
  1192.       ReleaseDC(0, MemDC);
  1193.       MemDC := CreateCompatibleDC(0);
  1194.       OldBitmap := SelectObject(MemDC, MemBitmap);
  1195.       try
  1196.         DC := Message.DC;
  1197.         Perform(WM_ERASEBKGND, MemDC, MemDC);
  1198.         FPaintBuffered := True;
  1199.         Message.DC := MemDC;
  1200.         try
  1201.           WMPaint(Message);
  1202.         finally
  1203.           Message.DC := DC;
  1204.           FPaintBuffered := False;
  1205.         end;
  1206.         if DC = 0 then DC := BeginPaint(Handle, PS);
  1207.         BitBlt(DC, 0, 0, ClientWidth, ClientHeight, MemDC, 0, 0, SRCCOPY);
  1208.         if Message.DC = 0 then EndPaint(Handle, PS);
  1209.       finally
  1210.         SelectObject(MemDC, OldBitmap);
  1211.         DeleteDC(MemDC);
  1212.         DeleteObject(MemBitmap);
  1213.       end;
  1214.     finally
  1215.       Canvas.Unlock;
  1216.     end;
  1217.   end;
  1218. end;
  1219. procedure TspSkinCustomSlider.Paint;
  1220. var
  1221.   R: TRect;
  1222.   HighlightThumb: Boolean;
  1223.   P: TPoint;
  1224.   Offset: Integer;
  1225.   Buffer: TBitMap;
  1226. begin
  1227.   GetSkinData;
  1228.   if csPaintCopy in ControlState then begin
  1229.     Offset := GetOffsetByValue(GetSliderValue);
  1230.     P := GetThumbPosition(Offset);
  1231.   end else
  1232.   P := Point(FThumbRect.Left, FThumbRect.Top);
  1233.   R := GetClientRect;
  1234.   if FTransparent
  1235.   then
  1236.     begin
  1237.       Buffer := TBitMap.Create;
  1238.       Buffer.Width := Width;
  1239.       Buffer.Height := Height;
  1240.       GetParentImage2(Self, Buffer.Canvas);
  1241.       Canvas.Draw(0, 0, Buffer);
  1242.       Buffer.Free;
  1243.     end
  1244.   else
  1245.     with Canvas do begin
  1246.       if FIndex = -1
  1247.       then
  1248.         Brush.Color := Color
  1249.       else
  1250.         Brush.Color := BGColor;
  1251.       FillRect(R);
  1252.     end;
  1253.   if FRuler.Width > 0 then begin
  1254.     if (soRulerOpaque in Options) and (FIndex = -1)
  1255.     then FRuler.Transparent := False else FRuler.Transparent := True;
  1256.     Canvas.Draw(FRulerOrg.X, FRulerOrg.Y, FRuler);
  1257.   end;
  1258.   if (soShowFocus in Options) and FFocused and
  1259.     not (csDesigning in ComponentState) then
  1260.   begin
  1261.     R := SliderRect;
  1262.     InflateRect(R, -2, -2);
  1263.     Canvas.DrawFocusRect(R);
  1264.   end;
  1265.   if (soShowPoints in Options) then begin
  1266.     if Assigned(FOnDrawPoints) then FOnDrawPoints(Self)
  1267.     else InternalDrawPoints(Canvas, Increment, 3, 5);
  1268.   end;
  1269.   if csPaintCopy in ControlState then
  1270.     HighlightThumb := not Enabled else
  1271.   HighlightThumb := FThumbDown or not Enabled;
  1272.   if (FIndex = -1) or not FUseSkinThumb
  1273.   then
  1274.     DrawThumb(Canvas, P, HighlightThumb)
  1275.   else
  1276.     DrawSkinThumb(Canvas, P, HighlightThumb);
  1277. end;
  1278. function TspSkinCustomSlider.CanModify: Boolean;
  1279. begin
  1280.   Result := True;
  1281. end;
  1282. function TspSkinCustomSlider.GetSliderValue: Longint;
  1283. begin
  1284.   Result := FValue;
  1285. end;
  1286. function TspSkinCustomSlider.GetSliderRect: TRect;
  1287. begin
  1288.   Result := Bounds(0, 0, Width, Height);
  1289. end;
  1290. procedure TspSkinCustomSlider.DrawSkinThumb;
  1291. var
  1292.   Buffer: TBitMap;
  1293.   R: TRect;
  1294. begin
  1295.   if Orientation = soHorizontal
  1296.   then R := HThumbRect
  1297.   else R := VThumbRect;
  1298.   if Highlight
  1299.   then R.Left := R.Left + (R.Right - R.Left) div 2
  1300.   else R.Right := R.Left + (R.Right - R.Left) div 2;
  1301.   Buffer := TBitMap.Create;
  1302.   Buffer.Width := RectWidth(R);
  1303.   Buffer.Height := RectHeight(R);
  1304.   Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height), Picture.Canvas, R);
  1305.   Buffer.Transparent := True;
  1306.   Canvas.Draw(Origin.X, Origin.Y, Buffer);
  1307.   Buffer.Free;
  1308. end;
  1309. procedure TspSkinCustomSlider.DrawThumb(Canvas: TCanvas; Origin: TPoint;
  1310.   Highlight: Boolean);
  1311. var
  1312.   R: TRect;
  1313.   Image: TBitmap;
  1314.   Buffer: TBitMap;
  1315. begin
  1316.   if Orientation = soHorizontal then Image := ImageHThumb
  1317.   else Image := ImageVThumb;
  1318.   R := Rect(0, 0, Image.Width, Image.Height);
  1319.   if NumThumbStates = 2 then begin
  1320.     if Highlight then R.Left := (R.Right - R.Left) div 2
  1321.     else R.Right := (R.Right - R.Left) div 2;
  1322.   end;
  1323.   Buffer := TBitMap.Create;
  1324.   Buffer.Width := RectWidth(R);
  1325.   Buffer.Height := RectHeight(R);
  1326.   Buffer.Canvas.CopyRect(Rect(0, 0, Buffer.Width, Buffer.Height), Image.Canvas, R);
  1327.   if soThumbOpaque in Options
  1328.   then Buffer.Transparent := False else Buffer.Transparent := True;
  1329.   Canvas.Draw(Origin.X, Origin.Y, Buffer);
  1330.   Buffer.Free;
  1331. end;
  1332. procedure TspSkinCustomSlider.InternalDrawPoints(ACanvas: TCanvas; PointsStep,
  1333.   PointsHeight, ExtremePointsHeight: Longint);
  1334. const
  1335.   MinInterval = 3;
  1336. var
  1337.   RulerLength: Integer;
  1338.   Interval, Scale, PointsCnt, I, Val: Longint;
  1339.   X, H, X1, X2, Y1, Y2: Integer;
  1340.   Range: Double;
  1341.   HThumbWidth, VThumbHeight: Integer;
  1342.   NumStates: Integer;
  1343. begin
  1344.   RulerLength := GetRulerLength;
  1345.   if (FIndex = -1) or not FUseSkinThumb
  1346.   then
  1347.     begin
  1348.       HThumbWidth := FImages[siHThumb].Width;
  1349.       VThumbHeight := FImages[siVThumb].Height;
  1350.       NumStates := NumThumbStates;
  1351.     end
  1352.   else
  1353.     begin
  1354.       HThumbWidth := RectWidth(HThumbRect);
  1355.       VThumbHeight := RectHeight(VThumbRect);
  1356.       NumStates := 2;
  1357.     end;
  1358.   if (FIndex = -1)
  1359.   then
  1360.     ACanvas.Pen.Color := clWindowText
  1361.   else
  1362.     ACanvas.Pen.Color := PointsColor;
  1363.   Scale := 0;
  1364.   Range := MaxValue - MinValue;
  1365.   repeat
  1366.     Inc(Scale);
  1367.     PointsCnt := Round(Range / (Scale * PointsStep)) + 1;
  1368.     if PointsCnt > 1 then
  1369.       Interval := RulerLength div (PointsCnt - 1)
  1370.     else Interval := RulerLength;
  1371.   until (Interval >= MinInterval + 1) or (Interval >= RulerLength);
  1372.   Val := MinValue;
  1373.   for I := 1 to PointsCnt do begin
  1374.     H := PointsHeight;
  1375.     if I = PointsCnt then Val := MaxValue;
  1376.     if (Val = MaxValue) or (Val = MinValue) then H := ExtremePointsHeight;
  1377.     X := GetOffsetByValue(Val);
  1378.     if Orientation = soHorizontal then begin
  1379.       X1 := X + (HThumbWidth div NumStates) div 2;
  1380.       Y1 := FPointsRect.Top;
  1381.       X2 := X1;
  1382.       Y2 := Y1 + H;
  1383.     end
  1384.     else begin
  1385.       X1 := FPointsRect.Left;
  1386.       Y1 := X + VThumbHeight div 2;
  1387.       X2 := X1 + H;
  1388.       Y2 := Y1;
  1389.     end;
  1390.     with ACanvas do begin
  1391.       MoveTo(X1, Y1);
  1392.       LineTo(X2, Y2);
  1393.     end;
  1394.     Inc(Val, Scale * PointsStep);
  1395.   end;
  1396. end;
  1397. procedure TspSkinCustomSlider.DefaultDrawPoints(PointsStep, PointsHeight,
  1398.   ExtremePointsHeight: Longint);
  1399. begin
  1400.   InternalDrawPoints(Canvas, PointsStep, PointsHeight, ExtremePointsHeight);
  1401. end;
  1402. procedure TspSkinCustomSlider.CreateElements;
  1403. var
  1404.   I: TspSliderImage;
  1405. begin
  1406.   FRuler := TBitmap.Create;
  1407.   for I := Low(FImages) to High(FImages) do SetImage(Ord(I), nil);
  1408.   AdjustElements;
  1409. end;
  1410. procedure TspSkinCustomSlider.BuildSkinRuler(R: TRect);
  1411. var
  1412.   TmpBmp: TBitmap;
  1413. begin
  1414.   TmpBmp := TBitmap.Create;
  1415.   try
  1416.     if Orientation = soHorizontal
  1417.     then
  1418.      begin
  1419.        TmpBmp.Width := R.Right - R.Left - 2 * Indent;
  1420.        TmpBmp.Height := RectHeight(HRulerRect);
  1421.        CreateHSkinImage(SkinEdgeSize, SkinEdgeSize, TmpBmp, Picture, HRulerRect,
  1422.          TmpBmp.Width, TmpBmp.Height);
  1423.       end
  1424.     else
  1425.       begin
  1426.         TmpBmp.Height := R.Bottom - R.Top - 2 * Indent;
  1427.         TmpBmp.Width := RectWidth(HRulerRect);
  1428.         CreateVSkinImage(SkinEdgeSize, SkinEdgeSize, TmpBmp, Picture, VRulerRect,
  1429.           TmpBmp.Width, TmpBmp.Height);
  1430.       end;
  1431.     FRuler.Assign(TmpBmp);
  1432.   finally
  1433.     TmpBmp.Free;
  1434.   end;
  1435. end;
  1436. procedure TspSkinCustomSlider.BuildRuler(R: TRect);
  1437. var
  1438.   DstR, BmpR: TRect;
  1439.   I, L, B, N, C, Offs, Len, RulerWidth: Integer;
  1440.   TmpBmp: TBitmap;
  1441.   Index: TspSliderImage;
  1442. begin
  1443.   TmpBmp := TBitmap.Create;
  1444.   try
  1445.     if Orientation = soHorizontal then Index := siHRuler
  1446.     else Index := siVRuler;
  1447.     if Orientation = soHorizontal then begin
  1448.       L := R.Right - R.Left - 2 * Indent;
  1449.       if L < 0 then L := 0;
  1450.       TmpBmp.Width := L;
  1451.       TmpBmp.Height := FImages[Index].Height;
  1452.       L := TmpBmp.Width - 2 * FEdgeSize;
  1453.       B := FImages[Index].Width - 2 * FEdgeSize;
  1454.       RulerWidth := FImages[Index].Width;
  1455.     end
  1456.     else begin
  1457.       TmpBmp.Width := FImages[Index].Width;
  1458.       TmpBmp.Height := R.Bottom - R.Top - 2 * Indent;
  1459.       L := TmpBmp.Height - 2 * FEdgeSize;
  1460.       B := FImages[Index].Height - 2 * FEdgeSize;
  1461.       RulerWidth := FImages[Index].Height;
  1462.     end;
  1463.     N := (L div B) + 1;
  1464.     C := L mod B;
  1465.     for I := 0 to N - 1 do begin
  1466.       if I = 0 then begin
  1467.         Offs := 0;
  1468.         Len := RulerWidth - FEdgeSize;
  1469.       end
  1470.       else begin
  1471.         Offs := FEdgeSize + I * B;
  1472.         if I = N - 1 then Len := C + FEdgeSize
  1473.         else Len := B;
  1474.       end;
  1475.       if Orientation = soHorizontal then
  1476.         DstR := Rect(Offs, 0, Offs + Len, TmpBmp.Height)
  1477.       else DstR := Rect(0, Offs, TmpBmp.Width, Offs + Len);
  1478.       if I = 0 then Offs := 0
  1479.       else
  1480.         if I = N - 1 then Offs := FEdgeSize + B - C
  1481.         else Offs := FEdgeSize;
  1482.       if Orientation = soHorizontal then
  1483.         BmpR := Rect(Offs, 0, Offs + DstR.Right - DstR.Left, TmpBmp.Height)
  1484.       else
  1485.         BmpR := Rect(0, Offs, TmpBmp.Width, Offs + DstR.Bottom - DstR.Top);
  1486.       TmpBmp.Canvas.CopyRect(DstR, FImages[Index].Canvas, BmpR);
  1487.     end;
  1488.     FRuler.Assign(TmpBmp);
  1489.   finally
  1490.     TmpBmp.Free;
  1491.   end;
  1492. end;
  1493. procedure TspSkinCustomSlider.AdjustElements;
  1494. var
  1495.   SaveValue: Longint;
  1496.   R: TRect;
  1497.   HThumbHeight, HThumbWidth,
  1498.   VThumbHeight, VThumbWidth: Integer;
  1499.   NumStates: Integer;
  1500. begin
  1501.   GetSkinData;
  1502.   SaveValue := Value;
  1503.   R := SliderRect;
  1504.   if FIndex = -1
  1505.   then
  1506.     BuildRuler(R)
  1507.   else
  1508.     BuildSkinRuler(R);
  1509.   if (FIndex = -1) or not FUseSkinThumb
  1510.   then
  1511.     begin
  1512.       HThumbHeight := FImages[siHThumb].Height;
  1513.       HThumbWidth := FImages[siHThumb].Width;
  1514.       VThumbHeight := FImages[siVThumb].Height;
  1515.       VThumbWidth := FImages[siVThumb].Width;
  1516.       NumStates := NumThumbStates;
  1517.     end
  1518.   else
  1519.     begin
  1520.       HThumbHeight := RectHeight(HThumbRect);
  1521.       HThumbWidth := RectWidth(HThumbRect);
  1522.       VThumbHeight := RectHeight(VThumbRect);
  1523.       VThumbWidth := RectWidth(VThumbRect);
  1524.       NumStates := 2;
  1525.     end;
  1526.     if Orientation = soHorizontal then begin
  1527.     if HThumbHeight > FRuler.Height then begin
  1528.       FThumbRect := Bounds(R.Left + Indent, R.Top + Indent,
  1529.         HThumbWidth div NumStates, HThumbHeight);
  1530.       FRulerOrg := Point(R.Left + Indent, R.Top + Indent +
  1531.         (HThumbHeight - FRuler.Height) div 2);
  1532.       FPointsRect := Rect(FRulerOrg.X, R.Top + Indent +
  1533.         HThumbHeight + 1,
  1534.         FRulerOrg.X + FRuler.Width, R.Bottom - R.Top - 1);
  1535.     end
  1536.     else begin
  1537.       FThumbRect := Bounds(R.Left + Indent, R.Top + Indent +
  1538.         (FRuler.Height - HThumbHeight) div 2,
  1539.         HThumbWidth div NumStates, HThumbHeight);
  1540.       FRulerOrg := Point(R.Left + Indent, R.Top + Indent);
  1541.       FPointsRect := Rect(FRulerOrg.X, R.Top + Indent + FRuler.Height + 1,
  1542.         FRulerOrg.X + FRuler.Width, R.Bottom - R.Top - 1);
  1543.     end;
  1544.   end
  1545.   else begin
  1546.     if VThumbWidth div NumThumbStates > FRuler.Width then
  1547.     begin
  1548.       FThumbRect := Bounds(R.Left + Indent, R.Top + Indent,
  1549.         VThumbWidth div NumStates, VThumbHeight);
  1550.       FRulerOrg := Point(R.Left + Indent + (VThumbWidth div NumStates -
  1551.         FRuler.Width) div 2, R.Top + Indent);
  1552.       FPointsRect := Rect(R.Left + Indent + VThumbWidth div NumStates + 1,
  1553.         FRulerOrg.Y, R.Right - R.Left - 1, FRulerOrg.Y + FRuler.Height);
  1554.     end
  1555.     else begin
  1556.       FThumbRect := Bounds(R.Left + Indent + (FRuler.Width -
  1557.         VThumbWidth div NumStates) div 2, R.Top + Indent,
  1558.         VThumbWidth div NumStates, VThumbHeight);
  1559.       FRulerOrg := Point(R.Left + Indent, R.Top + Indent);
  1560.       FPointsRect := Rect(R.Left + Indent + FRuler.Width + 1, FRulerOrg.Y,
  1561.         R.Right - R.Left - 1, FRulerOrg.Y + FRuler.Height);
  1562.     end;
  1563.   end;
  1564.   Value := SaveValue;
  1565.   Invalidate;
  1566. end;
  1567. procedure TspSkinCustomSlider.Sized;
  1568. begin
  1569.   AdjustElements;
  1570. end;
  1571. procedure TspSkinCustomSlider.Change;
  1572. begin
  1573.   if Assigned(FOnChange) then FOnChange(Self);
  1574. end;
  1575. procedure TspSkinCustomSlider.Changed;
  1576. begin
  1577.   if Assigned(FOnChanged) then FOnChanged(Self);
  1578. end;
  1579. procedure TspSkinCustomSlider.RangeChanged;
  1580. begin
  1581. end;
  1582. procedure TspSkinCustomSlider.DefineProperties(Filer: TFiler);
  1583.   function DoWrite: Boolean;
  1584.   begin
  1585.     if Assigned(Filer.Ancestor) then
  1586.       Result := FUserImages <> TspSkinCustomSlider(Filer.Ancestor).FUserImages
  1587.     else Result := FUserImages <> [];
  1588.   end;
  1589. begin
  1590.   if Filer is TReader then inherited DefineProperties(Filer);
  1591.   Filer.DefineBinaryProperty('UserImages', ReadUserImages, WriteUserImages,
  1592.      DoWrite);
  1593. end;
  1594. procedure TspSkinCustomSlider.ReadUserImages(Stream: TStream);
  1595. begin
  1596.   Stream.ReadBuffer(FUserImages, SizeOf(FUserImages));
  1597. end;
  1598. procedure TspSkinCustomSlider.WriteUserImages(Stream: TStream);
  1599. begin
  1600.   Stream.WriteBuffer(FUserImages, SizeOf(FUserImages));
  1601. end;
  1602. function TspSkinCustomSlider.StoreImage(Index: Integer): Boolean;
  1603. begin
  1604.   Result := TspSliderImage(Index) in FUserImages;
  1605. end;
  1606. function TspSkinCustomSlider.GetImage(Index: Integer): TBitmap;
  1607. begin
  1608.   Result := FImages[TspSliderImage(Index)];
  1609. end;
  1610. procedure TspSkinCustomSlider.SliderImageChanged(Sender: TObject);
  1611. begin
  1612.   if not (csCreating in ControlState) then Sized;
  1613. end;
  1614. procedure TspSkinCustomSlider.SetImage(Index: Integer; Value: TBitmap);
  1615. var
  1616.   Idx: TspSliderImage;
  1617. begin
  1618.   Idx := TspSliderImage(Index);
  1619.   if FImages[Idx] = nil then begin
  1620.     FImages[Idx] := TBitmap.Create;
  1621.     FImages[Idx].OnChange := SliderImageChanged;
  1622.   end;
  1623.   if Value = nil then begin
  1624.     FImages[Idx].Handle := LoadBitmap(HInstance, ImagesResNames[Idx]);
  1625.     Exclude(FUserImages, Idx);
  1626.     if not (csReading in ComponentState) then begin
  1627.       if Idx in [siHThumb, siVThumb] then Exclude(FOptions, soThumbOpaque)
  1628.       else Exclude(FOptions, soRulerOpaque);
  1629.       Invalidate;
  1630.     end;
  1631.   end
  1632.   else begin
  1633.     FImages[Idx].Assign(Value);
  1634.     Include(FUserImages, Idx);
  1635.   end;
  1636. end;
  1637. procedure TspSkinCustomSlider.SetEdgeSize(Value: Integer);
  1638. var
  1639.   MaxSize: Integer;
  1640. begin
  1641.   if Orientation = soHorizontal then MaxSize := FImages[siHRuler].Width
  1642.   else MaxSize := FImages[siVRuler].Height;
  1643.   if Value * 2 < MaxSize then
  1644.     if Value <> FEdgeSize then begin
  1645.       FEdgeSize := Value;
  1646.       Sized;
  1647.     end;
  1648. end;
  1649. function TspSkinCustomSlider.GetNumThumbStates: TspNumThumbStates;
  1650. begin
  1651.   Result := FNumThumbStates;
  1652. end;
  1653. procedure TspSkinCustomSlider.SetNumThumbStates(Value: TspNumThumbStates);
  1654. begin
  1655.   if FNumThumbStates <> Value then begin
  1656.     FNumThumbStates := Value;
  1657.     AdjustElements;
  1658.   end;
  1659. end;
  1660. procedure TspSkinCustomSlider.SetOrientation(Value: TspSliderOrientation);
  1661. begin
  1662.   if Orientation <> Value then begin
  1663.     FOrientation := Value;
  1664.     Sized;
  1665.     if ComponentState * [csLoading, csUpdating] = [] then
  1666.       SetBounds(Left, Top, Height, Width);
  1667.   end;
  1668. end;
  1669. procedure TspSkinCustomSlider.SetOptions(Value: TspSliderOptions);
  1670. begin
  1671.   if Value <> FOptions then begin
  1672.     FOptions := Value;
  1673.     Invalidate;
  1674.   end;
  1675. end;
  1676. procedure TspSkinCustomSlider.SetRange(Min, Max: Longint);
  1677. begin
  1678.   if (Min < Max) or (csReading in ComponentState) then begin
  1679.     FMinValue := Min;
  1680.     FMaxValue := Max;
  1681.     if not (csReading in ComponentState) then
  1682.       if Min + Increment > Max then FIncrement := Max - Min;
  1683.     if (soShowPoints in Options) then Invalidate;
  1684.     Self.Value := FValue;
  1685.     RangeChanged;
  1686.   end;
  1687. end;
  1688. procedure TspSkinCustomSlider.SetMinValue(Value: Longint);
  1689. begin
  1690.   if FMinValue <> Value then SetRange(Value, MaxValue);
  1691. end;
  1692. procedure TspSkinCustomSlider.SetMaxValue(Value: Longint);
  1693. begin
  1694.   if FMaxValue <> Value then SetRange(MinValue, Value);
  1695. end;
  1696. procedure TspSkinCustomSlider.SetIncrement(Value: Longint);
  1697. begin
  1698.   if (Value > 0) and (FIncrement <> Value) then begin
  1699.     FIncrement := Value;
  1700.     Self.Value := FValue;
  1701.     Invalidate;
  1702.   end;
  1703. end;
  1704. function TspSkinCustomSlider.GetValueByOffset(Offset: Integer): Longint;
  1705. var
  1706.   Range: Double;
  1707.   R: TRect;
  1708.   VThumbHeight: Integer;
  1709. begin
  1710.   // *
  1711.   R := SliderRect;
  1712.   if (FIndex = -1) or not FUseSkinThumb
  1713.   then
  1714.     VThumbHeight := FImages[siVThumb].Height
  1715.   else
  1716.     VThumbHeight := RectHeight(VThumbRect);
  1717.   if Orientation = soVertical then
  1718.     Offset := ClientHeight - Offset - VThumbHeight;
  1719.   Range := MaxValue - MinValue;
  1720.   Result := Round((Offset - R.Left - Indent) * Range / GetRulerLength);
  1721.   if not (soSmooth in Options) then
  1722.     Result := Round(Result / Increment) * Increment;
  1723.   Result := Min(MinValue + Max(Result, 0), MaxValue);
  1724. end;
  1725. function TspSkinCustomSlider.GetOffsetByValue(Value: Longint): Integer;
  1726. var
  1727.   Range: Double;
  1728.   R: TRect;
  1729.   MinIndent: Integer;
  1730.   VThumbHeight: Integer;
  1731. begin
  1732.   if (FIndex = -1) or not FUseSkinThumb
  1733.   then
  1734.     VThumbHeight := FImages[siVThumb].Height
  1735.   else
  1736.     VThumbHeight := RectHeight(VThumbRect);
  1737.   R := SliderRect;
  1738.   Range := MaxValue - MinValue;
  1739.   if Orientation = soHorizontal then
  1740.     MinIndent := R.Left + Indent
  1741.   else
  1742.     MinIndent := R.Top + Indent;
  1743.   Result := Round((Value - MinValue) / Range * GetRulerLength) + MinIndent;
  1744.   if Orientation = soVertical then
  1745.     Result := R.Top + R.Bottom - Result - VThumbHeight;
  1746.   Result := Max(Result, MinIndent);
  1747. end;
  1748. function TspSkinCustomSlider.GetThumbPosition(var Offset: Integer): TPoint;
  1749. var
  1750.   R: TRect;
  1751.   MinIndent: Integer;
  1752. begin
  1753.   R := SliderRect;
  1754.   if Orientation = soHorizontal then
  1755.     MinIndent := R.Left + Indent
  1756.   else
  1757.     MinIndent := R.Top + Indent;
  1758.   Offset := Min(GetOffsetByValue(GetValueByOffset(Min(Max(Offset, MinIndent),
  1759.     MinIndent + GetRulerLength))), MinIndent + GetRulerLength);
  1760.   if Orientation = soHorizontal then begin
  1761.     Result.X := Offset;
  1762.     Result.Y := FThumbRect.Top;
  1763.   end
  1764.   else begin
  1765.     Result.Y := Offset;
  1766.     Result.X := FThumbRect.Left;
  1767.   end;
  1768. end;
  1769. function TspSkinCustomSlider.GetThumbOffset: Integer;
  1770. begin
  1771.   if Orientation = soHorizontal then Result := FThumbRect.Left
  1772.   else Result := FThumbRect.Top;
  1773. end;
  1774. procedure TspSkinCustomSlider.InvalidateThumb;
  1775. begin
  1776.   if HandleAllocated then
  1777.     InvalidateRect(Handle, @FThumbRect, not (csOpaque in ControlStyle));
  1778. end;
  1779. procedure TspSkinCustomSlider.SetThumbOffset(Value: Integer);
  1780. var
  1781.   ValueBefore: Longint;
  1782.   P: TPoint;
  1783. begin
  1784.   ValueBefore := FValue;
  1785.   P := GetThumbPosition(Value);
  1786.   InvalidateThumb;
  1787.   FThumbRect := Bounds(P.X, P.Y, RectWidth(FThumbRect), RectHeight(FThumbRect));
  1788.   InvalidateThumb;
  1789.   if FSliding then begin
  1790.     FValue := GetValueByOffset(Value);
  1791.     if ValueBefore <> FValue then Change;
  1792.   end;
  1793. end;
  1794. function TspSkinCustomSlider.GetRulerLength: Integer;
  1795. begin
  1796.   if (FIndex = -1) or not FUseSkinThumb
  1797.   then
  1798.     begin
  1799.       if Orientation = soHorizontal then begin
  1800.         Result := FRuler.Width;
  1801.         Dec(Result, FImages[siHThumb].Width div NumThumbStates);
  1802.       end
  1803.       else begin
  1804.         Result := FRuler.Height;
  1805.         Dec(Result, FImages[siVThumb].Height);
  1806.       end;
  1807.     end
  1808.   else
  1809.     begin
  1810.       if Orientation = soHorizontal then begin
  1811.         Result := FRuler.Width;
  1812.         Dec(Result, RectWidth(HThumbRect) div 2);
  1813.       end
  1814.       else begin
  1815.         Result := FRuler.Height;
  1816.         Dec(Result, RectHeight(VThumbRect));
  1817.       end;
  1818.     end;
  1819. end;
  1820. procedure TspSkinCustomSlider.SetValue(Value: Longint);
  1821. var
  1822.   ValueChanged: Boolean;
  1823. begin
  1824.   if Value > MaxValue then Value := MaxValue;
  1825.   if Value < MinValue then Value := MinValue;
  1826.   ValueChanged := FValue <> Value;
  1827.   FValue := Value;
  1828.   ThumbOffset := GetOffsetByValue(Value);
  1829.   if ValueChanged then Change;
  1830. end;
  1831. procedure TspSkinCustomSlider.SetReadOnly(Value: Boolean);
  1832. begin
  1833.   if FReadOnly <> Value then begin
  1834.     if Value then begin
  1835.       StopTracking;
  1836.       if FSliding then ThumbMouseUp(mbLeft, [], 0, 0);
  1837.     end;
  1838.     FReadOnly := Value;
  1839.   end;
  1840. end;
  1841. procedure TspSkinCustomSlider.ThumbJump(Jump: TspJumpMode);
  1842. var
  1843.   NewValue: Longint;
  1844. begin
  1845.   if Jump <> jmNone then begin
  1846.     case Jump of
  1847.       jmHome: NewValue := MinValue;
  1848.       jmPrior:
  1849.         NewValue := (Round(Value / Increment) * Increment) - Increment;
  1850.       jmNext:
  1851.         NewValue := (Round(Value / Increment) * Increment) + Increment;
  1852.       jmEnd: NewValue := MaxValue;
  1853.       else Exit;
  1854.     end;
  1855.     if NewValue >= MaxValue then NewValue := MaxValue
  1856.     else if NewValue <= MinValue then NewValue := MinValue;
  1857.     if (NewValue <> Value) then Value := NewValue;
  1858.   end;
  1859. end;
  1860. function TspSkinCustomSlider.JumpTo(X, Y: Integer): TspJumpMode;
  1861. begin
  1862.   Result := jmNone;
  1863.   if Orientation = soHorizontal then begin
  1864.     if FThumbRect.Left > X then Result := jmPrior
  1865.     else if FThumbRect.Right < X then Result := jmNext;
  1866.   end
  1867.   else if Orientation = soVertical then begin
  1868.     if FThumbRect.Top > Y then Result := jmNext
  1869.     else if FThumbRect.Bottom < Y then Result := jmPrior;
  1870.   end;
  1871. end;
  1872. procedure TspSkinCustomSlider.WMTimer(var Message: TMessage);
  1873. begin
  1874.   TimerTrack;
  1875. end;
  1876. procedure TspSkinCustomSlider.CMEnabledChanged(var Message: TMessage);
  1877. begin
  1878.   inherited;
  1879.   InvalidateThumb;
  1880. end;
  1881. procedure TspSkinCustomSlider.CMFocusChanged(var Message: TCMFocusChanged);
  1882. var
  1883.   Active: Boolean;
  1884. begin
  1885.   with Message do Active := (Sender = Self);
  1886.   if Active <> FFocused then begin
  1887.     FFocused := Active;
  1888.     if (soShowFocus in Options) then Invalidate;
  1889.   end;
  1890.   inherited;
  1891. end;
  1892. procedure TspSkinCustomSlider.WMGetDlgCode(var Msg: TWMGetDlgCode);
  1893. begin
  1894.   Msg.Result := DLGC_WANTARROWS;
  1895. end;
  1896. procedure TspSkinCustomSlider.WMSize(var Message: TWMSize);
  1897. begin
  1898.   inherited;
  1899.   if not (csReading in ComponentState) then Sized;
  1900. end;
  1901. procedure TspSkinCustomSlider.StopTracking;
  1902. begin
  1903.   if FTracking then begin
  1904.     if FTimerActive then begin
  1905.       KillTimer(Handle, 1);
  1906.       FTimerActive := False;
  1907.     end;
  1908.     FTracking := False;
  1909.     MouseCapture := False;
  1910.     Changed;
  1911.   end;
  1912. end;
  1913. procedure TspSkinCustomSlider.TimerTrack;
  1914. var
  1915.   Jump: TspJumpMode;
  1916. begin
  1917.   Jump := JumpTo(FMousePos.X, FMousePos.Y);
  1918.   if Jump = FStartJump then begin
  1919.     ThumbJump(Jump);
  1920.     if not FTimerActive then begin
  1921.       SetTimer(Handle, 1, JumpInterval, nil);
  1922.       FTimerActive := True;
  1923.     end;
  1924.   end;
  1925. end;
  1926. procedure TspSkinCustomSlider.MouseDown(Button: TMouseButton; Shift: TShiftState;
  1927.   X, Y: Integer);
  1928. var
  1929.   Rect: TRect;
  1930.   P: TPoint;
  1931. begin
  1932.   inherited MouseDown(Button, Shift, X, Y);
  1933.   if (Button = mbLeft) and not (ssDouble in Shift) then begin
  1934.     if CanFocus then SetFocus;
  1935.     P := Point(X, Y);
  1936.     if PtInRect(FThumbRect, P) then
  1937.       ThumbMouseDown(Button, Shift, X, Y)
  1938.     else begin
  1939.       with FRulerOrg, FRuler do
  1940.         Rect := Bounds(X, Y, Width, Height);
  1941.       InflateRect(Rect, Ord(Orientation = soVertical) * 3,
  1942.         Ord(Orientation = soHorizontal) * 3);
  1943.       if PtInRect(Rect, P) and CanModify and not ReadOnly then begin
  1944.         MouseCapture := True;
  1945.         FTracking := True;
  1946.         FMousePos := P;
  1947.         FStartJump := JumpTo(X, Y);
  1948.         TimerTrack;
  1949.       end;
  1950.     end;
  1951.   end;
  1952. end;
  1953. procedure TspSkinCustomSlider.MouseMove(Shift: TShiftState; X, Y: Integer);
  1954. begin
  1955.   if (csLButtonDown in ControlState) and FSliding then
  1956.     ThumbMouseMove(Shift, X, Y)
  1957.   else if FTracking then FMousePos := Point(X, Y);
  1958.   inherited MouseMove(Shift, X, Y);
  1959. end;
  1960. procedure TspSkinCustomSlider.MouseUp(Button: TMouseButton; Shift: TShiftState;
  1961.   X, Y: Integer);
  1962. begin
  1963.   StopTracking;
  1964.   if FSliding then ThumbMouseUp(Button, Shift, X, Y);
  1965.   inherited MouseUp(Button, Shift, X, Y);
  1966. end;
  1967. procedure TspSkinCustomSlider.KeyDown(var Key: Word; Shift: TShiftState);
  1968. var
  1969.   Jump: TspJumpMode;
  1970. begin
  1971.   Jump := jmNone;
  1972.   if Shift = [] then begin
  1973.     if Key = VK_HOME then Jump := jmHome
  1974.     else if Key = VK_END then Jump := jmEnd;
  1975.     if Orientation = soHorizontal then begin
  1976.       if Key = VK_LEFT then Jump := jmPrior
  1977.       else if Key = VK_RIGHT then Jump := jmNext;
  1978.     end
  1979.     else begin
  1980.       if Key = VK_UP then Jump := jmNext
  1981.       else if Key = VK_DOWN then Jump := jmPrior;
  1982.     end;
  1983.   end;
  1984.   if (Jump <> jmNone) and CanModify and not ReadOnly then begin
  1985.     Key := 0;
  1986.     ThumbJump(Jump);
  1987.     Changed;
  1988.   end;
  1989.   inherited KeyDown(Key, Shift);
  1990. end;
  1991. procedure TspSkinCustomSlider.ThumbMouseDown(Button: TMouseButton;
  1992.   Shift: TShiftState; X, Y: Integer);
  1993. begin
  1994.   if CanFocus then SetFocus;
  1995.   if (Button = mbLeft) and CanModify and not ReadOnly then begin
  1996.     FSliding := True;
  1997.     FThumbDown := True;
  1998.     if Orientation = soHorizontal then FHit := X - FThumbRect.Left
  1999.     else FHit := Y - FThumbRect.Top;
  2000.     InvalidateThumb;
  2001.     Update;
  2002.   end;
  2003. end;
  2004. procedure TspSkinCustomSlider.ThumbMouseMove(Shift: TShiftState; X, Y: Integer);
  2005. begin
  2006.   if (csLButtonDown in ControlState) and CanModify and not ReadOnly then
  2007.   begin
  2008.     if Orientation = soHorizontal then ThumbOffset := X - FHit
  2009.     else ThumbOffset := Y - FHit;
  2010.   end;
  2011. end;
  2012. procedure TspSkinCustomSlider.ThumbMouseUp(Button: TMouseButton;
  2013.   Shift: TShiftState; X, Y: Integer);
  2014. begin
  2015.   if (Button = mbLeft) then begin
  2016.     FSliding := False;
  2017.     FThumbDown := False;
  2018.     InvalidateThumb;
  2019.     Update;
  2020.     if CanModify and not ReadOnly then Changed;
  2021.   end;
  2022. end;
  2023. constructor TspSkinLinkImage.Create(AOwner : TComponent);
  2024. begin
  2025.   inherited Create(AOwner);
  2026.   AutoSize := True;
  2027.   Cursor := crHandPoint;
  2028. end;
  2029. procedure TspSkinLinkImage.Click;
  2030. begin
  2031.   inherited Click;
  2032.   ShellExecute(0, 'open', PChar(FURL), nil, nil, SW_SHOWNORMAL);
  2033. end;
  2034. constructor TspSkinLinkLabel.Create;
  2035. begin
  2036.   inherited;
  2037.   FIndex := -1;
  2038.   Transparent := True;
  2039.   FSD := nil;
  2040.   FSkinDataName := 'stdlabel';
  2041.   FDefaultFont := TFont.Create;
  2042.   with FDefaultFont do
  2043.   begin
  2044.     Name := 'Arial';
  2045.     Height := 14;
  2046.     Style := [fsUnderLine];
  2047.   end;
  2048.   Font.Assign(FDefaultFont);
  2049.   Cursor := crHandPoint;
  2050.   FUseSkinFont := True;
  2051.   FDefaultActiveFontColor := clBlue;
  2052.   FURL := '';
  2053. end;
  2054. destructor TspSkinLinkLabel.Destroy;
  2055. begin
  2056.   FDefaultFont.Free;
  2057.   inherited;
  2058. end;
  2059. procedure TspSkinLinkLabel.DoDrawText(var Rect: TRect; Flags: Longint);
  2060. var
  2061.   Text: string;
  2062. begin
  2063.   GetSkinData;
  2064.   Text := GetLabelText;
  2065.   if (Flags and DT_CALCRECT <> 0) and ((Text = '') or ShowAccelChar and
  2066.     (Text[1] = '&') and (Text[2] = #0)) then Text := Text + ' ';
  2067.   if not ShowAccelChar then Flags := Flags or DT_NOPREFIX;
  2068.   Flags := DrawTextBiDiModeFlags(Flags);
  2069.   if FIndex <> -1
  2070.   then
  2071.     with Canvas.Font do
  2072.     begin
  2073.       if FUseSkinFont
  2074.       then
  2075.         begin
  2076.           Name := FontName;
  2077.           Style := FontStyle;
  2078.           Height := FontHeight;
  2079.           Style := Style + [fsUnderLine];
  2080.         end
  2081.       else
  2082.         Canvas.Font := Self.Font;
  2083.       if FMouseIn
  2084.       then
  2085.         Color := ActiveFontColor
  2086.       else
  2087.         Color := FontColor;
  2088.     end
  2089.   else
  2090.     begin
  2091.       if FUseSkinFont
  2092.       then
  2093.         Canvas.Font := DefaultFont
  2094.       else
  2095.         Canvas.Font := Self.Font;
  2096.       if FMouseIn then Canvas.Font.Color := FDefaultActiveFontColor;
  2097.       Canvas.Font.Style := Canvas.Font.Style + [fsUnderLine];
  2098.     end;
  2099.   if not Enabled then
  2100.   begin
  2101.     OffsetRect(Rect, 1, 1);
  2102.     Canvas.Font.Color := clBtnHighlight;
  2103.     DrawText(Canvas.Handle, PChar(Text), Length(Text), Rect, Flags);
  2104.     OffsetRect(Rect, -1, -1);
  2105.     Canvas.Font.Color := clBtnShadow;
  2106.     DrawText(Canvas.Handle, PChar(Text), Length(Text), Rect, Flags);
  2107.   end
  2108.   else
  2109.     DrawText(Canvas.Handle, PChar(Text), Length(Text), Rect, Flags);
  2110. end;
  2111. procedure TspSkinLinkLabel.Click;
  2112. begin
  2113.   inherited;
  2114.   ShellExecute(0, 'open', PChar(FURL), nil, nil, SW_SHOWNORMAL);
  2115. end;
  2116. procedure TspSkinLinkLabel.CMMouseEnter;
  2117. begin
  2118.   inherited;
  2119.   FMouseIn := True;
  2120.   RePaint;
  2121. end;
  2122. procedure TspSkinLinkLabel.CMMouseLeave;
  2123. begin
  2124.   inherited;
  2125.   FMouseIn := False;
  2126.   RePaint;
  2127. end;
  2128. procedure TspSkinLinkLabel.SetDefaultFont;
  2129. begin
  2130.   FDefaultFont.Assign(Value);
  2131. end;
  2132. procedure TspSkinLinkLabel.Notification;
  2133. begin
  2134.   inherited Notification(AComponent, Operation);
  2135.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  2136. end;
  2137. procedure TspSkinLinkLabel.GetSkinData;
  2138. begin
  2139.   if (FSD = nil) or FSD.Empty
  2140.   then
  2141.     FIndex := -1
  2142.   else
  2143.     FIndex := FSD.GetControlIndex(FSkinDataName);
  2144.   if (FIndex <> -1)
  2145.   then
  2146.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinStdLabelControl
  2147.     then
  2148.       with TspDataSkinStdLabelControl(FSD.CtrlList.Items[FIndex]) do
  2149.       begin
  2150.         Self.FontName := FontName;
  2151.         Self.FontColor := FontColor;
  2152.         Self.FontStyle := FontStyle;
  2153.         Self.FontHeight := FontHeight;
  2154.         Self.ActiveFontColor := ActiveFontColor;
  2155.       end
  2156. end;
  2157. procedure TspSkinLinkLabel.ChangeSkinData;
  2158. begin
  2159.   GetSkinData;
  2160.   RePaint;
  2161. end;
  2162. procedure TspSkinLinkLabel.SetSkinData;
  2163. begin
  2164.   FSD := Value;
  2165.   if (FSD <> nil) then ChangeSkinData;
  2166. end;
  2167. constructor TspSkinButtonLabel.Create;
  2168. begin
  2169.   inherited;
  2170.   FIndex := -1;
  2171.   ControlStyle := ControlStyle + [csSetCaption] - [csOpaque];
  2172.   FSkinDataName := 'stdlabel';
  2173.   FDefaultFont := TFont.Create;
  2174.   with FDefaultFont do
  2175.   begin
  2176.     Name := 'Arial';
  2177.     Style := [];
  2178.     Height := 14;
  2179.   end;
  2180.   FUseSkinFont := True;
  2181.   FDefaultActiveFontColor := clBlue;
  2182.   FNumGlyphs := 2;
  2183.   FMargin := -1;
  2184.   FSpacing := 1;
  2185.   FLayout := blGlyphLeft;
  2186.   FGlyph := TBitMap.Create;
  2187.   Width := 100;
  2188.   Height := 50;
  2189. end;
  2190. destructor TspSkinButtonLabel.Destroy;
  2191. begin
  2192.   FDefaultFont.Free;
  2193.   FGlyph.Free;
  2194.   inherited;
  2195. end;
  2196. procedure TspSkinButtonLabel.MouseDown;
  2197. begin
  2198.   FDown := True;
  2199.   RePaint;
  2200.   inherited;
  2201. end;
  2202. procedure TspSkinButtonLabel.MouseUp;
  2203. begin
  2204.   FDown := False;
  2205.   RePaint;
  2206.   inherited;
  2207. end;
  2208. procedure TspSkinButtonLabel.SetGlyph;
  2209. begin
  2210.   FGlyph.Assign(Value);
  2211.   RePaint;
  2212. end;
  2213. procedure TspSkinButtonLabel.SetNumGlyphs;
  2214. begin
  2215.   FNumGlyphs := Value;
  2216.   RePaint;
  2217. end;
  2218. procedure TspSkinButtonLabel.SetLayout;
  2219. begin
  2220.   if FLayout <> Value
  2221.   then
  2222.     begin
  2223.       FLayout := Value;
  2224.       RePaint;
  2225.     end;
  2226. end;
  2227. procedure TspSkinButtonLabel.SetSpacing;
  2228. begin
  2229.   if Value <> FSpacing
  2230.   then
  2231.     begin
  2232.       FSpacing := Value;
  2233.       RePaint;
  2234.     end;
  2235. end;
  2236. procedure TspSkinButtonLabel.SetMargin;
  2237. begin
  2238.   if (Value <> FMargin) and (Value >= -1)
  2239.   then
  2240.     begin
  2241.       FMargin := Value;
  2242.       RePaint;
  2243.     end;
  2244. end;
  2245. procedure TspSkinButtonLabel.CMMouseEnter;
  2246. begin
  2247.   inherited;
  2248.   FMouseIn := True;
  2249.   RePaint;
  2250. end;
  2251. procedure TspSkinButtonLabel.CMMouseLeave;
  2252. begin
  2253.   inherited;
  2254.   FMouseIn := False;
  2255.   RePaint;
  2256. end;
  2257. procedure TspSkinButtonLabel.SetDefaultFont;
  2258. begin
  2259.   FDefaultFont.Assign(Value);
  2260.   RePaint;
  2261. end;
  2262. procedure TspSkinButtonLabel.Notification;
  2263. begin
  2264.   inherited Notification(AComponent, Operation);
  2265.   if (Operation = opRemove) and (AComponent = FSD) then FSD := nil;
  2266. end;
  2267. procedure TspSkinButtonLabel.ChangeSkinData;
  2268. begin
  2269.   if (FSD = nil) or FSD.Empty
  2270.   then
  2271.     FIndex := -1
  2272.   else
  2273.     FIndex := FSD.GetControlIndex(FSkinDataName);
  2274.   if (FIndex <> -1)
  2275.   then
  2276.     begin
  2277.       if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinStdLabelControl
  2278.       then
  2279.         with TspDataSkinStdLabelControl(FSD.CtrlList.Items[FIndex]) do
  2280.         begin
  2281.           Self.FontName := FontName;
  2282.           Self.FontColor := FontColor;
  2283.           Self.FontHeight := FontHeight;
  2284.           Self.ActiveFontColor := ActiveFontColor;
  2285.           Self.FontStyle := FontStyle;
  2286.         end
  2287.     end;
  2288.   RePaint;
  2289. end;
  2290. procedure TspSkinButtonLabel.SetSkinData;
  2291. begin
  2292.   FSD := Value;
  2293.   if (FSD <> nil) then ChangeSkinData;
  2294. end;
  2295. procedure TspSkinButtonLabel.Paint;
  2296. function GetGlyphNum: Integer;
  2297. begin
  2298.   if FDown and FMouseIn and (FNumGlyphs > 2)
  2299.   then
  2300.     Result := 3
  2301.   else
  2302.   if FMouseIn and (FNumGlyphs > 3)
  2303.   then
  2304.     Result := 4
  2305.   else
  2306.     if not Enabled and (FNumGlyphs > 1)
  2307.     then
  2308.       Result := 2
  2309.     else
  2310.       Result := 1;
  2311. end;
  2312. begin
  2313.   if FIndex <> -1
  2314.   then
  2315.     with Canvas.Font do
  2316.     begin
  2317.       if FUseSkinFont
  2318.       then
  2319.         begin
  2320.           Name := FontName;
  2321.           Height := FontHeight;
  2322.           Style := FontStyle;
  2323.         end
  2324.       else
  2325.         Canvas.Font := FDefaultFont;
  2326.       if FMouseIn
  2327.       then
  2328.         Color := ActiveFontColor
  2329.       else
  2330.         Color := FontColor;
  2331.     end
  2332.   else
  2333.     begin
  2334.       Canvas.Font := FDefaultFont;
  2335.       if FMouseIn
  2336.       then
  2337.         Canvas.Font.Color := FDefaultActiveFontColor;
  2338.     end;
  2339.   DrawGlyphAndText(Canvas,
  2340.     ClientRect, FMargin, FSpacing, FLayout,
  2341.     Caption, FGlyph, FNumGlyphs, GetGlyphNum, FDown);
  2342. end;
  2343. { TspSkinCustomCheckGroup }
  2344. constructor TspSkinCustomCheckGroup.Create(AOwner: TComponent);
  2345. begin
  2346.   inherited Create(AOwner);
  2347.   ControlStyle := [csSetCaption, csDoubleClicks];
  2348.   FButtons := TList.Create;
  2349.   FItems := TStringList.Create;
  2350.   TStringList(FItems).OnChange := ItemsChange;
  2351.   FColumns := 1;
  2352.   FItemIndex := -1;
  2353.   FButtonSkinDataName := 'checkbox';
  2354.   FButtonDefaultFont := TFont.Create;
  2355.   with FButtonDefaultFont do
  2356.   begin
  2357.     Name := 'Arial';
  2358.     Style := [];
  2359.     Height := 14;
  2360.   end;
  2361. end;
  2362. procedure TspSkinCustomCheckGroup.SetButtonDefaultFont;
  2363. var
  2364.   I: Integer;
  2365. begin
  2366.   FButtonDefaultFont.Assign(Value);
  2367.   if FButtons.Count > 0
  2368.   then
  2369.     for I := 0 to FButtons.Count - 1 do
  2370.       with TspCheckGroupButton (FButtons[I]) do
  2371.         DefaultFont.Assign(FButtonDefaultFont);
  2372. end;
  2373. destructor TspSkinCustomCheckGroup.Destroy;
  2374. begin
  2375.   FButtonDefaultFont.Free;
  2376.   SetButtonCount(0);
  2377.   TStringList(FItems).OnChange := nil;
  2378.   FItems.Free;
  2379.   FButtons.Free;
  2380.   inherited Destroy;
  2381. end;
  2382. function TspSkinCustomCheckGroup.GetCheckedStatus(Index: Integer): Boolean;
  2383. begin
  2384.   if (Index >= 0) and (Index < FButtons.Count)
  2385.   then
  2386.     Result := TspCheckGroupButton(FButtons[Index]).Checked
  2387.   else
  2388.     Result := False;
  2389. end;
  2390. procedure TspSkinCustomCheckGroup.SetCheckedStatus(Index: Integer; Value: Boolean);
  2391. begin
  2392.   if (Index >= 0) and (Index < FButtons.Count)
  2393.   then
  2394.     TspCheckGroupButton(FButtons[Index]).Checked := Value;
  2395. end;
  2396. procedure TspSkinCustomCheckGroup.UpdateButtons;
  2397. var
  2398.   I: Integer;
  2399. begin
  2400.   SetButtonCount(FItems.Count);
  2401.   for I := 0 to FButtons.Count - 1 do
  2402.     TspGroupButton (FButtons[I]).Caption := FItems[I];
  2403.   ArrangeButtons;
  2404.   Invalidate;
  2405. end;
  2406. procedure TspSkinCustomCheckGroup.ChangeSkinData;
  2407. begin
  2408.   inherited;
  2409.   Self.ArrangeButtons;
  2410. end;
  2411. procedure TspSkinCustomCheckGroup.SetSkinData;
  2412. var
  2413.   I: Integer;
  2414. begin
  2415.   inherited;
  2416.   if FButtons.Count > 0
  2417.   then
  2418.    for I := 0 to FButtons.Count - 1 do
  2419.      with TspCheckGroupButton (FButtons[I]) do
  2420.        SkinData := Value;
  2421. end;
  2422. procedure TspSkinCustomCheckGroup.SetButtonSkinDataName;
  2423. var
  2424.   I: Integer;
  2425. begin
  2426.   FButtonSkinDataName := Value;
  2427.   if FButtons.Count > 0
  2428.   then
  2429.    for I := 0 to FButtons.Count - 1 do
  2430.      with TspCheckGroupButton (FButtons[I]) do
  2431.        SkinDataName := Value;
  2432. end;
  2433. procedure TspSkinCustomCheckGroup.FlipChildren(AllLevels: Boolean);
  2434. begin
  2435.   { The radio buttons are flipped using BiDiMode }
  2436. end;
  2437. procedure TspSkinCustomCheckGroup.ArrangeButtons;
  2438. var
  2439.   ButtonsPerCol, ButtonWidth, ButtonHeight, TopMargin, I: Integer;
  2440.   DeferHandle: THandle;
  2441.   ALeft: Integer;
  2442.   ButtonsRect: TRect;
  2443. begin
  2444.   if (FButtons.Count <> 0) and not FReading then
  2445.   begin
  2446.     ButtonsRect := Rect(0, 0, Width, Height);
  2447.     AdjustClientRect(ButtonsRect);
  2448.     ButtonsPerCol := (FButtons.Count + FColumns - 1) div FColumns;
  2449.     ButtonWidth := RectWidth(ButtonsRect) div FColumns - 2;
  2450.     I := RectHeight(ButtonsRect);
  2451.     ButtonHeight := I div ButtonsPerCol;
  2452. {    if FIndex <> -1
  2453.     then
  2454.       if FButtons.Count > 0
  2455.       then
  2456.         with TspGroupButton(FButtons[0]) do
  2457.         begin
  2458.           GetSkinData;
  2459.           if FIndex <> -1 then ButtonHeight := RectHeight(SkinRect);
  2460.         end;}
  2461.     TopMargin := ButtonsRect.Top;
  2462.     DeferHandle := BeginDeferWindowPos(FButtons.Count);
  2463.     try
  2464.       for I := 0 to FButtons.Count - 1 do
  2465.         with TspCheckGroupButton(FButtons[I]) do
  2466.         begin
  2467.           BiDiMode := Self.BiDiMode;
  2468.           ALeft := (I div ButtonsPerCol) * ButtonWidth + ButtonsRect.Left + 1;
  2469.           if UseRightToLeftAlignment then
  2470.             ALeft := RectWidth(ButtonsRect) - ALeft - ButtonWidth;
  2471.           DeferHandle := DeferWindowPos(DeferHandle, Handle, 0,
  2472.             ALeft,
  2473.             (I mod ButtonsPerCol) * ButtonHeight + TopMargin,
  2474.             ButtonWidth, ButtonHeight,
  2475.             SWP_NOZORDER or SWP_NOACTIVATE);
  2476.           Visible := True;
  2477.         end;
  2478.     finally
  2479.       EndDeferWindowPos(DeferHandle);
  2480.     end;
  2481.   end;
  2482. end;
  2483. procedure TspSkinCustomCheckGroup.ButtonClick(Sender: TObject);
  2484. begin
  2485.   if not FUpdating then
  2486.   begin
  2487.     FItemIndex := FButtons.IndexOf(Sender);
  2488.     Changed;
  2489.     Click;
  2490.   end;
  2491. end;
  2492. procedure TspSkinCustomCheckGroup.ItemsChange(Sender: TObject);
  2493. begin
  2494.   if not FReading then
  2495.   begin
  2496.     UpdateButtons;
  2497.   end;
  2498. end;
  2499. procedure TspSkinCustomCheckGroup.Loaded;
  2500. begin
  2501.   inherited Loaded;
  2502.   ArrangeButtons;
  2503. end;
  2504. procedure TspSkinCustomCheckGroup.ReadState(Reader: TReader);
  2505. begin
  2506.   FReading := True;
  2507.   inherited ReadState(Reader);
  2508.   FReading := False;
  2509.   UpdateButtons;
  2510. end;
  2511. procedure TspSkinCustomCheckGroup.SetButtonCount(Value: Integer);
  2512. var
  2513.   i: Integer;
  2514. begin
  2515.   while FButtons.Count < Value do TspCheckGroupButton .InternalCreate(Self);
  2516.   while FButtons.Count > Value do TspCheckGroupButton (FButtons.Last).Free;
  2517.   if FButtons.Count > 0
  2518.   then
  2519.    for I := 0 to FButtons.Count - 1 do
  2520.      with TspCheckGroupButton (FButtons[I]) do
  2521.      begin
  2522.        SkinData := Self.SkinData;
  2523.        SkinDataName := ButtonSkinDataName;
  2524.        DefaultFont.Assign(FButtonDefaultFont);
  2525.      end;
  2526. end;
  2527. procedure TspSkinCustomCheckGroup.SetColumns(Value: Integer);
  2528. begin
  2529.   if Value < 1 then Value := 1;
  2530.   if Value > 16 then Value := 16;
  2531.   if FColumns <> Value then
  2532.   begin
  2533.     FColumns := Value;
  2534.     ArrangeButtons;
  2535.     Invalidate;
  2536.   end;
  2537. end;
  2538. procedure TspSkinCustomCheckGroup.SetItems(Value: TStrings);
  2539. begin
  2540.   FItems.Assign(Value);
  2541. end;
  2542. procedure TspSkinCustomCheckGroup.CMEnabledChanged(var Message: TMessage);
  2543. var
  2544.   I: Integer;
  2545. begin
  2546.   inherited;
  2547.   for I := 0 to FButtons.Count - 1 do
  2548.     TspCheckGroupButton(FButtons[I]).Enabled := Enabled;
  2549. end;
  2550. procedure TspSkinCustomCheckGroup.CMFontChanged(var Message: TMessage);
  2551. begin
  2552.   inherited;
  2553.   ArrangeButtons;
  2554. end;
  2555. procedure TspSkinCustomCheckGroup.WMSize(var Message: TWMSize);
  2556. begin
  2557.   inherited;
  2558.   ArrangeButtons;
  2559. end;
  2560. constructor TspSkinBevel.Create;
  2561. begin
  2562.   inherited;
  2563.   FSD := nil;
  2564.   FSkinDataName := 'bevel';
  2565.   LightColor := clBtnHighLight;
  2566.   DarkColor := clBtnShadow;
  2567.   FIndex := -1;
  2568.   FDividerMode := False;
  2569. end;
  2570. procedure TspSkinBevel.SetSkinData(Value: TspSkinData);
  2571. begin
  2572.   FSD := Value;
  2573.   ChangeSkinData;
  2574. end;
  2575. procedure TspSkinBevel.SetDividerMode(Value: Boolean);
  2576. begin
  2577.   FDividerMode := Value;
  2578.   RePaint;
  2579. end;
  2580. procedure TspSkinBevel.ChangeSkinData;
  2581. begin
  2582.   if (FSD = nil) or FSD.Empty
  2583.   then
  2584.     FIndex := -1
  2585.   else
  2586.     FIndex := FSD.GetControlIndex(FSkinDataName);
  2587.   if FIndex = -1
  2588.   then
  2589.     begin
  2590.       LightColor := clBtnHighLight;
  2591.       DarkColor := clBtnShadow;
  2592.     end
  2593.   else
  2594.     if TspDataSkinControl(FSD.CtrlList.Items[FIndex]) is TspDataSkinBevel
  2595.     then
  2596.       with TspDataSkinBevel(FSD.CtrlList.Items[FIndex]) do
  2597.       begin
  2598.         Self.LightColor := LightColor;
  2599.         Self.DarkColor := DarkColor;
  2600.       end;
  2601.   RePaint;
  2602. end;
  2603. procedure TspSkinBevel.Paint;
  2604. const
  2605.   XorColor = $00FFD8CE;
  2606. var
  2607.   Color1, Color2: TColor;
  2608.   Temp: TColor;
  2609.   procedure BevelRect(const R: TRect);
  2610.   begin
  2611.     with Canvas do
  2612.     begin
  2613.       Pen.Color := Color1;
  2614.       PolyLine([Point(R.Left, R.Bottom), Point(R.Left, R.Top),
  2615.         Point(R.Right, R.Top)]);
  2616.       Pen.Color := Color2;
  2617.       PolyLine([Point(R.Right, R.Top), Point(R.Right, R.Bottom),
  2618.         Point(R.Left, R.Bottom)]);
  2619.     end;
  2620.   end;
  2621.   procedure BevelLine(C: TColor; X1, Y1, X2, Y2: Integer);
  2622.   begin
  2623.     with Canvas do
  2624.     begin
  2625.       Pen.Color := C;
  2626.       MoveTo(X1, Y1);
  2627.       LineTo(X2, Y2);
  2628.     end;
  2629.   end;
  2630. begin
  2631.   with Canvas do
  2632.   begin
  2633.     if (csDesigning in ComponentState) then
  2634.     begin
  2635.       if (Shape = bsSpacer) then
  2636.       begin
  2637.         Pen.Style := psDot;
  2638.         Pen.Mode := pmXor;
  2639.         Pen.Color := XorColor;
  2640.         Brush.Style := bsClear;
  2641.         Rectangle(0, 0, ClientWidth, ClientHeight);
  2642.         Exit;
  2643.       end
  2644.       else
  2645.       begin
  2646.         Pen.Style := psSolid;
  2647.         Pen.Mode  := pmCopy;
  2648.         Pen.Color := clBlack;
  2649.         Brush.Style := bsSolid;
  2650.       end;
  2651.     end;
  2652.     Pen.Width := 1;
  2653.     // must be skin
  2654.     if Style = bsLowered then
  2655.     begin
  2656.       Color1 := DarkColor;
  2657.       Color2 := LightColor;
  2658.     end
  2659.     else
  2660.     begin
  2661.       Color1 := LightColor;
  2662.       Color2 := DarkColor;
  2663.     end;
  2664.     //
  2665.     if FDividerMode
  2666.     then
  2667.       begin
  2668.         case Shape of
  2669.           bsTopLine, bsBottomLine:
  2670.             BevelRect(Rect(2, Height div 2 - 1, Width - 2, Height div 2));
  2671.           bsLeftLine, bsRightLine, bsBox, bsFrame:
  2672.             BevelRect(Rect(Width div 2 - 1, 2, Width div 2, Height - 2));
  2673.         end;
  2674.       end
  2675.     else
  2676.     case Shape of
  2677.       bsBox: BevelRect(Rect(0, 0, Width - 1, Height - 1));
  2678.       bsFrame:
  2679.         begin
  2680.           Temp := Color1;
  2681.           Color1 := Color2;
  2682.           BevelRect(Rect(1, 1, Width - 1, Height - 1));
  2683.           Color2 := Temp;
  2684.           Color1 := Temp;
  2685.           BevelRect(Rect(0, 0, Width - 2, Height - 2));
  2686.         end;
  2687.       bsTopLine:
  2688.         begin
  2689.           BevelLine(Color1, 0, 0, Width, 0);
  2690.           BevelLine(Color2, 0, 1, Width, 1);
  2691.         end;
  2692.       bsBottomLine:
  2693.         begin
  2694.           BevelLine(Color1, 0, Height - 2, Width, Height - 2);
  2695.           BevelLine(Color2, 0, Height - 1, Width, Height - 1);
  2696.         end;
  2697.       bsLeftLine:
  2698.         begin
  2699.           BevelLine(Color1, 0, 0, 0, Height);
  2700.           BevelLine(Color2, 1, 0, 1, Height);
  2701.         end;
  2702.       bsRightLine:
  2703.         begin
  2704.           BevelLine(Color1, Width - 2, 0, Width - 2, Height);
  2705.           BevelLine(Color2, Width - 1, 0, Width - 1, Height);
  2706.         end;
  2707.     end;
  2708.   end;
  2709. end;
  2710. // TspSkinButtonsBar
  2711. constructor TspButtonBarSection.Create(Collection: TCollection);
  2712. begin
  2713.   inherited Create(Collection);
  2714.   FItems := TspButtonBarItems.create(self);
  2715. end;
  2716. procedure TspButtonBarSection.Assign(Source: TPersistent);
  2717. begin
  2718.   if Source is TspButtonBarSection then
  2719.   begin
  2720.     Text := TspButtonBarSection(Source).Text;
  2721.     ImageIndex := TspButtonBarSection(Source).ImageIndex;
  2722.   end
  2723.   else inherited Assign(Source);
  2724. end;
  2725. function TspButtonBarSection.GetDisplayName: string;
  2726. begin
  2727.   Result := Text;
  2728.   if Result = '' then Result := inherited GetDisplayName;
  2729. end;
  2730. procedure TspButtonBarSection.SetText(const Value: string);
  2731. begin
  2732.   if FText <> Value then
  2733.   begin
  2734.     FText := Value;
  2735.     Changed(False);
  2736.   end;
  2737. end;
  2738. procedure TspButtonBarSection.SetItems(const Value: TspButtonBarItems);
  2739. begin
  2740.   FItems.assign(Value);
  2741. end;
  2742. destructor TspButtonBarSection.Destroy;
  2743. begin
  2744.   FItems.Free;
  2745.   inherited;
  2746. end;
  2747. procedure TspButtonBarSection.SectionClick(const Value: TNotifyEvent);
  2748. begin
  2749.   FonClick := Value;
  2750. end;
  2751. procedure TspButtonBarSection.Click;
  2752. begin
  2753.   if assigned(onClick) then
  2754.     onclick(self);
  2755. end;
  2756. procedure TspButtonBarSection.SetImageIndex(Value: Integer);
  2757. begin
  2758.   if FImageIndex <> Value then
  2759.   begin
  2760.     FImageIndex := Value;
  2761.     Changed(False);
  2762.   end;
  2763. end;
  2764. constructor TspButtonBarSections.Create(ButtonsBar: TspSkinButtonsBar);
  2765. begin
  2766.   inherited Create(TspButtonBarSection);
  2767.   FButtonsBar := ButtonsBar;
  2768. end;
  2769. function TspButtonBarSections.GetButtonsBar: TspSkinButtonsBar;
  2770. begin
  2771.   Result := FButtonsBar;
  2772. end;
  2773. function TspButtonBarSections.Add: TspButtonBarSection;
  2774. begin
  2775.   Result := TspButtonBarSection(inherited Add);
  2776. end;
  2777. function TspButtonBarSections.GetItem(Index: Integer): TspButtonBarSection;
  2778. begin
  2779.   Result := TspButtonBarSection(inherited GetItem(Index));
  2780. end;
  2781. function TspButtonBarSections.GetOwner: TPersistent;
  2782. begin
  2783.   Result := FButtonsBar;
  2784. end;
  2785. procedure TspButtonBarSections.SetItem(Index: Integer; Value: TspButtonBarSection);
  2786. begin
  2787.   inherited SetItem(Index, Value);
  2788. end;
  2789. procedure TspButtonBarSections.Update(Item: TCollectionItem);
  2790. begin
  2791.   if Item = nil
  2792.   then FButtonsBar.UpdateSections
  2793.   else FButtonsBar.UpdateSection(Item.Index);
  2794. end;
  2795. constructor TspSkinButtonsBar.Create(AOwner: TComponent);
  2796. begin
  2797.   inherited Create(AOwner);
  2798.   FShowButtons := True;
  2799.   FDefaultSectionFont := TFont.Create;
  2800.   with FDefaultSectionFont do
  2801.   begin
  2802.     Name := 'Arial';
  2803.     Style := [];
  2804.     Height := 14;
  2805.   end;
  2806.   FDefaultItemFont := TFont.Create;
  2807.   with FDefaultItemFont do
  2808.   begin
  2809.     Name := 'Arial';
  2810.     Style := [];
  2811.     Height := 14;
  2812.   end;
  2813.   FUpButton := nil;
  2814.   FDownButton := nil;
  2815.   FSectionButtonSkinDataName := 'toolbutton';
  2816.   BorderStyle := bvFrame;
  2817.   FItemsPanel := TspSkinPanel.Create(Self);
  2818.   with FItemsPanel do
  2819.   begin
  2820.     Parent := Self;
  2821.     Align := alClient;
  2822.     BorderStyle := bvNone;
  2823.     OnResize := OnItemPanelResize;
  2824.   end;
  2825.   Width := 150;
  2826.   FDefaultButtonHeight := 25;
  2827.   FItemHeight := 60;
  2828.   FItemsTransparent := True;
  2829.   Align := alLeft;
  2830.   FSectionButtons := TList.Create;
  2831.   FSectionItems := TList.Create ;
  2832.   FSections := TspButtonBarSections.Create(Self);
  2833. end;
  2834. destructor TspSkinButtonsBar.Destroy;
  2835. begin
  2836.   FDefaultSectionFont.Free;
  2837.   FDefaultItemFont.Free;
  2838.   ClearItems;
  2839.   ClearSections;
  2840.   FSectionButtons.Free;
  2841.   FSectionItems.Free;
  2842.   FItemsPanel.Free;
  2843.   FSections.Free;
  2844.   inherited Destroy;
  2845. end;
  2846. procedure TspSkinButtonsBar.SetShowButtons;
  2847. begin
  2848.   FShowButtons := Value;
  2849.   UpdateSections;
  2850. end;
  2851. procedure TspSkinButtonsBar.OnItemPanelResize(Sender: TObject);
  2852. begin
  2853.   CheckVisibleItems;
  2854. end;
  2855. procedure TspSkinButtonsBar.SetDefaultButtonHeight(Value: Integer);
  2856. begin
  2857.   FDefaultButtonHeight := Value;
  2858.   UpDateSectionButtons;
  2859. end;
  2860. procedure TspSkinButtonsBar.SetDefaultSectionFont;
  2861. begin
  2862.   FDefaultSectionFont.Assign(Value);
  2863. end;
  2864. procedure TspSkinButtonsBar.SetDefaultItemFont;
  2865. begin
  2866.   FDefaultItemFont.Assign(Value);
  2867. end;
  2868. procedure TspSkinButtonsBar.ChangeSkinData;
  2869. begin
  2870.   inherited;
  2871.   CheckVisibleItems;
  2872. end;
  2873. procedure TspSkinButtonsBar.ShowUpButton;
  2874. begin
  2875.   FUpButton := TspSkinButton.Create(Self);
  2876.   with FUpButton do
  2877.   begin
  2878.     CanFocused := False;
  2879.     Width := 18;
  2880.     Height := 18;
  2881.     Spacing := 0;
  2882.     SkinDataName := 'resizebutton';
  2883.     RepeatMode := True;
  2884.     RepeatInterval := 150;
  2885.     Caption := '';
  2886.     NumGlyhps := 1;
  2887.     Glyph.LoadFromResourceName(HInstance, 'SP_BB_UP');
  2888.     OnClick := UpButtonClick;
  2889.     SkinData := Self.SkinData;
  2890.     Top := - Height;
  2891.     Parent := FItemsPanel;
  2892.   end;
  2893. end;
  2894. procedure TspSkinButtonsBar.ShowDownButton;
  2895. begin
  2896.   FDownButton := TspSkinButton.Create(Self);
  2897.   with FDownButton do
  2898.   begin
  2899.     CanFocused:= False;
  2900.     Width := 18;
  2901.     Height := 18;
  2902.     Spacing := 0;
  2903.     SkinDataName := 'resizebutton';
  2904.     RepeatMode := True;
  2905.     RepeatInterval := 150;
  2906.     Glyph.LoadFromResourceName(HInstance, 'SP_BB_DOWN');
  2907.     Caption := '';
  2908.     NumGlyhps := 1;
  2909.     OnClick := DownButtonClick;
  2910.     SkinData := Self.SkinData;
  2911.     Top := - Height;
  2912.     Parent := FItemsPanel;
  2913.   end;
  2914. end;
  2915. procedure TspSkinButtonsBar.HideUpButton;
  2916. begin
  2917.   FUpButton.Free;
  2918.   FUpButton := nil;
  2919. end;
  2920. procedure TspSkinButtonsBar.HideDownButton;
  2921. begin
  2922.   FDownButton.Free;
  2923.   FDownButton := nil;
  2924. end;
  2925. procedure TspSkinButtonsBar.UpButtonClick(Sender: TObject);
  2926. begin
  2927.   ScrollUp;
  2928. end;
  2929. procedure TspSkinButtonsBar.DownButtonClick(Sender: TObject);
  2930. begin
  2931.   ScrollDown;
  2932. end;
  2933. procedure TspSkinButtonsBar.ArangeItems;
  2934. var
  2935.   I, J: Integer;
  2936. begin
  2937.   if (TopIndex > 0) and (FUpButton = nil)
  2938.   then
  2939.     ShowUpButton
  2940.   else
  2941.     if (TopIndex = 0) and (FUpButton <> nil) then HideUpButton;
  2942.   if (TopIndex + VisibleCount < FSectionItems.Count) and (FDownButton = nil)
  2943.   then
  2944.     ShowDownButton
  2945.   else
  2946.   if (TopIndex + VisibleCount >= FSectionItems.Count) and (FDownButton <> nil)
  2947.   then
  2948.     HideDownButton;
  2949.   if FUpButton <> nil
  2950.   then
  2951.     with FUpButton do
  2952.       SetBounds(FItemsPanel.Width - Width - 5, 5, Width, Height);
  2953.   if FDownButton <> nil
  2954.   then
  2955.     with FDownButton do
  2956.       SetBounds(FItemsPanel.Width - Width - 5, FItemsPanel.Height - Height - 5, Width, Height);
  2957.   J := 0;
  2958.   for I := 0 to FSectionItems.Count - 1 do
  2959.   with TspSectionItem(FSectionItems.Items[I]) do
  2960.   if Visible
  2961.   then
  2962.     begin
  2963.       SetBounds(0, J, FItemsPanel.Width, FItemHeight);
  2964.       Inc(J, FItemHeight);
  2965.       Parent := FItemsPanel;
  2966.     end;
  2967. end;
  2968. procedure TspSkinButtonsBar.CheckVisibleItems;
  2969. var
  2970.   I: Integer;
  2971.   OldVisibleCount, OldTopIndex: Integer;
  2972.   CanVisible: Boolean;
  2973. begin
  2974.   OldVisibleCount := VisibleCount;
  2975.   OldTopIndex := TopIndex;
  2976.   VisibleCount := FItemsPanel.Height div FItemHeight;
  2977.   if VisibleCount > FSectionItems.Count
  2978.   then VisibleCount := FSectionItems.Count;
  2979.   if VisibleCount = FSectionItems.Count
  2980.   then
  2981.     TopIndex := 0
  2982.   else
  2983.     if (TopIndex + VisibleCount > FSectionItems.Count) and (TopIndex > 0)
  2984.     then
  2985.      begin
  2986.        TopIndex := TopIndex - (VisibleCount - OldVisibleCount);
  2987.        if TopIndex < 0 then TopIndex := 0;
  2988.      end;
  2989.   for I := 0 to FSectionItems.Count - 1 do
  2990.   with TspSectionItem(FSectionItems.Items[I]) do
  2991.   begin
  2992.     CanVisible := (I >= TopIndex) and (I <= TopIndex + VisibleCount - 1);
  2993.     if CanVisible and not Visible
  2994.     then
  2995.       begin
  2996.         if I < OldTopIndex
  2997.         then
  2998.           begin
  2999.             Top := 0;
  3000.             Visible := CanVisible;
  3001.           end
  3002.         else
  3003.           begin
  3004.             Top := FItemsPanel.Height;
  3005.             Visible := CanVisible;
  3006.           end;
  3007.       end
  3008.     else
  3009.       begin
  3010.         Visible := CanVisible;
  3011.         if not Visible then Parent := nil;
  3012.       end;
  3013.   end;
  3014.   ArangeItems;
  3015. end;
  3016. procedure TspSkinButtonsBar.ScrollUp;
  3017. begin
  3018.   if (TopIndex = 0) or (VisibleCount = 0) then Exit;
  3019.   TspSectionItem(FSectionItems.Items[TopIndex + VisibleCount - 1]).Visible := False;
  3020.   Dec(TopIndex);
  3021.   TspSectionItem(FSectionItems.Items[TopIndex]).Visible := True;
  3022.   ArangeItems;
  3023. end;
  3024. procedure TspSkinButtonsBar.ScrollDown;
  3025. begin
  3026.   if VisibleCount = 0 then Exit;
  3027.   if TopIndex + VisibleCount >= FSectionItems.Count then Exit;
  3028.   TspSectionItem(FSectionItems.Items[TopIndex]).Visible := False;
  3029.   Inc(TopIndex);
  3030.   TspSectionItem(FSectionItems.Items[TopIndex + VisibleCount - 1]).Visible := True;
  3031.   ArangeItems;
  3032. end;
  3033. procedure TspSkinButtonsBar.SetItemHeight;
  3034. begin
  3035.   FItemHeight := Value;
  3036.   UpdateItems;
  3037. end;
  3038. procedure TspSkinButtonsBar.SetItemsTransparent;
  3039. begin
  3040.   FItemsTransparent := Value;
  3041.   UpdateItems;
  3042. end;
  3043. procedure TspSkinButtonsBar.UpDateSectionButtons;
  3044. var
  3045.   I: Integer;
  3046. begin
  3047.   if Sections.Count = 0 then Exit;
  3048.   for I := 0 to Sections.Count - 1 do UpdateSection(I);
  3049. end;
  3050. procedure TspSkinButtonsBar.OpenSection(Index: Integer);
  3051. var
  3052.   I: Integer;
  3053. begin
  3054.   if FSectionIndex = Index then Exit;
  3055.   FSectionIndex := Index;
  3056.   if FShowButtons
  3057.   then
  3058.     begin
  3059.       for I := 0 to FSectionButtons.Count - 1 do
  3060.       with TspSectionButton(FSectionButtons.Items[I]) do
  3061.       begin
  3062.        if (FItemIndex > FSectionIndex) and (Align <> alBottom) then Align := alBottom;
  3063.       end;
  3064.       for I := FSectionButtons.Count - 1 downto 0 do
  3065.       with TspSectionButton(FSectionButtons.Items[I]) do
  3066.       begin
  3067.         if (FItemIndex <= FSectionIndex) and (Align <> alTop) then Align := alTop;
  3068.       end;
  3069.     end;
  3070.   UpdateItems;
  3071.   Sections[Index].Click;
  3072. end;
  3073. procedure TspSkinButtonsBar.ClearItems;
  3074. var
  3075.   I: Integer;
  3076. begin
  3077.   if FSectionItems = nil then Exit;
  3078.   if FSectionItems.Count = 0 then Exit;
  3079.   for I := FSectionItems.Count - 1 downto 0 do
  3080.   begin
  3081.     TspSectionItem(FSectionItems.Items[I]).Free;
  3082.   end;
  3083.   FSectionItems.Clear;
  3084. end;
  3085. procedure TspSkinButtonsBar.ClearSections;
  3086. var
  3087.   I: Integer;
  3088. begin
  3089.   if FSectionButtons = nil then Exit;
  3090.   if FSectionButtons.Count = 0 then Exit;
  3091.   for I := 0 to FSectionButtons.Count - 1 do
  3092.   begin
  3093.     TspSectionButton(FSectionButtons.Items[I]).Free;
  3094.   end;
  3095.   FSectionButtons.Clear;
  3096. end;
  3097. procedure TspSkinButtonsBar.SetSkinData;
  3098. begin
  3099.   inherited;
  3100.   if FItemsPanel <> nil then FItemsPanel.SkinData := Value;
  3101. end;
  3102. procedure TspSkinButtonsBar.CreateWnd;
  3103. begin
  3104.   inherited CreateWnd;
  3105.   UpdateSections;
  3106.   UpdateItems;
  3107. end;
  3108. procedure TspSkinButtonsBar.SetSections(Value: TspButtonBarSections);
  3109. begin
  3110.   FSections.Assign(Value);
  3111. end;
  3112. procedure TspSkinButtonsBar.UpdateSection(Index: Integer);
  3113. var
  3114.   S: TspButtonBarSection;
  3115.   I: Integer;
  3116.   B: Boolean;
  3117. begin
  3118.   if not HandleAllocated then Exit;
  3119.   if FSections.Count = 0 then Exit;
  3120.   if not FShowButtons
  3121.   then
  3122.     begin
  3123.       UpdateItems;
  3124.       Exit;
  3125.     end;
  3126.   S := TspButtonBarSection(Sections.Items[Index]);
  3127.   for I := 0 to FSectionButtons.Count - 1 do
  3128.   with TspSectionButton(FSectionButtons.Items[I]) do
  3129.   if FItemIndex = Index then
  3130.   begin
  3131.     DefaultHeight := DefaultButtonHeight;
  3132.     B := Caption <> S.Text;
  3133.     if B then Caption := S.Text;
  3134.     Glyph.Assign(nil);
  3135.     if (S.ImageIndex <> -1) and (FSectionImages <> nil) and (S.ImageIndex < FSectionImages.Count)
  3136.     then
  3137.       FSectionImages.GetBitmap(S.ImageIndex, Glyph);
  3138.     RePaint;
  3139.     if (FSectionIndex = Index) and not B then UpdateItems;
  3140.     Break;
  3141.   end;
  3142. end;
  3143. procedure TspSkinButtonsBar.UpdateSections;
  3144. var
  3145.   I: Integer;
  3146.   S: TspButtonBarSection;
  3147. begin
  3148.   if not HandleAllocated then Exit;
  3149.   if FSections.Count = 0 then Exit;
  3150.   ClearSections;
  3151.   if not FShowButtons
  3152.   then
  3153.     begin
  3154.       CheckVisibleItems;
  3155.       Exit;
  3156.     end;
  3157.   for I := FSectionIndex downto 0  do
  3158.   begin
  3159.     S := TspButtonBarSection(Sections.Items[I]);
  3160.     FSectionButtons.Add(TspSectionButton.CreateEx(Self, Self, I));
  3161.     with TspSectionButton(FSectionButtons.Items[FSectionButtons.Count - 1]) do
  3162.     begin
  3163.       Align := alTop;
  3164.       Parent := Self;
  3165.       DefaultHeight := DefaultButtonHeight;
  3166.       SkinData := Self.SkinData;
  3167.       Caption := S.Text;
  3168.       if (FSectionImages <> nil) and (S.ImageIndex < FSectionImages.Count)
  3169.       then
  3170.         begin
  3171.           FSectionImages.GetBitmap(S.ImageIndex, Glyph);
  3172.         end;
  3173.     end;
  3174.   end;
  3175.   for I := Sections.Count - 1 downto  FSectionIndex + 1  do
  3176.   begin
  3177.     S := TspButtonBarSection(Sections.Items[I]);
  3178.     FSectionButtons.Add(TspSectionButton.CreateEx(Self, Self, I));
  3179.     with TspSectionButton(FSectionButtons.Items[FSectionButtons.Count - 1]) do
  3180.     begin
  3181.       Align := alBottom;
  3182.       Parent := Self;
  3183.       DefaultHeight := DefaultButtonHeight;
  3184.       SkinData := Self.SkinData;
  3185.       Caption := S.Text;
  3186.        if (FSectionImages <> nil) and (S.ImageIndex < FSectionImages.Count)
  3187.       then
  3188.         begin
  3189.           FSectionImages.GetBitmap(S.ImageIndex, Glyph);
  3190.         end;
  3191.     end;
  3192.   end;
  3193. end;
  3194. procedure TspSkinButtonsBar.UpdateItems;
  3195. var
  3196.   I: Integer;
  3197.   It: TspButtonBarItem;
  3198. begin
  3199.   if not HandleAllocated then Exit;
  3200.   if FSections.Count = 0 then Exit;
  3201.   if FShowButtons and (FSectionButtons.Count = 0) then Exit;
  3202.   ClearItems;
  3203.   if FUpButton <> nil then HideUpButton;
  3204.   if FDownButton <> nil then HideDownButton;
  3205.   if FSections.Items[FSectionIndex].Items.Count = 0 then Exit;
  3206.   TopIndex := 0;
  3207.   for I := 0 to FSections.Items[FSectionIndex].Items.Count - 1 do
  3208.   begin
  3209.     It := TspButtonBarItem(FSections.Items[FSectionIndex].Items[I]);
  3210.     FSectionItems.Add(TspSectionItem.CreateEx(FItemsPanel, Self, FSectionIndex, I));
  3211.     with TspSectionItem(FSectionItems.Items[FSectionItems.Count - 1]) do
  3212.     begin
  3213.       DefaultHeight := FItemHeight;
  3214.       Flat := FItemsTransparent;
  3215.       SkinData := Self.SkinData;
  3216.       Caption := It.Text;
  3217.       if (FItemImages <> nil) and (It.ImageIndex < FitemImages.Count)
  3218.       then
  3219.         begin
  3220.           FItemImages.GetBitmap(It.ImageIndex, Glyph);
  3221.         end;
  3222.     end;
  3223.   end;
  3224.   CheckVisibleItems;
  3225. end;
  3226. procedure TspSkinButtonsBar.SetSectionIndex(const Value: integer);
  3227. begin
  3228.   if (Value >= 0) and (Value <> FSectionIndex) and (Value < Sections.Count)
  3229.   then
  3230.     begin
  3231.       OpenSection(Value);
  3232.     end;
  3233. end;
  3234. procedure TspSkinButtonsBar.SetItemImages(const Value: TImagelist);
  3235. begin
  3236.   FItemImages := Value;
  3237.   UpdateItems;
  3238. end;
  3239. procedure TspSkinButtonsBar.Notification(AComponent: TComponent;
  3240.   Operation: TOperation);
  3241. begin
  3242.   if (operation=opremove) and (Acomponent = FItemImages) then
  3243.     SetItemImages(nil);
  3244.   if (operation=opremove) and (Acomponent=FSectionImages) then
  3245.     SetSectionImages(nil);
  3246. end;
  3247. procedure TspSkinButtonsBar.SetSectionImages(const Value: TImageList);
  3248. begin
  3249.   FSectionImages := Value;
  3250.   UpDateSectionButtons;
  3251. end;
  3252. procedure TspButtonBarItem.Assign(Source: TPersistent);
  3253. begin
  3254.   if Source is TspButtonBarItem then
  3255.   begin
  3256.     Text := TspButtonBarItem(Source).Text;
  3257.     ImageIndex:=TspButtonBarItem(source).ImageIndex;
  3258.     onClick:=TspButtonBarItem(source).onClick;
  3259.   end
  3260.   else inherited Assign(Source);
  3261. end;
  3262. procedure TspButtonBarItem.Click;
  3263. begin
  3264.   if assigned(onClick) then
  3265.     onClick(self);
  3266. end;
  3267. constructor TspButtonBarItem.Create(Collection: TCollection);
  3268. begin
  3269.   inherited Create(Collection);
  3270. end;
  3271. function TspButtonBarItem.GetDisplayName: string;
  3272. begin
  3273.   Result := Text;
  3274.   if Result = '' then Result := inherited GetDisplayName;
  3275. end;
  3276. procedure TspButtonBarItem.SetImageIndex(const Value: integer);
  3277. begin
  3278.   if FImageIndex<>value then
  3279.   begin
  3280.     FImageIndex := Value;
  3281.     changed(false)
  3282.   end;
  3283. end;
  3284. procedure TspButtonBarItem.ItemClick(const Value: TNotifyEvent);
  3285. begin
  3286.   FOnClick := Value;
  3287. end;
  3288. procedure TspButtonBarItem.SetText(const Value: string);
  3289. begin
  3290.   if FText <> Value then
  3291.   begin
  3292.     FText := Value;
  3293.     Changed(False);
  3294.   end;
  3295. end;
  3296. function TspButtonBarItems.Add: TspButtonBarItem;
  3297. begin
  3298.   Result := TspButtonBarItem(inherited Add);
  3299. end;
  3300. constructor TspButtonBarItems.Create(Section: TspButtonBarSection);
  3301. begin
  3302.   inherited Create(TspButtonBarItem);
  3303.   FSection := Section;
  3304. end;
  3305. function TspButtonBarItems.GetItem(Index: Integer): TspButtonBarItem;
  3306. begin
  3307.   Result := TspButtonBarItem(inherited GetItem(Index));
  3308. end;
  3309. function TspButtonBarItems.GetOwner: TPersistent;
  3310. begin
  3311.   Result := FSection;
  3312. end;
  3313. procedure TspButtonBarItems.SetItem(Index: Integer; Value: TspButtonBarItem);
  3314. begin
  3315.   inherited SetItem(Index, Value);
  3316. end;
  3317. procedure TspButtonBarItems.Update(Item: TCollectionItem);
  3318. begin
  3319.   FSection.Changed(False);
  3320. end;
  3321. constructor TspSectionButton.CreateEx;
  3322. begin
  3323.   inherited Create(AOwner);
  3324.   FButtonsBar := AButtonsBar;
  3325.   FItemIndex := AIndex;
  3326.   NumGlyhps := 1;
  3327.   Spacing := 5;
  3328.   SkinDataName := FButtonsBar.SectionButtonSkinDataName;
  3329.   DefaultFont := FButtonsBar.DefaultSectionFont;
  3330.   UseSkinFont := FButtonsBar.UseSkinFont;
  3331. end;
  3332. procedure TspSectionButton.ButtonClick;
  3333. begin
  3334.   FButtonsBar.OpenSection(FItemIndex);
  3335.   inherited;
  3336. end;
  3337. constructor TspSectionItem.CreateEx;
  3338. begin
  3339.   inherited Create(AOwner);
  3340.   FButtonsBar := AButtonsBar;
  3341.   FItemIndex := AIndex;
  3342.   FSectionIndex := ASectionIndex;
  3343.   Flat := True;
  3344.   AlphaBlend := False;
  3345.   SkinDataName := 'resizebutton';
  3346.   NumGlyhps := 1;
  3347.   Layout := blGlyphTop;
  3348.   Spacing := 5;
  3349.   DefaultFont := FButtonsBar.DefaultItemFont;
  3350.   UseSkinFont := FButtonsBar.UseSkinFont;
  3351. end;
  3352. procedure TspSectionItem.ButtonClick;
  3353. begin
  3354.   FButtonsBar.Sections[FSectionIndex].Items[FItemIndex].Click;
  3355.   inherited;
  3356. end;
  3357. {TspSkinNoteBook}
  3358. {TspSkinNoteBook}
  3359. type
  3360.   TspPageAccess = class(TStrings)
  3361.   private
  3362.     PageList: TList;
  3363.     Notebook: TspSkinNoteBook;
  3364.   protected
  3365.     function GetCount: Integer; override;
  3366.     function Get(Index: Integer): string; override;
  3367.     procedure Put(Index: Integer; const S: string); override;
  3368.     function GetObject(Index: Integer): TObject; override;
  3369.     procedure SetUpdateState(Updating: Boolean); override;
  3370.   public
  3371.     constructor Create(APageList: TList; ANotebook: TspSkinNoteBook);
  3372.     procedure Clear; override;
  3373.     procedure Delete(Index: Integer); override;
  3374.     procedure Insert(Index: Integer; const S: string); override;
  3375.     function Add(const S: string): Integer; override;
  3376.     procedure Move(CurIndex, NewIndex: Integer); override;
  3377.   end;
  3378. constructor TspPageAccess.Create(APageList: TList; ANotebook: TspSkinNoteBook);
  3379. begin
  3380.   inherited Create;
  3381.   PageList := APageList;
  3382.   Notebook := ANotebook;
  3383. end;
  3384. function TspPageAccess.GetCount: Integer;
  3385. begin
  3386.   Result := PageList.Count;
  3387. end;
  3388. function TspPageAccess.Get(Index: Integer): string;
  3389. begin
  3390.   Result := TspSkinPage(PageList[Index]).Caption;
  3391. end;
  3392. procedure TspPageAccess.Put(Index: Integer; const S: string);
  3393. var
  3394.   Form: TCustomForm;
  3395. begin
  3396.   TspSkinPage(PageList[Index]).Caption := S;
  3397.   if NoteBook.ButtonsMode then NoteBook.UpdateButton(Index, S);
  3398.   if csDesigning in NoteBook.ComponentState then
  3399.   begin
  3400.     Form := GetParentForm(NoteBook);
  3401.     if (Form <> nil) and (Form.Designer <> nil) then
  3402.       Form.Designer.Modified;
  3403.   end;
  3404. end;
  3405. function TspPageAccess.GetObject(Index: Integer): TObject;
  3406. begin
  3407.   Result := PageList[Index];
  3408. end;
  3409. procedure TspPageAccess.SetUpdateState(Updating: Boolean);
  3410. begin
  3411.   { do nothing }
  3412. end;
  3413. procedure TspPageAccess.Clear;
  3414. var
  3415.   I: Integer;
  3416.   Form: TCustomForm;
  3417. begin
  3418.   for I := 0 to PageList.Count - 1 do
  3419.     TspSkinPage(PageList[I]).Free;
  3420.   PageList.Clear;
  3421.   if NoteBook.ButtonsMode then NoteBook.UpdateButtons;
  3422.   if csDesigning in NoteBook.ComponentState then
  3423.   begin
  3424.     Form := GetParentForm(NoteBook);
  3425.     if (Form <> nil) and (Form.Designer <> nil) then
  3426.       Form.Designer.Modified;
  3427.   end;
  3428. end;
  3429. procedure TspPageAccess.Delete(Index: Integer);
  3430. var
  3431.   Form: TCustomForm;
  3432. begin
  3433.   TspSkinPage(PageList[Index]).Free;
  3434.   PageList.Delete(Index);
  3435.   NoteBook.PageIndex := 0;
  3436.   if NoteBook.ButtonsMode then NoteBook.UpdateButtons;
  3437.   if csDesigning in NoteBook.ComponentState then
  3438.   begin
  3439.     Form := GetParentForm(NoteBook);
  3440.     if (Form <> nil) and (Form.Designer <> nil) then
  3441.       Form.Designer.Modified;
  3442.   end;
  3443. end;
  3444. function TspPageAccess.Add;
  3445. var
  3446.   Page: TspSkinPage;
  3447.   Form: TCustomForm;
  3448. begin
  3449.   Page := TspSkinPage.Create(Notebook);
  3450.   with Page do
  3451.   begin
  3452.     Parent := Notebook;
  3453.     Caption := S;
  3454.   end;
  3455.   PageList.Add(Page);
  3456.   NoteBook.PageIndex := PageList.Count - 1;
  3457.   Result := PageList.Count - 1;
  3458.   if NoteBook.ButtonsMode then NoteBook.UpdateButtons;
  3459.   if csDesigning in NoteBook.ComponentState then
  3460.   begin
  3461.     Form := GetParentForm(NoteBook);
  3462.     if (Form <> nil) and (Form.Designer <> nil) then
  3463.       Form.Designer.Modified;
  3464.   end;
  3465. end;
  3466. procedure TspPageAccess.Insert(Index: Integer; const S: string);
  3467. var
  3468.   Page: TspSkinPage;
  3469.   Form: TCustomForm;
  3470. begin
  3471.   Page := TspSkinPage.Create(Notebook);
  3472.   with Page do
  3473.   begin
  3474.     Parent := Notebook;
  3475.     Caption := S;
  3476.   end;
  3477.   PageList.Insert(Index, Page);
  3478.   NoteBook.PageIndex := Index;
  3479.   if NoteBook.ButtonsMode then NoteBook.UpdateButtons;
  3480.   if csDesigning in NoteBook.ComponentState then
  3481.   begin
  3482.     Form := GetParentForm(NoteBook);
  3483.     if (Form <> nil) and (Form.Designer <> nil) then
  3484.       Form.Designer.Modified;
  3485.   end;
  3486. end;
  3487. procedure TspPageAccess.Move(CurIndex, NewIndex: Integer);
  3488. var
  3489.   AObject: TObject;
  3490. begin
  3491.   if CurIndex <> NewIndex then
  3492.   begin
  3493.     AObject := PageList[CurIndex];
  3494.     PageList[CurIndex] := PageList[NewIndex];
  3495.     PageList[NewIndex] := AObject;
  3496.   end;
  3497.   if NoteBook.ButtonsMode then NoteBook.UpdateButtons;
  3498. end;
  3499. constructor TspSkinPage.Create(AOwner: TComponent);
  3500. begin
  3501.   inherited Create(AOwner);
  3502.   Visible := False;
  3503.   ControlStyle := ControlStyle + [csNoDesignVisible];
  3504.   Align := alClient;
  3505.   BorderStyle := bvNone;
  3506.   FImageIndex := -1;
  3507. end;
  3508. procedure TspSkinPage.ReadState(Reader: TReader);
  3509. begin
  3510.   if Reader.Parent is TspSkinNoteBook then
  3511.     TspSkinNotebook(Reader.Parent).FPageList.Add(Self); 
  3512.   inherited ReadState(Reader);
  3513. end;
  3514. procedure TspSkinPage.WMNCHitTest(var Message: TWMNCHitTest);
  3515. begin
  3516.   if not (csDesigning in ComponentState) then
  3517.     Message.Result := HTTRANSPARENT
  3518.   else
  3519.     inherited;
  3520. end;
  3521. constructor TspPageButton.CreateEx;
  3522. begin
  3523.   inherited Create(AOwner);
  3524.   FNoteBook := ANoteBook;
  3525.   FPageIndex := APageIndex;
  3526.   NumGlyhps := 1;
  3527.   Spacing := 5;
  3528.   SkinDataName := FNoteBook.ButtonSkinDataName;
  3529. end;
  3530. procedure TspPageButton.ButtonClick;
  3531. begin
  3532.   FNoteBook.PageIndex := FPageIndex;
  3533.   inherited;
  3534. end;
  3535. var
  3536.   Registered: Boolean = False;
  3537.   
  3538. constructor TspSkinNoteBook.Create(AOwner: TComponent);
  3539. begin
  3540.   inherited Create(AOwner);
  3541.   ControlStyle := ControlStyle - [csAcceptsControls,
  3542.    csCaptureMouse, csClickEvents];
  3543.   FButtonsMode := False;
  3544.   FButtonSkinDataName := 'toolbutton';
  3545.   FButtons := TList.Create;
  3546.   BorderStyle := bvFrame;
  3547.   Width := 150;
  3548.   Height := 150;
  3549.   FPageList := TList.Create;
  3550.   FAccess := TspPageAccess.Create(FPageList, Self);
  3551.   FPageIndex := -1;
  3552.   FAccess.Add('Default');
  3553.   PageIndex := 0;
  3554.   Exclude(FComponentStyle, csInheritable);
  3555.   if not Registered then
  3556.   begin
  3557.     Classes.RegisterClasses([TspSkinPage]);
  3558.     Registered := True;
  3559.   end;
  3560. end;
  3561. destructor TspSkinNoteBook.Destroy;
  3562. begin
  3563.   FAccess.Free;
  3564.   FPageList.Free;
  3565.   ClearButtons;
  3566.   FButtons.Free;
  3567.   inherited Destroy;
  3568. end;
  3569. procedure TspSkinNoteBook.Notification(AComponent: TComponent;
  3570.   Operation: TOperation);
  3571. begin
  3572.   inherited;
  3573.   if (operation=opremove) and (Acomponent = FImages) then
  3574.     SetImages(nil);
  3575. end;
  3576. procedure TspSkinNoteBook.SetImages(const Value: TImageList);
  3577. begin
  3578.   FImages := Value;
  3579.   if FButtonsMode then UpDateButtons;
  3580. end;
  3581. procedure TspSkinNoteBook.UpdateButton;
  3582. var
  3583.   I: Integer;
  3584.   P: TspSkinPage;
  3585. begin
  3586.   for I := 0 to FButtons.Count - 1 do
  3587.   with TspPageButton(FButtons.Items[I]) do
  3588.   if FPageIndex = APageIndex
  3589.   then
  3590.     begin
  3591.       P := TspSkinPage(FPageList.Items[APageIndex]);
  3592.       Caption := ACaption;
  3593.       Glyph.Assign(nil);
  3594.       if P.ImageIndex <> -1
  3595.       then
  3596.         FImages.GetBitmap(P.ImageIndex, Glyph);
  3597.       RePaint;
  3598.     end;
  3599. end;
  3600. procedure TspSkinNoteBook.UpdateButtons;
  3601. var
  3602.   I: Integer;
  3603.   P: TspSkinPage;
  3604. begin
  3605.   if Pages.Count = 0 then Exit;
  3606.   ClearButtons;
  3607.   for I := 0 to Pages.Count - 1  do
  3608.   begin
  3609.     FButtons.Add(TspPageButton.CreateEx(Self, Self, I));
  3610.     P := TspSkinPage(FPageList.Items[I]);
  3611.     with TspPageButton(FButtons.Items[FButtons.Count - 1]) do
  3612.     begin
  3613.       if I <= Self.PageIndex
  3614.       then
  3615.         begin
  3616.           Top := Self.Height;
  3617.           Align := alTop;
  3618.         end
  3619.       else
  3620.         begin
  3621.           Top := Self.Height;
  3622.           Align := alBottom;
  3623.         end;
  3624.       Parent := Self;
  3625.       DefaultHeight := 25;
  3626.       SkinData := Self.SkinData;
  3627.       Caption := Pages[I];
  3628.       Glyph.Assign(nil);
  3629.       if (P.ImageIndex <> -1) and (FImages <> nil) and (P.ImageIndex < FImages.Count)
  3630.       then
  3631.         FImages.GetBitmap(P.ImageIndex, Glyph);
  3632.     end;
  3633.   end;
  3634. end;
  3635. procedure TspSkinNoteBook.ClearButtons;
  3636. var
  3637.   I: Integer;
  3638. begin
  3639.   if FButtons = nil then Exit;
  3640.   if FButtons.Count = 0 then Exit;
  3641.   for I := 0 to FButtons.Count - 1 do
  3642.   begin
  3643.     TspSkinSpeedButton(FButtons.Items[I]).Free;
  3644.   end;
  3645.   FButtons.Clear;
  3646. end;
  3647. procedure TspSkinNoteBook.SetButtonsMode(Value: Boolean);
  3648. begin
  3649.   FButtonsMode := Value;
  3650.   if FButtonsMode then UpDateButtons else ClearButtons;
  3651. end;
  3652. procedure TspSkinNoteBook.Loaded;
  3653. begin
  3654.   inherited;
  3655.   if (FPageIndex <> -1) and (FPageIndex >= 0) and (FPageIndex < FPageList.Count)
  3656.   then
  3657.     with TspSkinPage(FPageList[FPageIndex]) do
  3658.       SkinData := Self.SkinData;
  3659.   if FButtonsMode then UpDateButtons;
  3660. end;
  3661. procedure TspSkinNoteBook.CreateParams(var Params: TCreateParams);
  3662. begin
  3663.   inherited CreateParams(Params);
  3664.   with Params do
  3665.   begin
  3666.     Style := Style or WS_CLIPCHILDREN;
  3667.     WindowClass.style := WindowClass.style and not (CS_HREDRAW or CS_VREDRAW);
  3668.   end;
  3669. end;
  3670. function TspSkinNoteBook.GetChildOwner: TComponent;
  3671. begin
  3672.   Result := Self;
  3673. end;
  3674. procedure TspSkinNoteBook.GetChildren(Proc: TGetChildProc; Root: TComponent);
  3675. var
  3676.   I: Integer;
  3677. begin
  3678.   for I := 0 to FPageList.Count - 1 do Proc(TControl(FPageList[I]));
  3679. end;
  3680. procedure TspSkinNoteBook.ReadState(Reader: TReader);
  3681. begin
  3682.   Pages.Clear;
  3683.   inherited ReadState(Reader);
  3684.   if (FPageIndex <> -1) and (FPageIndex >= 0) and (FPageIndex < FPageList.Count) then
  3685.     with TspSkinPage(FPageList[FPageIndex]) do
  3686.     begin
  3687.       BringToFront;
  3688.       SkinData := Self.SkinData;
  3689.       Visible := True;
  3690.       Align := alClient;
  3691.     end
  3692.   else FPageIndex := -1;
  3693. end;
  3694. procedure TspSkinNoteBook.ShowControl(AControl: TControl);
  3695. var
  3696.   I: Integer;
  3697. begin
  3698.   for I := 0 to FPageList.Count - 1 do
  3699.     if FPageList[I] = AControl then
  3700.     begin
  3701.       SetPageIndex(I);
  3702.       Exit;
  3703.     end;
  3704.   inherited ShowControl(AControl);
  3705. end;
  3706. procedure TspSkinNoteBook.SetPages(Value: TStrings);
  3707. begin
  3708.   FAccess.Assign(Value);
  3709.   UpdateButtons;
  3710. end;
  3711. procedure TspSkinNoteBook.SetPageIndex(Value: Integer);
  3712. var
  3713.   ParentForm: TCustomForm;
  3714.   I: Integer;
  3715. begin
  3716.   if csLoading in ComponentState then
  3717.   begin
  3718.     FPageIndex := Value;
  3719.     Exit;
  3720.   end;
  3721.   if (Value <> FPageIndex) and (Value >= 0) and (Value < FPageList.Count) then
  3722.   begin
  3723.     ParentForm := GetParentForm(Self);
  3724.     if ParentForm <> nil then
  3725.       if ContainsControl(ParentForm.ActiveControl) then
  3726.         ParentForm.ActiveControl := Self;
  3727.     with TspSkinPage(FPageList[Value]) do
  3728.     begin
  3729.       BringToFront;
  3730.       SkinData := Self.SkinData;
  3731.       Visible := True;
  3732.       Align := alClient;
  3733.     end;
  3734.     if (FPageIndex >= 0) and (FPageIndex < FPageList.Count) then
  3735.       TspSkinPage(FPageList[FPageIndex]).Visible := False;
  3736.     FPageIndex := Value;
  3737.     if ParentForm <> nil then
  3738.       if ParentForm.ActiveControl = Self then SelectFirst;
  3739.     //
  3740.     if FButtonsMode
  3741.     then
  3742.       begin
  3743.         for I := FButtons.Count - 1 downto 0 do
  3744.           with TspPageButton(FButtons.Items[I]) do
  3745.           begin
  3746.             if (FPageIndex > Self.PageIndex) and (Align <> alBottom) then Align := alBottom;
  3747.           end;
  3748.         for I := 0 to FButtons.Count - 1 do
  3749.           with TspPageButton(FButtons.Items[I]) do
  3750.           begin
  3751.             if (FPageIndex <= Self.PageIndex) and (Align <> alTop) then Align := alTop;
  3752.           end;
  3753.       end;
  3754.     //
  3755.     if Assigned(FOnPageChanged) then
  3756.       FOnPageChanged(Self);
  3757.   end;
  3758. end;
  3759. procedure TspSkinNoteBook.SetActivePage(const Value: string);
  3760. begin
  3761.   SetPageIndex(FAccess.IndexOf(Value));
  3762. end;
  3763. function TspSkinNoteBook.GetActivePage: string;
  3764. begin
  3765.   Result := FAccess[FPageIndex];
  3766. end;
  3767. constructor TspSkinXFormButton.Create(AOwner: TComponent);
  3768. begin
  3769.   inherited;
  3770.   FDefImage := TBitMap.Create;
  3771.   FDefActiveImage := TBitMap.Create;
  3772.   FDefDownImage := TBitMap.Create;
  3773.   FDefMask := TBitMap.Create;
  3774.   CanFocused := False;
  3775.   FDefActiveFontColor := 0;
  3776.   FDefDownFontColor := 0;
  3777. end;
  3778. destructor TspSkinXFormButton.Destroy;
  3779. begin
  3780.   FDefImage.Free;
  3781.   FDefActiveImage.Free;
  3782.   FDefDownImage.Free;
  3783.   FDefMask.Free;
  3784.   inherited;
  3785. end;
  3786. procedure TspSkinXFormButton.SetControlRegion;
  3787. var
  3788.   TempRgn: HRGN;
  3789. begin
  3790.   if (FIndex = -1) and (FDefImage <> nil) and not FDefImage.Empty
  3791.   then
  3792.     begin
  3793.       TempRgn := FRgn;
  3794.       
  3795.       if FDefMask.Empty and (FRgn <> 0)
  3796.       then
  3797.         begin
  3798.           SetWindowRgn(Handle, 0, True);
  3799.         end
  3800.       else
  3801.         begin
  3802.           CreateSkinSimplyRegion(FRgn, FDefMask);
  3803.           SetWindowRgn(Handle, FRgn, True);
  3804.         end;
  3805.         
  3806.       if TempRgn <> 0 then DeleteObject(TempRgn);
  3807.     end
  3808.   else
  3809.     inherited;
  3810. end;
  3811. procedure TspSkinXFormButton.SetBounds;
  3812. begin
  3813.   inherited;
  3814.   if (FIndex = -1) and (FDefImage <> nil) and not FDefImage.Empty
  3815.   then
  3816.     begin
  3817.       if Width <> FDefImage.Width then Width := FDefImage.Width;
  3818.       if Height <> FDefImage.Height then Height := FDefImage.Height;
  3819.     end;
  3820. end;
  3821. procedure TspSkinXFormButton.DrawDefaultButton;
  3822. var
  3823.   IsDown: Boolean;
  3824.   R: TRect;
  3825. begin
  3826.   with C do
  3827.   begin
  3828.     R := ClientRect;
  3829.     Font.Assign(FDefaultFont);
  3830.     IsDown := FDown and (((FMouseIn or (IsFocused and not FMouseDown)) and
  3831.              (GroupIndex = 0)) or (GroupIndex  <> 0));
  3832.     if IsDown and not FDefDownImage.Empty
  3833.     then
  3834.       Draw(0, 0, FDefDownImage)
  3835.     else
  3836.     if (FMouseIn or IsFocused) and not FDefActiveImage.Empty
  3837.     then
  3838.       Draw(0, 0, FDefActiveImage)
  3839.     else
  3840.       Draw(0, 0, FDefImage);
  3841.     if IsDown
  3842.     then
  3843.       Font.Color := FDefDownFontColor
  3844.     else
  3845.     if FMouseIn or IsFocused
  3846.     then
  3847.       Font.Color := FDefActiveFontColor;
  3848.     DrawGlyphAndText(C, ClientRect, FMargin, FSpacing, FLayout,
  3849.      Caption, FGlyph, FNumGlyphs, 1, IsDown);
  3850.   end;
  3851. end;
  3852. procedure TspSkinXFormButton.CreateControlDefaultImage;
  3853. begin
  3854.   if (FIndex = -1) and not FDefImage.Empty
  3855.   then
  3856.     DrawDefaultButton(B.Canvas)
  3857.   else
  3858.     inherited;
  3859. end;
  3860. procedure TspSkinXFormButton.ChangeSkinData;
  3861. begin
  3862.   GetSkinData;
  3863.   if (FIndex = -1) and not FDefImage.Empty
  3864.   then
  3865.     begin
  3866.       Width := FDefImage.Width;
  3867.       Height := FDEfImage.Height;
  3868.       SetControlRegion;
  3869.       RePaint;
  3870.     end
  3871.   else
  3872.     inherited;  
  3873. end;
  3874. procedure TspSkinXFormButton.SetDefImage(Value: TBitMap);
  3875. begin
  3876.   FDefImage.Assign(Value);
  3877.   if not FDefImage.Empty
  3878.   then
  3879.     begin
  3880.       DefaultHeight := FDefImage.Height;
  3881.       DefaultWidth := FDefImage.Width;
  3882.     end;
  3883. end;
  3884. procedure TspSkinXFormButton.SetDefActiveImage(Value: TBitMap);
  3885. begin
  3886.   FDefActiveImage.Assign(Value);
  3887. end;
  3888. procedure TspSkinXFormButton.SetDefDownImage(Value: TBitMap);
  3889. begin
  3890.   FDefDownImage.Assign(Value);
  3891. end;
  3892. procedure TspSkinXFormButton.SetDefMask(Value: TBitMap);
  3893. begin
  3894.   FDefMask.Assign(Value);
  3895.   if not FDefImage.Empty
  3896.   then
  3897.     SetControlRegion;
  3898. end;
  3899. procedure TspSkinXFormButton.Loaded;
  3900. begin
  3901.   inherited;
  3902.   if (FIndex = -1) and (FDefMask <> nil) and not FDefMask.Empty
  3903.   then
  3904.     SetControlRegion;
  3905. end;
  3906. end.