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

📄 dxpagecontrol.pas

📁 PageControl 2.0 与1.0兼营版控件 ,TPageControl的扩展。增强了一些功能。
💻 PAS
📖 第 1 页 / 共 5 页
字号:
        begin
          PSource := ScanLine[YSource];
          PDest := PDestStart;
          for XSource := 0 to Width - 1 do
          begin
            PDest^ := PSource^;
            Dec(PDest, Height * LineCopyingDirection);
            Inc(PSource);
          end;
          Inc(PDestStart, LineCopyingDirection);
        end;

        TempVar := Width;
        Width := Height;
        Height := TempVar;
        if Width = Height then
        begin
          Width := Width + 1;
          Width := Width - 1;
        end;

        PDest := PBuffer;
        for YSource := 0 to Height - 1 do
        begin
          Move(PDest^, ScanLine[YSource]^, Width * 4);
          Inc(PDest, Width);
        end;

        FreeMem(PBuffer);
      end;
  end;
end;
{$ENDIF}

function Size(cx, cy: Longint): TSize;
begin
  Result.cx := cx;
  Result.cy := cy;
end;

procedure ValidateRect(var R: TRect);
begin
  with R do
  begin
    if Right < Left then
      Right := Left;
    if Bottom < Top then
      Bottom := Top;
  end;
end;

function VerifyImageList(Images: TImageList): Boolean;
begin
  Result := (Images <> nil) and (Images.Count > 0);
end;

procedure TcxCustomTabControl.ArrowButtonClick(
  NavigatorButton: TcxPCNavigatorButton);
var
//  TooSmallControlSize: Boolean;
  SpecialAlignment: Boolean;
  Direction: Integer;
begin
  if FNavigatorButtonStates[NavigatorButton] = nbsDisabled then Exit;
  SpecialAlignment := IsRightToLeftAlignment(Self) or IsBottomToTopAlignment(Self);
  if (SpecialAlignment and (NavigatorButton = nbTopLeft)) or
     ((not SpecialAlignment) and (NavigatorButton = nbBottomRight)) then
    Direction := 1
  else
    Direction := -1;
  Inc(FFirstVisibleTab, Direction);
  if Rotate then RequestLayout
  else
  begin
//    CalculateLongitudinalTabPositions(TooSmallControlSize);
//    FPainter.RepaintTabsRegion;
//    SynchronizeHotTrackStates(InternalGetShiftState);
    RequestLayout;
  end;
end;

procedure TcxCustomTabControl.Calculate;

var
  cTabsDistance: Integer; // c - longitudinal coordinate
  TooSmallControlSize: Boolean;

  function InitializeVariables: Boolean;
  begin
    FNavigatorButtons := [];
    SynchronizeNavigatorButtons;
    FTabsPosition := FPainter.GetTabsPosition([]);
    Result := FTabsPosition.NormalRowWidth > 0;
    if not Result then Exit;
    cTabsDistance := DistanceGetter(FPainter.GetTabsNormalDistance, not Rotate{along "c" axis});
  end;

  procedure MultiLineCalculate;
  begin
    if not InitializeVariables then Exit;

    PlaceVisibleTabsOnRows(FTabsPosition.NormalRowWidth, cTabsDistance);
    CalculateLongitudinalTabPositions(TooSmallControlSize);
    CalculateRowHeight;
    RearrangeRows;
  end;

  procedure NotMultiLineCalculate;

    procedure SetTabRows;
    var
      FirstIndex, LastIndex, I: Integer;
    begin
      InitializeVisibleTabRange(Self, FirstIndex, LastIndex);
      for I := FirstIndex to LastIndex do
        with FVisibleTabList[I] do
        begin
          FRow := 0;
          FVisibleRow := 0;
        end;
    end;

  begin
    FRowCount := 1;
    if TabPosition in [tpTop, tpLeft] then FTopOrLeftPartRowCount := 1
    else FTopOrLeftPartRowCount := 0;
    CalculateLongitudinalTabPositions(TooSmallControlSize);
    if TooSmallControlSize then Exit;
    SetTabRows;
    CalculateRowHeight;
    CalculateRowPositions;
  end;

  procedure ResetControlInternalVariables;
  var
    VisibleTabCount: Integer;

    procedure ValidateTabVisibleIndex(var TabVisibleIndex: Integer);
    begin
      if TabVisibleIndex >= VisibleTabCount then
        TabVisibleIndex := -1;
    end;

  begin
    VisibleTabCount := FVisibleTabList.Count;

    FillChar(FExtendedBottomOrRightTabsRect, SizeOf(TRect), 0);
    FillChar(FExtendedTopOrLeftTabsRect, SizeOf(TRect), 0);

    if (FFirstVisibleTab = -1) and (VisibleTabCount > 0) then
      FFirstVisibleTab := 0;
    if FFirstVisibleTab >= VisibleTabCount then
      FFirstVisibleTab := VisibleTabCount - 1;
    FLastVisibleTab := FFirstVisibleTab;

    ValidateTabVisibleIndex(FHotTrackTabVisibleIndex);
    ValidateTabVisibleIndex(FMainTabVisibleIndex);
    ValidateTabVisibleIndex(FPressedTabVisibleIndex);

    FRowCount := 0;

    if FTabIndex >= Tabs.Count then
      FTabIndex := Tabs.Count - 1;

    FTopOrLeftPartRowCount := 0;
  end;

begin
  ResetControlInternalVariables;
  if FVisibleTabList.Count = 0 then Exit;
  CalculateTabNormalSizes;
  if MultiLine then MultiLineCalculate else NotMultiLineCalculate;
end;

procedure TcxCustomTabControl.CalculateLongitudinalTabPositions(var TooSmallControlSize: Boolean);
var
  cFinish, cStart, cTabsDistance: Integer; // c - longitudinal coordinate
  dSign: Integer;
  cIsY: Boolean;
  LineIndexBoundsA: TcxPCLineIndexBoundsArray;
  cMinTabSelectionDistance: Integer;

  procedure InitializeVariables(NavigatorButtons: TcxPCNavigatorButtons);
  begin
    TooSmallControlSize := True;
    FNavigatorButtons := NavigatorButtons;
    FTabsPosition := FPainter.GetTabsPosition(NavigatorButtons);
    if FTabsPosition.NormalRowWidth <= 0 then Exit else TooSmallControlSize := False;

    cIsY := TabPosition in [tpLeft, tpRight];
    cStart := PointGetter(FTabsPosition.NormalTabsRect.TopLeft, cIsY);
    dSign := 1;
    if IsRightToLeftAlignment(Self) or IsBottomToTopAlignment(Self) then
    begin
      cFinish := -cStart;
      Inc(cStart, FTabsPosition.NormalRowWidth - 1);
      dSign := -1;
    end else
      cFinish := cStart + FTabsPosition.NormalRowWidth - 1;
    cTabsDistance := DistanceGetter(FPainter.GetTabsNormalDistance, not Rotate{along "c" axis});
    cMinTabSelectionDistance := DistanceGetter(FPainter.GetMinTabSelectionDistance, not Rotate);
  end;

  function InternalCalculateLongitudinalTabPositions(Row: Integer = -1): Boolean;
  var
    I: Integer;
    c, cTabFinish, cTabWidth: Integer;
    FirstIndex, LastIndex: Integer;
  begin
    Result := True;

    if FRowCount > 1(*MultiLine*) then
    begin
      FirstIndex := LineIndexBoundsA[Row].Left;
      LastIndex := LineIndexBoundsA[Row].Right;
    end
    else
    begin
      FirstIndex := FFirstVisibleTab;
      LastIndex := FVisibleTabList.Count - 1;
    end;

    c := cStart;
    for I := FirstIndex to LastIndex do
    begin
      if (c + (cMinTabSelectionDistance - 1) * dSign) * dSign > cFinish then
        Result := False;
      cTabWidth := FVisibleTabList[I].NormalLongitudinalSize;
      cTabFinish := c + (cTabWidth - 1) * dSign;
      with FVisibleTabList[I].FTabPosition do
        if dSign > 0 then PointSetter(TabNormalPosition, cIsY, c)
        else PointSetter(TabNormalPosition, cIsY, cTabFinish);
      FIsLastVisibleTabFullyVisible := cTabFinish * dSign <= cFinish;
      c := cTabFinish + (1 + cTabsDistance) * dSign;
      if c * dSign > cFinish then
      begin
        if I < LastIndex then Result := False;
        FLastVisibleTab := I;
        Exit;
      end;
    end;
    if not MultiLine then FLastVisibleTab := LastIndex;
  end;

  procedure NotMultiLineCalculateLongitudinalTabPositions;
  var
    OnlyObligatoryButtons, r: Boolean;
    OldFirstVisibleTab: Integer;
  begin
    repeat
      OldFirstVisibleTab := FFirstVisibleTab;
      FFirstVisibleTab := 0;
      OnlyObligatoryButtons := True;
      InitializeVariables(GetNavigatorButtons(OnlyObligatoryButtons));
      if TooSmallControlSize then Exit;
      r := InternalCalculateLongitudinalTabPositions;
      if r and FIsLastVisibleTabFullyVisible then Break;
      OnlyObligatoryButtons := False;
      FFirstVisibleTab := OldFirstVisibleTab;
      InitializeVariables(GetNavigatorButtons(OnlyObligatoryButtons));
      if TooSmallControlSize then Exit;
      r := InternalCalculateLongitudinalTabPositions;

      if r and FIsLastVisibleTabFullyVisible then
        while FFirstVisibleTab > 0 do
        begin
          Dec(FFirstVisibleTab);
          r := InternalCalculateLongitudinalTabPositions;
          if (not r) or (not FIsLastVisibleTabFullyVisible) then
          begin
            Inc(FFirstVisibleTab);
            InternalCalculateLongitudinalTabPositions;
            Break;
          end;
        end;
    until True;
    SynchronizeNavigatorButtons;
    UpdateArrowButtonsState;
  end;

  procedure MultiLineCalculateLongitudinalTabPositions;
  var
    LineFreeSpaceWidth, LineFreeSpaceWidthRest, TotalTabsNormalWidth: Integer;

    procedure StretchTabWidths(Row: Integer);
    var
      I: Integer;
      dTabNormalWidth: Integer;
    begin
      LineFreeSpaceWidthRest := LineFreeSpaceWidth;
      for I := LineIndexBoundsA[Row].Left to LineIndexBoundsA[Row].Right do
        with FVisibleTabList[I].FTabPosition do
        begin
          if I = LineIndexBoundsA[Row].Right then dTabNormalWidth := LineFreeSpaceWidthRest
          else dTabNormalWidth := TabNormalWidth * LineFreeSpaceWidth div TotalTabsNormalWidth;
          Dec(LineFreeSpaceWidthRest, dTabNormalWidth);
          Inc(TabNormalWidth, dTabNormalWidth);
        end;
    end;

  var
    Row: Integer;
    ToStretchTabs: Boolean;
  begin
    InitializeVariables([]);
    if TooSmallControlSize then Exit;
    InitializeLineBoundsA(LineIndexBoundsA, 0, FVisibleTabList.Count - 1);
    ToStretchTabs := not(Rotate or RaggedRight);
    for Row := 0 to RowCount - 1 do
    begin
      if ToStretchTabs then
      begin
        TotalTabsNormalWidth := GetLineWidth(LineIndexBoundsA, Row, 0);
        LineFreeSpaceWidth := FTabsPosition.NormalRowWidth - GetLineWidth(LineIndexBoundsA, Row, cTabsDistance);
        if LineFreeSpaceWidth > 0 then StretchTabWidths(Row);
      end;
      InternalCalculateLongitudinalTabPositions(Row);
    end;
  end;

  procedure SetLongitudinalExtendedTabsRectsBounds;
  begin
    if TabPosition in [tpTop, tpBottom] then
    begin
      with FExtendedBottomOrRightTabsRect, FTabsPosition do
      begin
        Left := ExtendedTabsRect.Left;
        Right := ExtendedTabsRect.Right;
      end;
      with FExtendedTopOrLeftTabsRect, FTabsPosition do
      begin
        Left := ExtendedTabsRect.Left;
        Right := ExtendedTabsRect.Right;
      end;
    end else
    begin
      with FExtendedBottomOrRightTabsRect, FTabsPosition do
      begin
        Top := ExtendedTabsRect.Top;
        Bottom := ExtendedTabsRect.Bottom;
      end;
      with FExtendedTopOrLeftTabsRect, FTabsPosition do
      begin
        Top := ExtendedTabsRect.Top;
        Bottom := ExtendedTabsRect.Bottom;
      end;
    end;
  end;

begin
  if FVisibleTabList.Count = 0 then
    Exit;
  if FRowCount > 1(*MultiLine*) then
    MultiLineCalculateLongitudinalTabPositions
  else
    NotMultiLineCalculat

⌨️ 快捷键说明

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