cxnavigator.pas

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

PAS
1,873
字号
  AHotTrackButton := nil;
  APressedButton := nil;
  if FHotTrackButtonViewInfo <> nil then
    AHotTrackButton := FHotTrackButtonViewInfo.Button;
  if FPressedButtonViewInfo <> nil then
    APressedButton := FPressedButtonViewInfo.Button;
  FHotTrackButtonViewInfo := nil;
  FPressedButtonViewInfo := nil;

  AMinWidth := 0;
  AMinHeight := 0;
  ANavigatorButtons := Navigator.GetNavigatorButtons;
  AVisibleButtonCount := GetVisibleButtonCount;
  CheckButtonCount;
  AButtonVisibleIndex := 0;

  for I := 0 to  ANavigatorButtons.ButtonCount - 1 do
    if ANavigatorButtons[I].Visible then
    begin
      AButtonViewInfo := TcxNavigatorButtonViewInfo(FButtons[AButtonVisibleIndex]);
      AButtonViewInfo.Button := ANavigatorButtons[I];
      if AButtonViewInfo.Button = APressedButton then
        FPressedButtonViewInfo := AButtonViewInfo;
      if AButtonViewInfo.Button = AHotTrackButton then
        FHotTrackButtonViewInfo := AButtonViewInfo;
      AMinSize := GetMinButtonSize(AButtonVisibleIndex, AVisibleButtonCount,
        ACheckMinHeight);
      Inc(AMinWidth, AMinSize.cx);
      if AMinHeight < AMinSize.cy then
        AMinHeight := AMinSize.cy;
      Inc(AButtonVisibleIndex);
    end;
  ADifX := 0;
  if AHeight < AMinHeight then
    AHeight := AMinHeight;
  if AWidth < AMinWidth then
    AWidth := AMinWidth
  else
  begin
    if ButtonCount > 0 then
      ADifX := (AWidth - AMinWidth) div ButtonCount;
    AWidth := AMinWidth + ADifX * ButtonCount;
  end;
  AButtonBounds.Right := ANavigatorBounds.Left;
  AButtonBounds.Top := ANavigatorBounds.Top;
  AButtonBounds.Bottom := AButtonBounds.Top + AHeight;
  for I := 0 to ButtonCount - 1 do
  begin
    AButtonBounds.Left := AButtonBounds.Right;
    AButtonBounds.Right := AButtonBounds.Right + GetMinButtonSize(I, AVisibleButtonCount).cx + ADifX;
    Buttons[I].Bounds := AButtonBounds;
  end;
end;

procedure TcxNavigatorViewInfo.Clear;
var
  I: Integer;
begin
  FIsDirty := True;
  FHotTrackButtonViewInfo := nil;
  FPressedButtonViewInfo := nil;
  for I := 0 to ButtonCount - 1 do
    TcxNavigatorButtonViewInfo(FButtons[I]).Free;
  FButtons.Clear;
end;

procedure TcxNavigatorViewInfo.DoEnter;
begin
  InvalidateButton(FocusedButton);
  UpdateSelected;
end;

procedure TcxNavigatorViewInfo.DoExit;
begin
  InvalidateButton(FocusedButton);
  UpdateSelected;
end;

function TcxNavigatorViewInfo.GetButtonAt(const pt: TPoint): TcxNavigatorButton;
var
  AViewInfo: TcxNavigatorButtonViewInfo;
begin
  AViewInfo := GetButtonViewInfoAt(pt);
  if AViewInfo <> nil then
    Result := AViewInfo.Button
  else
    Result := nil;
end;

function TcxNavigatorViewInfo.GetButtonViewInfoAt(const pt: TPoint): TcxNavigatorButtonViewInfo;
var
  I: Integer;
begin
  Result := nil;
  for I := 0 to ButtonCount - 1 do
    if PtInRect(Buttons[I].Bounds, pt) then
    begin
      Result := Buttons[I];
      Break;
    end;
end;

function TcxNavigatorViewInfo.GetButtonViewInfoByButton(
  AButton: TcxNavigatorButton): TcxNavigatorButtonViewInfo;
var
  I: Integer;
begin
  Result := nil;
  for I := 0 to ButtonCount - 1 do
    if Buttons[I].Button = AButton then
    begin
      Result := Buttons[I];
      break;
    end;
end;

procedure TcxNavigatorViewInfo.MakeIsDirty;
begin
  FIsDirty := True;
end;

procedure TcxNavigatorViewInfo.MouseDown(X, Y: Integer);
var
  AButtonViewInfo: TcxNavigatorButtonViewInfo;
begin
  FHintTimer.Enabled := False;
  HintActivate(False);
  AButtonViewInfo := GetButtonViewInfoAt(Point(X, Y));
  if (AButtonViewInfo <> nil)
    and (GetButtonState(AButtonViewInfo) <> cxbsDisabled)  then
  begin
    FButtonPressTimer.Interval := cxInitRepeatPause;
    FButtonPressTimer.Enabled := True;
    PressedButtonViewInfo := AButtonViewInfo;
    FocusedButton := AButtonViewInfo;
    InvalidateButton(PressedButtonViewInfo);
  end;
  UpdateSelected;
end;

procedure TcxNavigatorViewInfo.MouseMove(X, Y: Integer);
var
  AButtonViewInfo: TcxNavigatorButtonViewInfo;
begin
  AButtonViewInfo := GetButtonViewInfoAt(Point(X, Y));
  if AButtonViewInfo <> HotTrackButtonViewInfo then
  begin
    if (HotTrackButtonViewInfo <> nil)
      and (GetButtonState(HotTrackButtonViewInfo) <> cxbsDisabled) then
      InvalidateButton(HotTrackButtonViewInfo);
    FHotTrackButtonViewInfo := AButtonViewInfo;
    if (HotTrackButtonViewInfo <> nil)
      and (GetButtonState(HotTrackButtonViewInfo) <> cxbsDisabled) then
      InvalidateButton(HotTrackButtonViewInfo);
    if FHintWindowShowing then
      HintActivate(True)
    else FHintTimer.Enabled := True;
  end;
  if HotTrackButtonViewInfo = nil then
    HintActivate(False);
  UpdateSelected;
end;

procedure TcxNavigatorViewInfo.MouseUp(X, Y: Integer);
var
  AButtonViewInfo: TcxNavigatorButtonViewInfo;
begin
  FButtonPressTimer.Enabled := False;
  AButtonViewInfo := PressedButtonViewInfo;
  FPressedButtonViewInfo := nil;
  InvalidateButton(AButtonViewInfo);
  FHintTimer.Enabled := True;
  UpdateSelected;
  if (AButtonViewInfo <> nil) and PtInRect(AButtonViewInfo.Bounds, Point(X, Y)) and AButtonViewInfo.Enabled then
    AButtonViewInfo.Button.DoClick;
end;

procedure TcxNavigatorViewInfo.Paint;
var
  R: TRect;
  I: Integer;
  ANavigatorControl: TWinControl;
begin
  FCanvas.Canvas := Navigator.GetNavigatorCanvas;
    if FIsDirty then
      Calculate;
    for I := 0 to ButtonCount - 1 do
      PaintButton(I);
    R := Navigator.GetNavigatorBounds;
    ANavigatorControl := Navigator.GetNavigatorControl;
    Navigator.GetNavigatorLookAndFeel.GetAvailablePainter(totButton).DrawButtonGroupBorder(Canvas,
      R, FIsInplace and ANavigatorControl.Enabled, FIsSelected or (not FIsInplace and
        (csDesigning in ANavigatorControl.ComponentState) and ANavigatorControl.Enabled));
    if FIsInplace then
      Canvas.ExcludeClipRect(R);
end;

procedure TcxNavigatorViewInfo.PressArrowKey(ALeftKey: Boolean);
var
  AIndex: Integer;
begin
  AIndex := FButtons.IndexOf(FocusedButton);
  if AIndex < 0 then exit;
  if ALeftKey then
  begin
    if AIndex > 0 then
      FocusedButton := Buttons[AIndex - 1];
  end else
  begin
    if AIndex < ButtonCount - 1 then
      FocusedButton := Buttons[AIndex + 1];
  end;
end;

procedure TcxNavigatorViewInfo.UpdateButtonsEnabled;
var
  I: Integer;
begin
  for I := 0 to ButtonCount - 1 do
    if Buttons[I].Enabled <> Buttons[I].Button.GetInternalEnabled then
    begin
      Buttons[I].Enabled := not Buttons[I].Enabled;
      InvalidateButton(Buttons[I]);
    end;
end;

procedure TcxNavigatorViewInfo.InvalidateButton(AButton: TcxNavigatorButtonViewInfo);
var
  ANavigatorControl: TWinControl;
begin
  if AButton <> nil then
  begin
    ANavigatorControl := Navigator.GetNavigatorControl;
    if ANavigatorControl.HandleAllocated then
      Windows.InvalidateRect(ANavigatorControl.Handle,
        @(AButton.Bounds), False);
  end;
end;

procedure TcxNavigatorViewInfo.PaintButton(AButtonIndex: Integer);

  procedure DrawButtonGlyph(ACanvas: TcxCanvas; const AGlyphRect: TRect);
  var
    AButton: TcxNavigatorButtonViewInfo;
    AButtonState: TcxButtonState;
    APainter: TcxCustomLookAndFeelPainterClass;
  begin
    AButton := TcxNavigatorButtonViewInfo(FButtons[AButtonIndex]);
    AButtonState := GetButtonState(AButton);
    APainter := Navigator.GetNavigatorLookAndFeel.GetAvailablePainter(totButton);
    APainter.DrawNavigatorGlyph(ACanvas, AButton.Button.InternalImages,
        AButton.Button.InternalImageIndex, AButtonIndex, AGlyphRect,
        AButtonState <> cxbsDisabled, AButton.Button.IsUserImageListUsed);
  end;

var
  ABitmap: TcxCustomBitmap;
  AButton: TcxNavigatorButtonViewInfo;
  AButtonBounds, AContentRect, AImageRect, R1: TRect;
  AButtonState: TcxButtonState;
  AImageSize: TSize;
  APainter: TcxCustomLookAndFeelPainterClass;
  ACanvas: TcxCanvas;
begin
  AButton := TcxNavigatorButtonViewInfo(FButtons[AButtonIndex]);
  AButtonBounds := AButton.Bounds;
  if not Canvas.RectVisible(AButtonBounds) then
    Exit;
  AButtonState := GetButtonState(AButton);
  APainter := Navigator.GetNavigatorLookAndFeel.GetAvailablePainter(totButton);
  AButtonBounds := APainter.AdjustGroupButtonDisplayRect(AButtonBounds, FButtons.Count, AButtonIndex);
  AImageSize := AButton.Button.GetImageSize;
  AContentRect := AButtonBounds;
  ExtendRect(AContentRect, GetButtonBorderExtent(APainter, AButtonIndex, FButtons.Count));
  with AContentRect do
  begin
    AImageRect.Left := Left + (Right - Left - AImageSize.cx) div 2;
    AImageRect.Top := Top + (Bottom - Top - AImageSize.cy) div 2;
    AImageRect.Right := AImageRect.Left + AImageSize.cx;
    AImageRect.Bottom := AImageRect.Top + AImageSize.cy;
    if GetButtonState(AButton) = cxbsPressed then
      OffsetRect(AImageRect, 1, 1);
  end;

  ABitmap := TcxCustomBitmap.CreateSize(cxRectWidth(AButtonBounds), cxRectHeight(AButtonBounds), pf32bit);
  try
    ACanvas := ABitmap.cxCanvas;
    cxDrawTransparentControlBackground(Navigator.GetNavigatorControl, ACanvas,
      AButtonBounds);
    APainter.DrawButtonInGroup(ACanvas, ABitmap.ClientRect,
      AButtonState, FButtons.Count, AButtonIndex, clWindow);
      
    R1 := AImageRect;
    OffsetRect(R1, - AButtonBounds.Left, - AButtonBounds.Top);
    DrawButtonGlyph(ACanvas, R1);
    cxBitBlt(Canvas.Handle, ACanvas.Handle, AButtonBounds, cxNullPoint, SRCCOPY);

    if Navigator.GetNavigatorTabStop and (AButton = FocusedButton) and
       Navigator.GetNavigatorFocused
    then
       Canvas.DrawFocusRect(AImageRect);

    if APainter = TcxWinXPLookAndFeelPainter then
     Canvas.ExcludeClipRect(AButton.Bounds);  
  finally
    FreeAndNil(ABitmap);
  end;
end;

procedure TcxNavigatorViewInfo.HintActivate(AShow: Boolean);

  function NeedShowHint(const AHint: string): Boolean;
  begin
    Result := AShow and Navigator.GetNavigatorShowHint and (AHint <> '') and
      CanShowHint(Navigator.GetNavigatorControl);
  end;

var
  AHint: string;
  P: TPoint;
  R: TRect;
begin
  if FHintWindow <> nil then
  begin
    FHintWindow.Hide;
    if IsWindowVisible(FHintWindow.Handle) then
      ShowWindow(FHintWindow.Handle, SW_HIDE);
    FreeAndNil(FHintWindow);
  end;
  FHintTimer.Enabled := False;
  FHintWindowShowing := False;
  if (HotTrackButtonViewInfo <> nil) then
    AHint := GetShortHint(HotTrackButtonViewInfo.Hint)
  else
    AHint := '';
  if NeedShowHint(AHint) then
  begin
    FHintWindow := HintWindowClass.Create(nil);
    P := InternalGetCursorPos;
    Inc(P.Y, cxGetCursorSize.cy);
    R := FHintWindow.CalcHintRect(Screen.Width, AHint, nil);
    R := Rect(P.X, P.Y, P.X + R.Right, P.Y + R.Bottom - R.Top);
    FHintWindow.Color := Application.HintColor;
  {$IFDEF DELPHI7}
    FHintWindow.ParentWindow := Application.Handle; //Bug in delphi7 and higher
  {$ENDIF}
    FHintWindow.ActivateHint(R, AHint);
    FHintWindowShowing := True;
  end;
end;

function TcxNavigatorViewInfo.GetButton(Index: Integer): TcxNavigatorButtonViewInfo;
begin
  Result := TcxNavigatorButtonViewInfo(FButtons[Index]);
end;

function TcxNavigatorViewInfo.GetButtonCount: Integer;
begin
  Result := FButtons.Count;
end;

function TcxNavigatorViewInfo.GetFocusedButton: TcxNavigatorButtonViewInfo;
begin
  if (FFocusedButton <> nil) and not FFocusedButton.Visible then
    FFocusedButton := nil;
  if (FFocusedButton = nil) and (ButtonCount > 0) then
    FFocusedButton := Buttons[0].Button;
  if (FFocusedButton <> nil) then
    Result := GetButtonViewInfoByButton(FFocusedButton)
  else Result := nil;
end;

procedure TcxNavigatorViewInfo.SetFocusedButton(Value: TcxNavigatorButtonViewInfo);
var
  AOldButtonViewInfo: TcxNavigatorButtonViewInfo;
begin
  AOldButtonViewInfo := GetFocusedButton;
  if AOldButtonViewInfo <> Value then
  begin
    FFocusedButton := Value.Button;
    InvalidateButton(AOldButtonViewInfo);
    InvalidateButton(Value);
  end;
end;

function TcxNavigatorViewInfo.StopButtonPressTimerIfLeftMouseReleased: Boolean;
begin
  if not (ssLeft in InternalGetShiftState) then
  begin
    FButtonPressTimer.Enabled := False;
    MouseUp(-1, -1);
    Result := True;
  end
  else
    Result := False;
end;

function TcxNavigatorViewInfo.GetButtonBorderExtent(APainter: TcxCustomLookAndFeelPainterClass;
  AButtonIndex, AButtonCount: Integer): TRect;
begin
  Result := APainter.ButtonGroupBorderSizes(AButtonCount, AButtonIndex);
end;

function TcxNavigatorViewInfo.GetButtonState(AButton: TcxNavigatorButtonViewInfo): TcxButtonState;
begin
  Result := cxbsNormal;
  if not AButton.Enabled then
    Result := cxbsDisabled
  else
    if (AButton = PressedButtonViewInfo)
      and (AButton = HotTrackButtonViewInfo) then
      Result := cxbsPressed
    else
      if AButton = HotTrackButtonViewInfo then
        Result := cxbsHot;
end;

function TcxNavigatorViewInfo.GetMiddleButtonBorderExtent(
  APainter: TcxCustomLookAndFeelPainterClass): TRect;
begin
  Result := APainter.ButtonGroupBorderSizes(3, 1);
end;

function TcxNavigatorViewInfo.GetMinButtonSize(
  AButtonIndex, AButtonCount: Integer; AAutoHeight: Boolean = False): TSize;
var
  AButtonBorderExtent: TRect;
  APainter: TcxCustomLookAndFeelPainterClass;
begin
  Result := TcxNavigatorButtonViewInfo(FButtons[AButtonIndex]).Button.GetImageSize;
  APainter := Navigator.GetNavigatorLookAndFeel.GetAvailablePainter(totButton);
  AButtonBorderExtent := GetMiddleButtonBorderExtent(APainter);
  Result.cx := Result.cx + AButtonBorderExtent.Left + AButtonBorderExtent.Right + 1;
  if AAutoHeight then
    Result.cy := Result.cy + AButtonBorderExtent.Top + AButtonBorderExtent.Bottom + 1
  else
    Result.cy := AButtonBorderExtent.Top + AButtonBorderExtent.Bottom + 1;
end;

function TcxNavigatorViewInfo.GetVisibleButtonCount: Integer;
var
  ANavigatorButtons: TcxCustomNavigatorButtons;
  I: Integer;
begin
  Result := 0;
  ANavigatorButtons := Navigator.GetNavigatorButtons;
  for I := 0 to  ANavigatorButtons.ButtonCount - 1 do
    if ANavigatorButtons[I].Visible then
      Inc(Result);
end;

procedure TcxNavigatorViewInfo.DoButtonPressTimer(Sender: TObject);
begin
  if StopButtonPressTimerIfLeftMouseReleased then
    Exit;
  FButtonPressTimer.Interval := cxRepeatPause;
  if (HotTrackButtonViewInfo <> nil) and (HotTrackButtonViewInfo = PressedButtonViewInfo) and
      PressedButtonViewInfo.Enabled and (PressedButtonViewInfo.Button.DefaultIndex in [NBDI_PRIOR, NBDI_NEXT]) then
    try
      PressedButtonViewInfo.Button.DoClick;
    except
      FButtonPressTimer.Enabled := False;
      raise;
    end;
end;

procedure TcxNavigatorViewInfo.DoHintTimer(Sender: TObject);
begin
  HintActivate(True);

⌨️ 快捷键说明

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