I've just finished TChromeTabs V1.3. You can get it here: http://code.google.com/p/delphi-chrome-tabs/downloads. There are a ton of bug fixes and some really nice new features including:

I've just finished TChromeTabs V1.3. You can get it here: http://code.google.com/p/delphi-chrome-tabs/downloads. There are a ton of bug fixes and some really nice new features including:

- Tab spinners - You can render them like Chrome does or use an ImageList.
- Variable size tabs - Tabs are resized depending on the caption.
- Title bar tabs - Display TChromeTabs in the Aero title bar.

With this update I believe that TChromeTabs completely recreates the Google Chrome tab experience (plus a lot more). Please tell me if you think anything is missing.

If you have any bug reports or feature requests, let me know soon as possible as the time I have to work on TChromeTabs is almost over.

Cheers,
Paul
http://code.google.com/p/delphi-chrome-tabs/downloads/list?saved=1&ts=1357570270

Comments

  1. Hey Paul, awesome! I mean, both TChromeTabs and you :)

    ReplyDelete
  2. Hi Paul,
    One bug report - I checked out the latest source, opened the demo project (with some 'missing properties' error messages), compiled it, run it, and find that the 'upload-image' and 'download-image' spinners do not appear. BTW, I didn't know it has built-in animated spinners, so great!

    And questions about pinned tabs - is it possible to pin to the right side? Is it possible to also show captions for pinned tabs?

    ReplyDelete
  3. Edwin Yip - Thanks :)

    The missing properties are due to a couple of 'breaking' changes I had to make. I shouldn't make any difference to tabs.

    Strange that the spinners don't work. Needless to say, they work on my machine. Do they work in the compiled demo in the download zip? Which version of Delphi are you using?

    You can pin tabs to the right if you change the BiDi mode. This also makes all tabs align to the right though. Is this what you mean?

    I think the idea of having pinned tabs is that they take up very little space i.e. no text, only an image. I'm sure you could do it manually though. I'll have a think about it and get back to you.

    ReplyDelete
  4. I'm impressed by the work you've done!
    Even if I still encounter some bugs and Access Violations while playing with tabs (using your demo or my testing app).
    Example for strange graphical behavior (top and bottom):
    http://img713.imageshack.us/img713/6141/07012013175827.png

    ReplyDelete
  5. Sébastien Paradis - I've not experienced AV's for many revisions and I've never seen any tab corruption that come close to your screenshot. Can you provide me with more details such as Delphi version and, more importantly, the steps required to reproduce the problems.

    BTW, these could be issues to do with the Delphi version. I design and test in XE2. I only really check that it compiles in Delphi 7.

    ReplyDelete
  6. Good job, I think this version is ready for production

    ReplyDelete
  7. Alex Egorov - I think it's close. My idea is to just work on fixes for a while and then release a production ready V2.0.

    There are a couple of things I still need to look at. One is an issue with catching a theme change and moving the tabs out of the title bar if Aero is no longer supported. I'd also like to figure out what the two issues reported in this thread are.

    ReplyDelete
  8. Paul Thornton Checked the compiled demo, all the spinners work, maybe that has something to do with the compilation by D2010, since I also saw AV's as Sebastien reported, but they are gone in the compiled demo.

    I'm not sure what Chrome's pined tabs are intended for, but I think left-pining and right-pinning tabs in your TChromeTabs can be useful for special tabs, for example, a 'Configuration' tab which always appear at a fixed position.

    PS, with the compiled demo I just discovered that TChromeTabs supports inter-window drag and drop, but not sure if it works out-of-the-box in a inter-process scenario.

    ReplyDelete
  9. Edwin Yip - I'd really like to get the AV's fixed, I don't have D2010. Can you try to narrow down the problem? When does it happen? Is it consistently repeatable etc. Do you have MadExcept or EurekaLog? A stacktrace would probably help me a lot.

    Pinned tabs are great in Chrome. They allow you quick access to your most used web pages and take up very little space Also, they're always in the same place and can't be closed by accident.

    You can add the right pinned tabs to the Google Code issue tracker (Request for Enhancement). I can't promise anything though as I reckon it will be a lot of work and I don't really have the need for it myself. Feel free to implement it yourself and I'll gladly merge it. I'm also happy to give you any help you need.

    The inter window drag drop only works within the same application. If you want to drag/drop between processes you will need to come up with your own solution. I don't need it and I have a feeling it's going to be pretty tricky.

    ReplyDelete
  10. Paul Thornton I've got Eurekalog, and I tried just now but I couldn't reproduce the AV again. I'll update you when I've got new details.

    Re right pinned tabs, well, It's just an idea came to my mind and I thought I'd post it,  I don't actually need it at this moment, so do inter-app dragging, but if I need it and implemented I'll contribute it to the svn repos.

    ReplyDelete
  11. Yes these bugs could come from my compilation, as I installed all TChromeTabs versions since 0.9 by overwriting files in the same folder. I use D2007.
    "the steps required to reproduce the problems" : if I knew I would already have told you :) I mostly played with see-through, tab width depending on caption, min/max width, overlap (including negative), pinned or not and that's all.
    Less problems with pre-compiled demos but still few ones, for example bottom tabs pinned with a negative ovelap:
    http://img17.imageshack.us/img17/3822/08012013144241.png
    (Note: this is demo provided with 1.1 or 1.2, in the last one I don't have any tabs at the top!)

    ReplyDelete
  12. Possible bug: double click on the window title over tabs - demo app closeы, but should be maximized.

    For the top tabs inactive tabs have blurred font, and it becomes normal after mouse over this tab. How I can disable this?

    ReplyDelete
  13. Alex Egorov 
    >Possible bug: double click on the window title over tabs - > >demo app closes, but should be maximized.

    I can't repeat this. Are you using the compiled app or compiling it yourself? Any other info you can give me?

    > Blurred font
    The blurred font is a pain in the a**. It's what happens when you draw text over a bitmap that has an alpha < 255. I have no idea how Chrome does it. I've searched everywhere and asked a question on SO (http://stackoverflow.com/questions/11307509/drawing-text-on-glass-background-becomes-blurred-as-alpha-is-lowered). None of the answers took into account the different background alpha values.

    If anyone can figure out how to fix this I will be eternally grateful :)

    ReplyDelete
  14. Sébastien Paradis - I'm not sure the negative overlap display is a bug. I purposefully left many property checks fairly loose as it allows you to play with the display a little. For example, setting a negative tab overlap allows you to have spaces between the tabs. Increasing the pinned tab size will prevent what you're seeing in the image you posted.

    ReplyDelete
  15. I'm using compiled demo, don't know how can describe you this bug - window closes after double click on the title...
    Found some: after start - can't move window using small window title over tabs, and double click closes window
    But can move window using window title on the right side after tabs, and maximizing by double click on this area is works.
    And also anfter this manipulations with right side area small title area over tabs start to work correctly

    About blured font on inactive tabs - for bottom tabs all looks fine, but yes, this tabs without alpha

    ReplyDelete
  16. Hm.. I'm provide not correct description, area over tabs not begins to work, works only several pixels over tabs and all other area not work

    ReplyDelete
  17. Another small and not critical issue with add tab button:
    when tabs not resized Floating Horz Offset works fine and as expected, but after reducing the size of window this Offset increased on some value when tabs begin to resizing

    ReplyDelete
  18. Alex Egorov - which version of Windows are you using? Is Aero enabled? Do you change any settings after starting the demo?

    ReplyDelete
  19. Windows 7 32 bit with Aero, nothing changed after starting

    ReplyDelete
  20. Alex Egorov - I think I fixed the misplaced add button in an update earlier today. At least I can't repeat it with this version and I can with the previous one.

    I'm on Win7 64bit. I doubt that would affect anything.

    Maybe you can debug the app and see what's happening when you double click the title bar. Maybe in ChromeTabs.pas - WMLButtonDblClk or of of the message handlers in ChromeTabsGlassForm.pas.

    Does it happen with "Behaviour -> Display the top tabs in the title bar non client" are both checked and unchecked?

    ReplyDelete
  21. This is netbook without delphi, can't debug, tomorrow will try on another computer with delphi, when unchecked "... tabs in the title bar non client" - all works fine

    ReplyDelete
  22. On Windows XP with themes option "Behaviour -> Display the top tabs in the title bar non client" does not work, when checked - no top tabs visible

    ReplyDelete
  23. Alex Egorov - Can you try the latest version from SVN? I made a lot of fixes today and sone of your issues sound like they're already fixed.

    ReplyDelete
  24. Paul, just discovered your ChromeTabs, thanks to Nick. Installed and running fine on Windows 8 x64, using XE3. Very impressed with the amount of settings/options.
    One thing I'm trying to do is eliminate the rounded corners on the tabs. I know this doesn't make them "chrome" tabs anymore, but I personally prefer the squared corners of something like the TTabSet with ModernPopout style. I've managed to get square corners using the OnGetControlPolygons event, and creating my own IChromeTabPolygons, but I'm having an issue getting the correct colors for the correct tab. Am I using the appropriate event to tackle this? Any other suggestions?

    ReplyDelete
  25. Vic Adam - Hi Vic... Glad you like TChromeTabs :) You can set all the colour settings via the LookAndFeel property. Take a look under the Look and Feel tab in the demo then click on Tabs in the tree. You will see the colour properties for all the tab states; active, not active and hot.

    If you prefer, you can use the OnBeforeDrawItem to draw whatever you like on the canvas including bit maps.

    I'm actively trying to clean up any remaining issues before I release 2.0. Please let me know if you come across anything.

    I'd also suggest that you use the SVN version as I'm committing fixes everyday.

    ReplyDelete
  26. Hi Paul. Actually, my issue is in the OnGetControlPolygons event. I create the polygon, then use Polygons.AddPolyGon, but the 2nd (brush) and 3rd (pen) parameters are the issue. How do I get the actual brush and pen for the current tab being painted. If I use, for example: Polygons.AddPolygon(MyPolygon, ChromeTabs1.LookAndFeel.Tabs.Active.Style.GetBrush(ItemRect) , ChromeTabs1.LookAndFeel.Tabs.BaseLine.GetPen); then all tabs are painted the same color, not the active tab being white and the others faded. How can I detect which tab is being painted in this event? Or am I approaching this all wrong?
    Most of what I've figured out is from looking at your source, but here you use properties like: FChromeTabControlPropertyItems.CurrentTabProperties.StopColor which I can't access.

    ReplyDelete
  27. Vic Adam - do you want to paint each tab in a brush\pen that you set in an event? I'm not sure you can do this at the moment as all the brush and pen values come from the LookAndFeel. I'm happy to try to implement it though.

    Can you send me some sample code along with a few comments about exactly what you want to do?

    ReplyDelete
  28. Thanks Paul. I will put some code/comments together.

    My goal is simply to have your ChromeTabs exactly as they are, except with squared corners on the tabs, not slanted/rounded ones.

    ReplyDelete
  29. Vic Adam - Ah, I think I understand what you mean now. It's getting late here. I'll probably take a look in the morning.

    ReplyDelete
  30. Vic Adam - Hi again. I've just committed an update to SVN that makes a few changes to OnGetControlPolygons that allows you to do what (I think) you want to do.

    I've added some commented out code in the demo (in OnGetControlPolygons) to draw square tabs. It's very basic, but should get you started.

    ReplyDelete
  31. Perfect, that is exactly what I was looking for! Never thought to use nil for the brush/pen though. Thanks for your help, and keep up the quality work.

    ReplyDelete
  32. Hi Paul, you are constantly doing a great job! Just an update - the last time I reported the download/upload spinners didn't display, it's OK now after I checked out the latest svn and re-built the packages. The problem should have been on my side, sorry...

    PS I remember you said somewhere you'll change TChromeTabs to not occupy the tabs (when the window is maximized) if Areo effect is not available, I think it's not a good idea, since it's all about utilizing the screen estate, whether or not Areo effect is available or not. Just my 2 cents.

    ReplyDelete
  33. Edwin Yip - Hi Edwin. I totally agree about keeping the tabs in the title bar even when Aero is not active. Unfortunately, I don't think it's easily achieved.

    When Aero is active, all you need to do is make the tab background transparent, then find a way of inserting the tabs into the title bar area. This does involve rebuilding the title bar, but it's not a big deal.

    When Aero is not active, I don't think we can use the same technique. I've tried and the whole title bar looks messed up. I think the way Chrome does it is to manually repaint the entire non client area of the form. If you take a look at the Chrome source code you will see a lot of images that look like they're used to do precisely this.

    I'll keep thinking about it and will implement it if I figure it out.

    Of course it would be great if somebody else know how to do it :)

    ReplyDelete
  34. Hi Paul! Tnx for component!

    In version 1.3 i found some changes in "Activate new tab" algorithm.
    Even if ActivateNewTab property set to False, after create (manually or by pressed New Tab Button) first tab, component change focus to this tab.
    In older version a new tab has not received the focus, as well as the following ones.

    I understand why it was done - the state of the component with a lot of existing tabs but without active - is unacceptable.

    But I just keep a reference to the object (content of the tab) in the Data property :) After creating a new tab, I have no chance to initialize this property, immediately triggered OnChangeActiveTab.

    Of couse i can use some like IgnoreNewTabActivatingNotify: Boolean; :)
    But i fink this is not so nice.

    sorry for my english.

    ReplyDelete
  35. Anton Aksenov - Hi Anton. The correct place to perform an action on a new tab is in the OnChange event. Simply check that TabChangeType = tcAdded. You can use the same event to clean up any objects connected to your tab (TabChangeType = tcDeleting). Was that what you needed?

    ReplyDelete
  36. Paul, First I want to say that I do not see a serious problem in this situation) I just want to talk about it.

    It seems not quite right to put the business logic in an event handler interface.

    I have a method LoadRoutine:
    begin
      ET: = TEditTab.Create (SomeParam1, SomeParam2,... nevermind);
      CT: = ChromeTab1.Tabs.Add;
      CT.Data: = ET;
      ET.Tab: = CT;
       // Do some with ET - content object in tab
      // ET - is a business logic object. He make reflection any changes to the ChromeTab: caption, icon, readonly state, modify, etc.

      if flActivateTab then
        ChromeTab1.ActiveTab: = CT;
    end;

    I call this method from the Ctrl O, at the start of the program, when you click the mouse from the "last open", etc.

    For v1.3 i just declare a variable in the object form, FCreatedEditTab: TEditTab, and changed the code like this:

    LoadRoutine:
    begin
      ET := TEditTab.Create(SomeParam1, SomeParam2, nevermind);
      FCreatedEditTab := ET;
      CT := ChromeTab1.Tabs.Add;
      if ChromeTab1.Tabs.Count > 1 then
        CT.Data := ET;
      ET.Tab: = CT; 
      ......

    procedure TMainForm. ChromeTab1Change(Sender: TObject; ATab: TChromeTab; TabChangeType: TTabChangeType);
    begin
      if TabChangeType = tcAdded then
        ATab.Data: = FCreatedEditTab;
    ......

    As a result I moved part of the business logic of the method LoadRoutine to the event interface TChromeTab.OnChange.

    ReplyDelete
  37. Anton Aksenov - Thianks for your comments. I am always happy to hear peoples suggestions.

    Can you clarify? Would you like to pass the tab properties to the constructor? If this is the case I see two issues:

    1) The TCollection constructor is also called at design time. I'm not sure it's good practice to add another just for run time.
    2) If I pass the data param in the constructor where do I stop? Do I include the caption, the image index, the overlay index etc. Do I include any new parameters if they are added in the future?

    If anybody wants to jump in with their opinions I would love to hear them.

    ReplyDelete
  38. As a joke, you can pass to the constructor of an anonymous method :)
    But seriously, IMHO this component is needed for content management. And the content - it's 'Data' property. Ie probably nothing to worry if your code will be a focus on content, such as:
    constructor  TChromeTab .Create(Collection: TCollection; Data: Pointer); overload;
    ...
    begin
      FData := Data;
      Create(Collection);
    end;

    I want to say, 'Data' - this is the content. A caption, icon, etc - this way of presenting the content. Ie two different things.

    ReplyDelete
  39. Paul, why in method procedure TChromeTabsList.Notify(Item: TCollectionItem; Action: TCollectionNotification);
    you don't call GetChromeTabInterface.DoOnChange(TChromeTab(Item), tcDeleted); for cnDeleting?
    If i call TChromeTab.Free for deleting the tab, TChromeTabs.OnChage is not evented.
    Now I use ChromeTabs.Tabs.DeleteTab (CT.Index) instead of calling the destructor.
    This is not a problem, just maybe you missed something.

    ReplyDelete
  40. Anton Aksenov - The whole TCollection/Notify code is not optimal and is on my list to be refactored. I just need to find a bit of time.

    ReplyDelete
  41. Paul Thornton , do you have compiled after 1.3 version for some tests? Don't have a time in the work days to compile, can test on weekend, but don't have delphi here :(

    ReplyDelete
  42. Alex Egorov - I probably won't be adding a zip package to Google Code until I release 2.0. However, I've uploaded the compiled demo for you to play with. You can find it here: http://download.easy-ip.net/delphi/ChromeTabsDemoXE2_2_0_BETA.zip

    ReplyDelete
  43. Paul Thornton Is there a way to only show the tabs in the title when the form is maximized?

    ReplyDelete
  44. Frédéric Hannes - you could alter the source code. However, I'll try to make an update later today that makes it easy.

    ReplyDelete

Post a Comment