Можно ли контролировать отображение вкладок в компоненте JvDockServer? - PullRequest
3 голосов
/ 09 июля 2011

Если вы запустите AdvanceDemo в примере кода JvCL JVCL, выбрав VSNetStyle, вы можете перетащить вторую форму на основную форму;отобразится вкладка с названием второй формы.Если вы затем перетащите другую форму на ту же сторону основной формы, будет создана другая вкладка.Две вкладки будут перекрываться:

screenshot of overlapping tabs

Есть ли способ контролировать, насколько эти две вкладки перекрываются?Мне бы хотелось, чтобы вкладки были достаточно разделены, чтобы пользователи могли читать текст на обеих вкладках.

Спасибо, как всегда - Al C.

1 Ответ

5 голосов
/ 09 июля 2011

Как прокомментировал, я также думаю, что это ошибка.Точнее, ошибка в TJvDockVSChannel.Paint, которая рисует вкладки (внутренне вкладки называются blocks ).У такого блока есть защищенное свойство InactiveBlockWidth , имя которого предлагает управлять его шириной.Это свойство отлично работает для самой вкладки, но заголовок снова смещается на ту же величину в TJvDockVSChannel.Paint, что, как мне кажется, является проблемой.

Вы можете поэкспериментировать, назначив событие OnFinishSetDockPanelSizeDockServer:

type
  TJvDockVSBlockAccess = class(TJvDockVSBlock);

procedure TMainForm.lbDockServer1FinishSetDockPanelSize(
  DockPanel: TJvDockPanel);
var
  Channel: TJvDockVSChannel;
  Block: TJvDockVSBlockAccess;
  i: Integer;
begin
  if DockPanel is TJvDockVSNETPanel then
  begin
    Channel := TJvDockVSNETPanel(DockPanel).VSChannel;
    for i := 0 to Channel.BlockCount - 1 do
    begin
      Block := TJvDockVSBlockAccess(Channel.Block[i]);
      Block.InactiveBlockWidth := 100;
    end;
  end;
end;

Поскольку это защищенное свойство на данный момент, это может указывать на то, что его функциональность находится в стадии разработки .Я полагаю, что команда разработчиков Jedi на данный момент решила нарисовать только глиф каждой неактивной вкладки, потому что отсутствует полная реализация для динамической обработки ширины вкладок.Например, вы должны иметь возможность установить минимальную ширину каждой вкладки, и когда полоса (т. Е. Контейнер, в котором она находится) меняет высоту, все вкладки должны соответственно расширяться или сужаться.

Редактировать:

Благодаря гибкой конструкции вы можете обойти ошибку, установив свойство DockPanelClass в DockServer.Я полагаю, что свойство должно быть установлено до установки свойства Style.Он включает в себя переписывание всей подпрограммы Paint, потому что InactiveBlockWidth также используется в GetBlockRect, который, в свою очередь, не является виртуальным:

type
  TJvDockVSBlockAccess = class(TJvDockVSBlock);

  THackJvDockVSNETPanel = class(TJvDockVSNETPanel)
  public
    constructor Create(AOwner: TComponent); override;
  end;

  THackJvDockVSChannel = class(TJvDockVSChannel)
  protected
    procedure Paint; override;
    procedure ResetBlock; override;
    procedure Resize; override;
  end;

const
  InactiveTabWidth = 100;

{ TMainForm }

procedure TMainForm.FormCreate(Sender: TObject);
begin
  ...
  JvDockVSNetStyle1.DockPanelClass := THackJvDockVSNETPanel;
end;

{ THackJvDockVSNETPanel }

constructor THackJvDockVSNETPanel.Create(AOwner: TComponent);
begin
  inherited Create(AOwner);
  VSChannelClass := THackJvDockVSChannel;
end;

{ THackJvDockVSChannel }

procedure THackJvDockVSChannel.Paint;
var
  I: Integer;

  procedure DrawSingleBlock(Block: TJvDockVSBlockAccess);
  var
    DrawRect: TRect;
    I: Integer;
    OldGraphicsMode: Integer;
    VisiblePaneCount: Integer;

    procedure AdjustImagePos;
    begin
      if Align = alLeft then
      begin
        Inc(DrawRect.Left, 3);
        Inc(DrawRect.Top, 4);
      end
      else if Align = alTop then
      begin
        Inc(DrawRect.Left, 4);
        Inc(DrawRect.Top, 2);
      end
      else if Align = alRight then
      begin
        Inc(DrawRect.Left, 4);
        Inc(DrawRect.Top, 4);
      end
      else if Align = alBottom then
      begin
        Inc(DrawRect.Left, 4);
        Inc(DrawRect.Top, 3);
      end;
    end;

  begin
    VisiblePaneCount := 0;
    for I := 0 to Block.VSPaneCount - 1 do
    begin
      if not Block.VSPane[I].Visible then
        Continue;
      GetBlockRect(Block, I, DrawRect);
      Canvas.Brush.Color := TabColor;
      Canvas.FillRect(DrawRect);
      Canvas.Brush.Color := clGray;
      Canvas.FrameRect(DrawRect);
      AdjustImagePos;
      Block.ImageList.Draw(Canvas, DrawRect.Left, DrawRect.Top, I);
      if Align in [alTop, alBottom] then
        Inc(DrawRect.Left, 24)
      else if Align in [alLeft, alRight] then
      begin
        Inc(DrawRect.Top, 24);
        if Align = alLeft then
          DrawRect.Left := 15
        else
          DrawRect.Left := 20;
        DrawRect.Right := DrawRect.Left + (DrawRect.Bottom - DrawRect.Top);
      end;
      Canvas.Brush.Color := TabColor;
      Canvas.Pen.Color := clBlack;
      Dec(DrawRect.Right, 3);
      OldGraphicsMode := SetGraphicsMode(Canvas.Handle, GM_ADVANCED);
      Canvas.Brush.Style := bsClear;
      DrawText(Canvas.Handle, PChar(Block.VSPane[I].DockForm.Caption), -1,
        DrawRect, DT_END_ELLIPSIS or DT_NOCLIP);
      SetGraphicsMode(Canvas.Handle, OldGraphicsMode);
      Inc(VisiblePaneCount);
    end;
    if VisiblePaneCount > 0 then
      CurrentPos := CurrentPos + BlockInterval;
  end;

begin
  ResetBlock;
  CurrentPos := BlockStartOffset;
  for I := 0 to BlockCount - 1 do
    DrawSingleBlock(TJvDockVSBlockAccess(Block[I]));
end;

procedure THackJvDockVSChannel.ResetBlock;
var
  I: Integer;
begin
  inherited ResetBlock;
  for I := 0 to BlockCount - 1 do
    TJvDockVSBlockAccess(Block[I]).InactiveBlockWidth := InactiveTabWidth;
end;

procedure THackJvDockVSChannel.Resize;
begin
  { Here you could widen or narrow the tabs according the total space and
    depending on the number of tabs }
  inherited Resize;
end;

Sample of widened tabs

...