cxspinedit.pas

来自「胜天进销存源码,国产优秀的进销存」· PAS 代码 · 共 1,961 行 · 第 1/5 页

PAS
1,961
字号
    property OnMouseLeave;
    property OnMouseMove;
    property OnMouseUp;
    property OnStartDrag;
    property OnEndDock;
    property OnStartDock;
  end;

  { TcxFilterSpinEditHelper }

  TcxFilterSpinEditHelper = class(TcxFilterMaskEditHelper)
  public
    class function EditPropertiesHasButtons: Boolean; override;
    class function GetFilterEditClass: TcxCustomEditClass; override;
    class function GetSupportedFilterOperators(
      AProperties: TcxCustomEditProperties;
      AValueTypeClass: TcxValueTypeClass;
      AExtendedSet: Boolean = False): TcxFilterControlOperators; override;
    class procedure InitializeProperties(AProperties,
      AEditProperties: TcxCustomEditProperties; AHasButtons: Boolean); override;
  end;

implementation

uses
  dxOffice11, dxThemeConsts, dxThemeManager, dxUxTheme,
  cxGeometry, cxEditConsts, cxEditPaintUtils, cxEditUtils, cxFormats, cxDWMApi, Math;

const
  cxSpinEditTimerInitialInterval = 400;
  cxSpinEditTimerInterval = 100;
{$IFDEF DELPHI6}
  MaxIntValue = High(Int64);
  MinIntValue = Low(Int64);
{$ELSE}
  MaxIntValue = High(Integer);
  MinIntValue = Low(Integer);
{$ENDIF}

type
  TcxSpinEditUltraFlatButtonPosition = (sufbpLeftMost, sufbpMiddle, sufbpRightMost,
    sufbpMiddleTop, sufbpMiddleBottom, sufbpRightTop, sufbpRightBottom);
  TcxSpinEditFlatButtonPosition = (sfbpLeftSide, sfbpLeftSideRightMost,
    sfbpRightSide, sfbpRightSideLeftMost, sfbpMiddleTop, sfbpMiddleBottom,
    sfbpRightTop, sfbpRightBottom);

procedure CalculateSpinEditViewInfo(AViewData: TcxSpinEditViewData;
  AViewInfo: TcxSpinEditViewInfo);
const
  AButtonNativeStateMap: array [TcxEditButtonState] of Integer =
    (UPS_DISABLED, UPS_NORMAL, UPS_PRESSED, UPS_HOT);
var
  ATheme: TdxTheme;
  I: Integer;
begin
  if Length(AViewInfo.ButtonsInfo) = 0 then
    Exit;
  with AViewInfo do
    if NativeStyle and AreVisualStylesMustBeUsed(NativeStyle, totSpin) then
    begin
      ATheme := OpenTheme(totSpin);
      for I := 0 to Length(AViewInfo.ButtonsInfo) - 1 do
      begin
        ButtonsInfo[I].Data.NativeState := AButtonNativeStateMap[ButtonsInfo[I].Data.State];
        ButtonsInfo[I].Data.BackgroundPartiallyTransparent := IsThemeBackgroundPartiallyTransparent(
          ATheme, ButtonsInfo[I].Data.NativePart, ButtonsInfo[I].Data.NativeState);
      end
    end
    else
      for I := 0 to Length(AViewInfo.ButtonsInfo) - 1 do
        ButtonsInfo[I].Data.NativeState := TC_NONE;
end;

procedure DrawSpinEdit(ACanvas: TcxCanvas; AViewInfo: TcxSpinEditViewInfo);
var
  APrevClipRgn: TcxRegion;
begin
  DrawTextEdit(ACanvas, AViewInfo);
  with AViewInfo do
    if (Length(ButtonsInfo) > 0) and (ButtonsInfo[0].Data.NativePart <> TC_NONE) and
      (ButtonsPosition <> sbpHorzLeftRight) and not IsCustomDrawButton then
    begin
      APrevClipRgn := ACanvas.GetClipRegion;
      try
        ACanvas.IntersectClipRect(AViewInfo.BorderRect);
        InternalPolyLine(ACanvas, [DelimiterLine[0], DelimiterLine[1]], BackgroundColor, True);
      finally
        ACanvas.SetClipRegion(APrevClipRgn, roSet);
      end;
    end;
end;

procedure DrawSpinEditFlatButtonBorder(ACanvas: TcxCanvas;
  AButtonPosition: TcxSpinEditFlatButtonPosition; var R: TRect; AContentColor, ABorderColor: TColor);
begin
  with R do
    case AButtonPosition of
      sfbpLeftSide:
        begin
          DrawButtonBorder(ACanvas, R, [bBottom, bLeft, bTop], ABorderColor);
          DrawButtonBorder(ACanvas, R, [bRight], AContentColor);
        end;
      sfbpLeftSideRightMost, sfbpRightSideLeftMost, sfbpRightTop:
        begin
          ACanvas.FrameRect(R, ABorderColor);
          InflateRect(R, -1, -1);
        end;
      sfbpRightSide, sfbpMiddleTop:
        begin
          DrawButtonBorder(ACanvas, R, [bTop, bRight, bBottom], ABorderColor);
          DrawButtonBorder(ACanvas, R, [bLeft], AContentColor);
        end;
      sfbpMiddleBottom:
        begin
          DrawButtonBorder(ACanvas, R, [bBottom, bRight], ABorderColor);
          DrawButtonBorder(ACanvas, R, [bLeft, bTop], AContentColor);
        end;
      sfbpRightBottom:
        begin
          DrawButtonBorder(ACanvas, R, [bLeft, bBottom, bRight], ABorderColor);
          DrawButtonBorder(ACanvas, R, [bTop], AContentColor);
        end;
  end;
end;

procedure DrawSpinEditUltraFlatButtonBorder(ACanvas: TcxCanvas; R: TRect;
  AButtonPosition: TcxSpinEditUltraFlatButtonPosition; ABrushColor: TColor;
  AButtonViewInfo: TcxEditButtonViewInfo; const ABounds: TRect;
  AIsEditBackgroundTransparent, AHasExternalBorder: Boolean;
  AEditBorderStyle: TcxEditBorderStyle; out ABackgroundRect, AContentRect: TRect);
var
  AHighlightColor: TColor;
begin
  AHighlightColor := GetEditBorderHighlightColor(
    AButtonViewInfo.Data.Style = btsOffice11);

  if (AButtonViewInfo.Data.State in [ebsDisabled, ebsNormal]) or
    not AButtonViewInfo.Data.IsInplace and (AEditBorderStyle = ebsNone) or
    AButtonViewInfo.Data.IsInplace and not AHasExternalBorder then
  begin
    if not(AButtonViewInfo.Data.State in [ebsDisabled, ebsNormal]) then
      ACanvas.FrameRect(R, AHighlightColor)
    else
      if not AIsEditBackgroundTransparent then
        ACanvas.FrameRect(R, AButtonViewInfo.Data.BackgroundColor);
    InflateRect(R, -1, -1);
    ABackgroundRect := R;
  end
  else
  begin
    ABackgroundRect := R;
    case AButtonPosition of
      sufbpLeftMost:
        begin
          DrawButtonBorder(ACanvas, R, [bRight], AHighlightColor);
          Dec(ABackgroundRect.Right);
          ExtendRect(R, Rect(1, 1, 0, 1));
        end;
      sufbpMiddle:
        if R.Left = ABounds.Left then
        begin
          DrawButtonBorder(ACanvas, R, [bRight], AHighlightColor);
          Dec(ABackgroundRect.Right);
          ExtendRect(R, Rect(1, 1, 0, 1));
        end
        else
        begin
          DrawButtonBorder(ACanvas, R, [bLeft, bRight], AHighlightColor);
          ExtendRect(ABackgroundRect, Rect(1, 0, 1, 0));
          ExtendRect(R, Rect(0, 1, 0, 1));
        end;
      sufbpRightMost:
        begin
          DrawButtonBorder(ACanvas, R, [bLeft], AHighlightColor);
          Inc(ABackgroundRect.Left);
          ExtendRect(R, Rect(0, 1, 1, 1));
        end;
      sufbpRightTop:
        begin
          DrawButtonBorder(ACanvas, R, [bBottom], AHighlightColor);
          Dec(ABackgroundRect.Bottom);
          if R.Left = ABounds.Left then
            Inc(R.Left)
          else
          begin
            DrawButtonBorder(ACanvas, R, [bLeft], AHighlightColor);
            Inc(ABackgroundRect.Left);
          end;
          ExtendRect(R, Rect(0, 1, 1, 0));
        end;
      sufbpRightBottom:
        begin
          DrawButtonBorder(ACanvas, R, [bTop], AHighlightColor);
          Inc(ABackgroundRect.Top);
          if R.Left = ABounds.Left then
            Inc(R.Left)
          else
          begin
            DrawButtonBorder(ACanvas, R, [bLeft], AHighlightColor);
            Inc(ABackgroundRect.Left);
          end;
          ExtendRect(R, Rect(0, 0, 1, 1));
        end;
      sufbpMiddleTop:
        begin
          DrawButtonBorder(ACanvas, R, [bLeft, bBottom, bRight], AHighlightColor);
          ExtendRect(ABackgroundRect, Rect(1, 0, 1, 1));
          Inc(R.Top);
        end;
      sufbpMiddleBottom:
        begin
          DrawButtonBorder(ACanvas, R, [bLeft, bTop, bRight], AHighlightColor);
          ExtendRect(ABackgroundRect, Rect(1, 1, 1, 0));
          Dec(R.Bottom);
        end;
    end;
  end;
  AContentRect := R;
end;

{ TcxSpinEditViewInfo }

procedure TcxSpinEditViewInfo.DrawButtonContent(ACanvas: TcxCanvas;
  AButtonVisibleIndex: Integer; const AContentRect: TRect;
  APenColor, ABrushColor: TColor; ANeedOffsetContent: Boolean);

const
  APainterArrowMap: array[Boolean, 0..3] of TcxEditBtnKind = (
    (cxbkSpinLeftBtn, cxbkSpinRightBtn, cxbkSpinLeftBtn, cxbkSpinRightBtn),
    (cxbkSpinDownBtn, cxbkSpinUpBtn, cxbkSpinDownBtn, cxbkSpinUpBtn));

  procedure InternalDrawArrow(const R: TRect; AColor: TColor);
  const
    AArrowDirectionMap: array[Boolean, 0..3] of TcxArrowDirection = (
      (adLeft, adRight, adLeft, adRight),
      (adDown, adUp, adLeft, adRight)
    );
  begin
    DrawArrow(ACanvas, ArrowSize, R,
      AArrowDirectionMap[ButtonsPosition = sbpVert, AButtonVisibleIndex],
      AButtonVisibleIndex > 1, ANeedOffsetContent, AColor);
  end;

var
  AButtonInfo: TcxEditButtonViewInfo;
begin
  AButtonInfo := ButtonsInfo[AButtonVisibleIndex];
  if Painter <> nil then
  begin
    Painter.DrawEditorButton(ACanvas, AContentRect,
      APainterArrowMap[ButtonsPosition = sbpVert, AButtonVisibleIndex],
      EditBtnState2ButtonState[AButtonInfo.Data.State]);
  end
  else
    if AButtonInfo.Data.State <> ebsDisabled then
      InternalDrawArrow(AContentRect, APenColor)
    else
    begin
      InternalDrawArrow(cxRectOffset(AContentRect, 1, 1), clBtnHighlight);
      InternalDrawArrow(AContentRect, clBtnShadow);
    end;
end;

procedure TcxSpinEditViewInfo.DrawHotFlatButtonBorder(ACanvas: TcxCanvas; AButtonViewInfo: TcxEditButtonViewInfo;
  var ARect: TRect; out AContentRect: TRect; var APenColor, ABrushColor: TColor);

  function GetButtonPosition: TcxSpinEditFlatButtonPosition;
  const
    AButtonPositionA: array[Boolean, TcxSpinEditButtonsPosition, sebBackward..sebForward] of TcxSpinEditFlatButtonPosition = (
      (
        (sfbpLeftSideRightMost, sfbpRightSideLeftMost),
        (sfbpRightSideLeftMost, sfbpRightSide),
        (sfbpRightBottom, sfbpRightTop)
      ),
      (
        (sfbpLeftSideRightMost, sfbpRightSideLeftMost),
        (sfbpRightSide, sfbpRightSide),
        (sfbpMiddleBottom, sfbpMiddleTop)
      )
    );
    AFastButtonPositionA: array[TcxSpinEditButtonsPosition, sebFastBackward..sebFastForward] of TcxSpinEditFlatButtonPosition = (
      (sfbpLeftSide, sfbpRightSide),
      (sfbpRightSideLeftMost, sfbpRightSide),
      (sfbpRightSideLeftMost, sfbpRightSide)
    );
  begin
    if AButtonViewInfo.Index > 1 then
      Result := AFastButtonPositionA[ButtonsPosition, TcxSpinEditButton(AButtonViewInfo.Index)]
    else
      Result := AButtonPositionA[Length(ButtonsInfo) > 2, ButtonsPosition,
        TcxSpinEditButton(AButtonViewInfo.Index)];
  end;

const
  ABrushColorA: array [TcxEditButtonState] of TColor = (
    clBtnFace, clBtnFace, clBtnText, clBtnShadow
  );
begin
  with AButtonViewInfo do
  begin
    ABrushColor := ABrushColorA[Data.State];
    if Data.Transparent then
      ABrushColor := Data.BackgroundColor;

    if Data.State in [ebsPressed, ebsSelected] then
      if Data.Transparent and (Data.State = ebsSelected) then
        APenColor := clBtnShadow
      else
        APenColor := clBtnHighlight
    else
      APenColor := clBtnText;
    DrawSpinEditFlatButtonBorder(ACanvas, GetButtonPosition, ARect, ABrushColor, clBtnShadow);

    AContentRect := ARect;
  end;
end;

procedure TcxSpinEditViewInfo.DrawNativeButtonBorder(ACanvas: TcxCanvas; AButtonViewInfo: TcxEditButtonViewInfo;
  var ARect: TRect; out AContentRect: TRect; var APenColor, ABrushColor: TColor);
begin
  if IsCustomDrawButton then
    AContentRect := ARect
  else
    AContentRect := cxEmptyRect;
end;

procedure TcxSpinEditViewInfo.DrawUltraFlatButtonBorder(ACanvas: TcxCanvas; AButtonViewInfo: TcxEditButtonViewInfo;
  AIsOffice11Style: Boolean; var ARect: TRect; var AContentRect: TRect; out APenColor, ABrushColor: TColor);
var
  AButtonPosition: TcxSpinEditUltraFlatButtonPosition;
begin
  with ACanvas, AButtonViewInfo do
  begin
    if AButtonViewInfo.Data.Transparent then
      ABrushColor := Data.BackgroundColor
    else
      if AButtonViewInfo.Data.State = ebsDisabled then
        ABrushColor := clBtnFace
      else
        if AButtonViewInfo.Data.State = ebsNormal then
          if AIsOffice11Style then
            ABrushColor := dxOffice11DockColor1
          else
            ABrushColor := clBtnFace
        else
          ABrushColor := GetEditButtonHighlightColor(
            AButtonViewInfo.Data.State = ebsPressed, AIsOffice11Style);
    case AButtonViewInfo.Index  of
      cxSpinFastBackwardButtonIndex:
        if ButtonsPosition = sbpHorzLeftRight then
          AButtonPosition := sufbpLeftMost
        else
          AButtonPosition := sufbpMiddle;
      cxSpinFastForwardButtonIndex:
        AButtonPosition := sufbpRightMost;
      cxSpinBackwardButtonIndex:
        if ButtonsPosition = sbpVert then
          if Length(ButtonsInfo) > 2 then
            AButtonPosition := sufbpMiddleBottom
          else
            AButtonPosition := sufbpRightBottom
        else
          if (Length(ButtonsInfo) = 2) and (ButtonsPosition = sbpHorzLeftRight) then
            AButtonPosition := sufbpLeftMost
          else
            AButtonPosition := sufbpMiddle;
      else
        if ButtonsPosition = sbpVert then
          if Length(ButtonsInfo) > 2 then
            AButtonPosition := sufbpMiddleTop
          else
            AButtonPosition := sufbpRightTop
        else
          if Length(ButtonsInfo) > 2 then
            AButtonPosition := sufbpMiddle
          else
            AButtonPosition := sufbpRightMost;
    end;
    DrawSpinEditUltraFlatButtonBorder(ACanvas, ARect,
      AButtonPosition, ABrushColor, AButtonViewInfo, BorderRect,
      Transparent, epoHasExternalBorder in PaintOptions, Self.BorderStyle,
      ARect, AContentRect);
  end;
end;

procedure TcxSpinEditViewInfo.DrawNativeButtonBackground(ACanvas: TcxCanvas; AButtonViewInfo: TcxEditButtonViewInfo; const ARect: TRect);
begin
  with AButtonViewInfo do
    DrawThemeBackground(OpenTheme(totSpin), ACanvas.Handle, Data.NativePart,
      Data.NativeState, ARect)
end;

procedure TcxSpinEditViewInfo.InternalPaint(ACanvas: TcxCanvas);

⌨️ 快捷键说明

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