Custom title bar with buttons etc...

Hi everybody

Today, I’m looking for a way to custom my title bar, just like the Mail application that uses buttons and a search bar, in the title bar.

I found nothing in Xojo to do something like this.

Any idea?

Here is a way for a CARBON app… maybe someone can come up with a COCOA equiv

This gives a unified area , then just position you buttons so this area encompasses them

SUB SetRoundWIndowTop(w as window, top as integer, bottom as integer)
  
  #If TargetCarbon Then
    If System.IsFunctionAvailable("HIWindowSetContentBorderThickness","Carbon") Then
      Soft Declare Function HIWindowSetContentBorderThickness Lib "Carbon" (w As WindowPtr, inBorderThickness As Ptr) As Integer
      Soft Declare Function ChangeWindowAttributes Lib "Carbon" (w As WindowPtr, setAttributes As Integer, clearAttributes As Integer) As Integer
      
      Const kHIWindowBitRoundBottomBarCorners=13
      
      Dim OSError As Integer
      Dim BorderThickness As New MemoryBlock(16)
      
      BorderThickness.SingleValue(0)=top //Top
      BorderThickness.SingleValue(4)=0 //Must Be Zero
      BorderThickness.SingleValue(8)=bottom //Bottom
      BorderThickness.SingleValue(12)=0 //Must Be Zero
      
      OSError=HIWindowSetContentBorderThickness(w,BorderThickness)
      OSError=ChangeWindowAttributes(w,Bitwise.ShiftLeft(1,(kHIWindowBitRoundBottomBarCorners-1)),0)
    End If
  #EndIf
  
END SUB

[quote=158062:@SbastienAngot]Hi everybody

Today, I’m looking for a way to custom my title bar, just like the Mail application that uses buttons and a search bar, in the title bar.

I found nothing in Xojo to do something like this.

Any idea?[/quote]

I got this from a Will Shank post in https://forum.xojo.com/10914-black-windows

Put this in the Open event of the window

[code] declare function contentView lib “Cocoa” selector “contentView” (id As integer) As Ptr
declare function superView lib “Cocoa” selector “superview” (id As Ptr) As Ptr
declare function subviews lib “Cocoa” selector “subviews” (id As Ptr) As Ptr
declare function objAtIdx lib “Cocoa” selector “objectAtIndex:” (id As Ptr, idx As UInt32) As Ptr
declare sub addSubView lib “Cocoa” selector “addSubview:positioned:relativeTo:” _
(id As Ptr, aView As integer, order As integer, rel As Ptr)

dim cv As Ptr = contentView(self.Handle)
dim themeFrame As Ptr = superView(cv)
dim firstSubView As Ptr = objAtIdx(subViews(themeFrame), 0)
addSubView(themeFrame, Slider1.Handle, 0, firstSubView)
addSubView(themeFrame, PushButton1.Handle, 0, firstSubView)[/code]

In this example, I placed Slider1 and PushButton1 on the titlebar in the IDE. The last two lines make them show.

For the NSSearchField, see https://forum.xojo.com/13244-nssearchfield

Workaround: Use MBS Plugins.
There is a nice example project ‘Toolbar buttons.rbp’ which comes with Christian’s plugins

Link:
http://www.monkeybreadsoftware.net/example-cocoa-toolbarbuttons-toolbarbuttons.shtml

Ages ago we did a request on this matter:
<https://xojo.com/issue/18112>

I used the MBS plugins, based on the above example, this way (here on Yosemite):

You can move any control with a valid Handle to the toolbar by using setView: on a NSToolbarItem:

[code]Declare Function objectAtIndex Lib “Cocoa” Selector “objectAtIndex:” (NSArray As Ptr, idx As UInt32) As Ptr
Declare Function toolbar Lib “Cocoa” Selector “toolbar” (NSWindow As Ptr) As Ptr
Declare Function items Lib “Cocoa” Selector “items” (NSToolbar As Ptr) As Ptr
Declare Sub setView Lib “Cocoa” Selector “setView:” (NSToolbarItem As Ptr, NSView As Ptr)
Declare Sub setMinSize Lib “Cocoa” Selector “setMinSize:” (NSToolbarItem As Ptr, minSize As NSSize)
Declare Sub setMaxSize Lib “Cocoa” Selector “setMaxSize:” (NSToolbarItem As Ptr, maxSize As NSSize)

Dim toolbarPtr As Ptr = toolbar(Ptr(Handle))
Dim itemsPtr As Ptr = items(toolbarPtr)
Dim toolbarItemPtr As Ptr = objectAtIndex(itemsPtr, 0)
setView(toolbarItemPtr, Ptr(ComboBox1.Handle))

Dim minSize As NSSize
minSize.width = ComboBox1.Width
minSize.height = ComboBox1.Height

Dim maxSize As NSSize
maxSize.width = ComboBox1.Width
maxSize.height = ComboBox1.Height

setMinSize(toolbarItemPtr, minSize)
setMaxSize(toolbarItemPtr, maxSize)[/code]

This does not work.

NSSize : can’t find a type by that name.

NSSize is a structure with to fields:
width As Single
height As Single

Thanks Eli, works fine

Toolbar Example

[quote=158166:@Axel Schneider]Thanks Eli, works fine

Toolbar Example[/quote]

Thanks for the example Axel, this will help me a lot

That’s the official way to do it!

We used to (App Wrapper still does) move the controls into the Window title, I recently discovered that Apple are going to prevent this in a future release.

[quote=158080:@Michel Bujardet]I got this from a Will Shank post in https://forum.xojo.com/10914-black-windows

Put this in the Open event of the window

declare function contentView lib “Cocoa” selector “contentView” (id As integer) As Ptr
declare function superView lib “Cocoa” selector “superview” (id As Ptr) As Ptr
declare function subviews lib “Cocoa” selector “subviews” (id As Ptr) As Ptr
declare function objAtIdx lib “Cocoa” selector “objectAtIndex:” (id As Ptr, idx As UInt32) As Ptr
declare sub addSubView lib “Cocoa” selector “addSubview:positioned:relativeTo:” _
(id As Ptr, aView As integer, order As integer, rel As Ptr)

dim cv As Ptr = contentView(self.Handle)
dim themeFrame As Ptr = superView(cv)
dim firstSubView As Ptr = objAtIdx(subViews(themeFrame), 0)
addSubView(themeFrame, Slider1.Handle, 0, firstSubView)
addSubView(themeFrame, PushButton1.Handle, 0, firstSubView)
In this example, I placed Slider1 and PushButton1 on the titlebar in the IDE. The last two lines make them show.[/quote]
This is the way that Apple will block in the future, so in your next update you may want to switch to the toolbar method.

With Yosemite, you can now ‘hide’ the titlebar, move the content into the ‘titlebar’ area and draw your completely own custom titlebar (just be warned that moving the content up has detrimental effects on labels and CGLayers at the moment). The OS will continue to draw the window widgets for you (which is a relief).

[quote=158243:@Sam Rowlands]This is the way that Apple will block in the future, so in your next update you may want to switch to the toolbar method.

[/quote]

I had tried that, but do not have any app using it. If I need it, I will use the method Axel posted, then.

[quote=158091:@Eli Ott]You can move any control with a valid Handle to the toolbar by using setView: on a NSToolbarItem:

[code]Declare Function objectAtIndex Lib “Cocoa” Selector “objectAtIndex:” (NSArray As Ptr, idx As UInt32) As Ptr
Declare Function toolbar Lib “Cocoa” Selector “toolbar” (NSWindow As Ptr) As Ptr
Declare Function items Lib “Cocoa” Selector “items” (NSToolbar As Ptr) As Ptr
Declare Sub setView Lib “Cocoa” Selector “setView:” (NSToolbarItem As Ptr, NSView As Ptr)
Declare Sub setMinSize Lib “Cocoa” Selector “setMinSize:” (NSToolbarItem As Ptr, minSize As NSSize)
Declare Sub setMaxSize Lib “Cocoa” Selector “setMaxSize:” (NSToolbarItem As Ptr, maxSize As NSSize)

Dim toolbarPtr As Ptr = toolbar(Ptr(Handle))
Dim itemsPtr As Ptr = items(toolbarPtr)
Dim toolbarItemPtr As Ptr = objectAtIndex(itemsPtr, 0)
setView(toolbarItemPtr, Ptr(ComboBox1.Handle))

Dim minSize As NSSize
minSize.width = ComboBox1.Width
minSize.height = ComboBox1.Height

Dim maxSize As NSSize
maxSize.width = ComboBox1.Width
maxSize.height = ComboBox1.Height

setMinSize(toolbarItemPtr, minSize)
setMaxSize(toolbarItemPtr, maxSize)[/code][/quote]
It works pretty fine for me, thanks @Eli Ott !

The only issue I get is with BevelButtons now… I want custom buttons with a backdrop, but the «Action» event of bevelButtons is never triggered. If I use a PushButton, it’s ok, but not with bevelButtons… I’m getting crazy!

Any idea? Otherwise, I will use canvas, but if I can use real buttons it is a better way.

Ok, I found a solution, I can use the MouseDown function instead, it works :slight_smile:

[quote=160486:@SbastienAngot]
The only issue I get is with BevelButtons now… I want custom buttons with a backdrop, but the Action event of bevelButtons is never triggered. If I use a PushButton, it’s ok, but not with bevelButtons… I’m getting crazy!

Any idea? Otherwise, I will use canvas, but if I can use real buttons it is a better way.[/quote]

You can use a PushButton with Icon.

PushButton with Icon

I use SegmentedControls.

Xojo’s Bevel Button is not a native control, it’s a custom control that Xojo made.

I’ve found that these work the best when used on a toolbar, they also align perfectly (along the v axis) where as different controls don’t.

For some reason, I can’t unZip Axel’s example.
Is there a way to use an existing toolbar. And add my own controls to it?

I cannot unzip Axel’s example either.

Its not a zip file.
rename it to have a.html extension and double click
Takes you to a download page where the real zip file lives.
Go figure…