norgepaul / TChromeTabs

Comprehensive Delphi implementation of Chrome's tab system
Other
218 stars 78 forks source link

Problems with scrolling and closing tabs #63

Open IgitBuh opened 6 years ago

IgitBuh commented 6 years ago

First of all let me thank you for this awesome Delphi component! I love how you took care about the smallest details and made this component extremely flexible to use! Having said that, I found some glitches that I'd like to address, hoping you could fix them to make this component even better.

  1. The width of the tabs isn’t initialized correctly if the close button is visible and TabWidthFromContent is set to True. The initial width ignores the close button area, so the text is cut off. After launching the program, one has to move the cursor over the component, then move it out again, then the component fixes all tab widths automatically.

  2. AutoHideButtons = True causes the scroll buttons to initialize as a tiny area in the top left if there are initially enough tabs to make the scroll buttons visible from the beginning. Moving the cursor over the component and out again fixes their position, but not their state. One has to click the left scroll button to make it disabled (as it should be because you can’t scroll further left). Demonstration of 1 and 2: tchrometabs-scrollbuttons2

  3. Closing tab with TabWidthFromContent = True is somewhat buggy. First, the button right from the closed tab changes its size to the closed tab size. Maybe you made this so the user can directly click on the close button of the next tab, but I think it’s wrong to cut the text of the next longer tab just for this. I wish there was an option to keep the widths. Second, closing the tab with enabled scrolling causes a confusing result. Demonstration of 3: tchrometabs-closetab

  4. I'd wish there was a procedure to update all positions at any time. Currently this is only triggered when the cursor leaves the component. If there was such a public procedure, one could probably work around some of the problems like these.

I'm using the latest TChromeTabs version. Here's the configuration of the described problems (I've left out the LookAndFeel part because I didn't change anything there):

  object MyChromeTabs: TChromeTabs
    Left = 32
    Top = 32
    Width = 436
    Height = 27
    ActiveTabIndex = 4
    Options.Display.CloseButton.Offsets.Vertical = 6
    Options.Display.CloseButton.Offsets.Horizontal = 2
    Options.Display.CloseButton.Height = 14
    Options.Display.CloseButton.Width = 14
    Options.Display.CloseButton.AutoHide = True
    Options.Display.CloseButton.Visibility = bvAll
    Options.Display.CloseButton.AutoHideWidth = 20
    Options.Display.CloseButton.CrossRadialOffset = 4
    Options.Display.AddButton.Offsets.Vertical = 10
    Options.Display.AddButton.Offsets.Horizontal = 2
    Options.Display.AddButton.Height = 14
    Options.Display.AddButton.Width = 31
    Options.Display.AddButton.ShowPlusSign = False
    Options.Display.AddButton.Visibility = avRightFloating
    Options.Display.AddButton.HorizontalOffsetFloating = -3
    Options.Display.ScrollButtonLeft.Offsets.Vertical = 10
    Options.Display.ScrollButtonLeft.Offsets.Horizontal = 1
    Options.Display.ScrollButtonLeft.Height = 15
    Options.Display.ScrollButtonLeft.Width = 15
    Options.Display.ScrollButtonRight.Offsets.Vertical = 10
    Options.Display.ScrollButtonRight.Offsets.Horizontal = 1
    Options.Display.ScrollButtonRight.Height = 15
    Options.Display.ScrollButtonRight.Width = 15
    Options.Display.TabModifiedGlow.Style = msRightToLeft
    Options.Display.TabModifiedGlow.VerticalOffset = -6
    Options.Display.TabModifiedGlow.Height = 30
    Options.Display.TabModifiedGlow.Width = 100
    Options.Display.TabModifiedGlow.AnimationPeriodMS = 4000
    Options.Display.TabModifiedGlow.EaseType = ttEaseInOutQuad
    Options.Display.TabModifiedGlow.AnimationUpdateMS = 50
    Options.Display.Tabs.SeeThroughTabs = False
    Options.Display.Tabs.TabOverlap = 15
    Options.Display.Tabs.ContentOffsetLeft = 18
    Options.Display.Tabs.ContentOffsetRight = 16
    Options.Display.Tabs.OffsetLeft = 0
    Options.Display.Tabs.OffsetTop = 4
    Options.Display.Tabs.OffsetRight = 0
    Options.Display.Tabs.OffsetBottom = 0
    Options.Display.Tabs.MinWidth = 100
    Options.Display.Tabs.MaxWidth = 200
    Options.Display.Tabs.TabWidthFromContent = True
    Options.Display.Tabs.PinnedWidth = 39
    Options.Display.Tabs.ImageOffsetLeft = 13
    Options.Display.Tabs.TextTrimType = tttFade
    Options.Display.Tabs.Orientation = toTop
    Options.Display.Tabs.BaseLineTabRegionOnly = False
    Options.Display.Tabs.WordWrap = False
    Options.Display.Tabs.TextAlignmentHorizontal = taLeftJustify
    Options.Display.Tabs.TextAlignmentVertical = taVerticalCenter
    Options.Display.Tabs.ShowImages = True
    Options.Display.Tabs.ShowPinnedTabText = False
    Options.Display.TabContainer.TransparentBackground = True
    Options.Display.TabContainer.OverlayButtons = True
    Options.Display.TabContainer.PaddingLeft = 0
    Options.Display.TabContainer.PaddingRight = 0
    Options.Display.TabMouseGlow.Offsets.Vertical = 0
    Options.Display.TabMouseGlow.Offsets.Horizontal = 0
    Options.Display.TabMouseGlow.Height = 200
    Options.Display.TabMouseGlow.Width = 200
    Options.Display.TabMouseGlow.Visible = True
    Options.Display.TabSpinners.Upload.ReverseDirection = True
    Options.Display.TabSpinners.Upload.RenderedAnimationStep = 2
    Options.Display.TabSpinners.Upload.Position.Offsets.Vertical = 0
    Options.Display.TabSpinners.Upload.Position.Offsets.Horizontal = 0
    Options.Display.TabSpinners.Upload.Position.Height = 16
    Options.Display.TabSpinners.Upload.Position.Width = 16
    Options.Display.TabSpinners.Upload.SweepAngle = 135
    Options.Display.TabSpinners.Download.ReverseDirection = False
    Options.Display.TabSpinners.Download.RenderedAnimationStep = 5
    Options.Display.TabSpinners.Download.Position.Offsets.Vertical = 0
    Options.Display.TabSpinners.Download.Position.Offsets.Horizontal = 0
    Options.Display.TabSpinners.Download.Position.Height = 16
    Options.Display.TabSpinners.Download.Position.Width = 16
    Options.Display.TabSpinners.Download.SweepAngle = 135
    Options.Display.TabSpinners.AnimationUpdateMS = 50
    Options.Display.TabSpinners.HideImagesWhenSpinnerVisible = True
    Options.DragDrop.DragType = dtBetweenContainers
    Options.DragDrop.DragOutsideImageAlpha = 220
    Options.DragDrop.DragOutsideDistancePixels = 30
    Options.DragDrop.DragStartPixels = 2
    Options.DragDrop.DragControlImageResizeFactor = 0.500000000000000000
    Options.DragDrop.DragCursor = crDefault
    Options.DragDrop.DragDisplay = ddTabAndControl
    Options.DragDrop.DragFormBorderWidth = 2
    Options.DragDrop.DragFormBorderColor = 8421504
    Options.DragDrop.ContrainDraggedTabWithinContainer = True
    Options.Animation.DefaultMovementAnimationTimeMS = 100
    Options.Animation.DefaultStyleAnimationTimeMS = 300
    Options.Animation.AnimationTimerInterval = 15
    Options.Animation.MinimumTabAnimationWidth = 40
    Options.Animation.DefaultMovementEaseType = ttLinearTween
    Options.Animation.DefaultStyleEaseType = ttLinearTween
    Options.Animation.MovementAnimations.TabAdd.UseDefaultEaseType = True
    Options.Animation.MovementAnimations.TabAdd.UseDefaultAnimationTime = True
    Options.Animation.MovementAnimations.TabAdd.EaseType = ttEaseOutExpo
    Options.Animation.MovementAnimations.TabAdd.AnimationTimeMS = 500
    Options.Animation.MovementAnimations.TabDelete.UseDefaultEaseType = True
    Options.Animation.MovementAnimations.TabDelete.UseDefaultAnimationTime = True
    Options.Animation.MovementAnimations.TabDelete.EaseType = ttEaseOutExpo
    Options.Animation.MovementAnimations.TabDelete.AnimationTimeMS = 500
    Options.Animation.MovementAnimations.TabMove.UseDefaultEaseType = False
    Options.Animation.MovementAnimations.TabMove.UseDefaultAnimationTime = False
    Options.Animation.MovementAnimations.TabMove.EaseType = ttEaseOutExpo
    Options.Animation.MovementAnimations.TabMove.AnimationTimeMS = 500
    Options.Behaviour.BackgroundDblClickMaximiseRestoreForm = True
    Options.Behaviour.BackgroundDragMovesForm = True
    Options.Behaviour.TabSmartDeleteResizing = True
    Options.Behaviour.TabSmartDeleteResizeCancelDelay = 700
    Options.Behaviour.UseBuiltInPopupMenu = True
    Options.Behaviour.TabRightClickSelect = True
    Options.Behaviour.ActivateNewTab = True
    Options.Behaviour.DebugMode = False
    Options.Behaviour.IgnoreDoubleClicksWhileAnimatingMovement = True
    Options.Scrolling.Enabled = True
    Options.Scrolling.ScrollButtons = csbLeftAndRight
    Options.Scrolling.ScrollStep = 20
    Options.Scrolling.ScrollRepeatDelay = 20
    Options.Scrolling.AutoHideButtons = True
    Options.Scrolling.DragScroll = True
    Options.Scrolling.DragScrollOffset = 50
    Options.Scrolling.MouseWheelScroll = True
    Tabs = <
      item
        Caption = 'This is the first tab 1'
        Active = False
        Tag = 0
        ImageIndex = 3
        ImageIndexOverlay = -1
        Pinned = False
        Visible = True
        Modified = False
        SpinnerState = tssNone
        HideCloseButton = False
      end
      item
        Caption = 'Longer tab 2'
        Active = False
        Tag = 0
        ImageIndex = 2
        ImageIndexOverlay = 24
        Pinned = False
        Visible = True
        Modified = False
        SpinnerState = tssNone
        HideCloseButton = False
      end
      item
        Caption = 'Very long tab 3'
        Active = False
        Tag = 0
        ImageIndex = 4
        ImageIndexOverlay = 25
        Pinned = False
        Visible = True
        Modified = False
        SpinnerState = tssNone
        HideCloseButton = False
      end
      item
        Caption = 'Tab 4'
        Active = False
        Tag = 0
        ImageIndex = -1
        ImageIndexOverlay = -1
        Pinned = False
        Visible = True
        Modified = False
        SpinnerState = tssNone
        HideCloseButton = False
      end
      item
        Caption = 'This is the last tab 5'
        Active = True
        Tag = 0
        ImageIndex = -1
        ImageIndexOverlay = -1
        Pinned = False
        Visible = True
        Modified = False
        SpinnerState = tssNone
        HideCloseButton = False
      end>
  end
bogdanpolak commented 5 years ago

Too long and too complicated issue. Needs to be splitted into 3 requests with simple steps which producing error

bogdanpolak commented 5 years ago

Code which testing bug (1) of above requests.

The width of the tabs isn’t initialized correctly if the close button is visible and TabWidthFromContent is set to True. The initial width ignores the close button area, so the text is cut off. After launching the program, one has to move the cursor over the component, then move it out again, then the component fixes all tab widths automatically.

procedure TForm1.EventSetTabWidth(Sender: TObject;
  ATabControl: ChromeTabsControls.TChromeTabControl; var TabWidth: Integer);
begin
  TestTabWidth := TabWidth;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  if Assigned(TestChromeTabs) then
    TestChromeTabs.Free;
  TestChromeTabs := TChromeTabs.Create(self);
  TestChromeTabs.OnSetTabWidth := EventSetTabWidth;
  TestChromeTabs.Parent := self;
  TestChromeTabs.Left := 8;
  TestChromeTabs.Top := 102;
  TestChromeTabs.Width := 350;
  TestChromeTabs.Options.Display.Tabs.TabWidthFromContent := True;
  TestChromeTabs.Tabs.Add.Caption := '1 Tab 1';
  TestChromeTabs.Tabs.Add.Caption := '2 Longer tab caption 2';
  TestChromeTabs.Tabs.Add.Caption := '3 Tab 3';
  (Sender as TButton).Caption := Format('Expected: %d,  Actual: %d',
    [79, TestTabWidth]);
end;

I'm going to verify this. Check two other cases and register three separate issues. Then we can close this multi-issue. Any comments?

bogdanpolak commented 5 years ago

Registered issue #70 with problem described in the point 1:

  1. The width of the tabs isn’t initialized correctly if the close button is visible and TabWidthFromContent is set to True. The initial width ignores the close button area, so the text is cut off. After launching the program, one has to move the cursor over the component, then move it out again, then the component fixes all tab widths automatically.
bogdanpolak commented 5 years ago

Can't reproduce: point 2.

  1. AutoHideButtons = True causes the scroll buttons to initialize as a tiny area in the top left if there are initially enough tabs to make the scroll buttons visible from the beginning. Moving the cursor over the component and out again fixes their position, but not their state. One has to click the left scroll button to make it disabled (as it should be because you can’t scroll further left).

When I paste provided TChromeTab component then tab are displayed incorrectly, but can produce similar scenarios for code.