Platforms to show: All Mac Windows Linux Cross-Platform
/MacBase/Custom NSWindows/NSWindow like AppStore/AppStore NSWindow
Required plugins for this example: MBS MacControls Plugin, MBS MacBase Plugin, MBS MacCocoa Plugin, MBS MacOSX Plugin, MBS Main Plugin
You find this example project in your Plugins Download as a Xojo project file within the examples folder: /MacBase/Custom NSWindows/NSWindow like AppStore/AppStore NSWindow
This example is the version from Sat, 23th Mar 2012.
Project "AppStore NSWindow.xojo_binary_project"
Class App Inherits Application
Const kEditClear = "Effacer"
Const kFileQuit = "Quitter"
Const kFileQuitShortcut = ""
End Class
Class Window1 Inherits CustomToolbarWindow
End Class
MenuBar MenuBar1
MenuItem FileMenu = "&Fichier"
MenuItem FileQuit = "#App.kFileQuit"
MenuItem EditMenu = "Edition"
MenuItem EditUndo = "Annuler"
MenuItem UntitledMenu1 = "-"
MenuItem EditCut = "Couper"
MenuItem EditCopy = "&Copier"
MenuItem EditPaste = "Coller"
MenuItem EditClear = "#App.kEditClear"
MenuItem UntitledMenu0 = "-"
MenuItem EditSelectAll = "Tout Sélectionner"
End MenuBar
Class CustomToolbarWindow Inherits Window
Event Activate()
End Event
Event ContentsChanged()
End Event
Event Deactivate()
End Event
Event MouseDown(X As Integer, Y As Integer) As Boolean
End Event
Event MouseDrag(X As Integer, Y As Integer)
End Event
Event MouseUp()
End Event
Event Open()
End Event
Event Paint(g As Graphics)
End Event
EventHandler Sub Activate()
Active=True
Activate() // Event
End EventHandler
EventHandler Sub ContentsChanged()
if winBt<>Nil then
winBt.Dirty=Self.ContentsChanged
winBt.needsDisplay=True
end if
ContentsChanged() // Event
End EventHandler
EventHandler Sub Deactivate()
Active=False
Deactivate() // Event
End EventHandler
EventHandler Function MouseDown(X As Integer, Y As Integer) As Boolean
// we take care of the window buttons
// as they are not in the titlebar area.
if x>13 and x<67 and y<18 then
Return False
// Moves the window
elseif y>=0 and y<=22 then
movePoint=New NSPointMBS
clickDX=X
clickDY=Self.Height-Y
ScreenHeight=Screen(0).Height
MoveAreaClicked=True
Return True
end if
Return MouseDown( X,Y ) // Event
End EventHandler
EventHandler Sub MouseDrag(X As Integer, Y As Integer)
// Moves the window
if MoveAreaClicked then
movePoint.X=system.MouseX-clickDX
movePoint.Y=ScreenHeight-system.MouseY-clickDY
Self.NSWindowMBS.setFrameOrigin( movePoint )
end if
MouseDrag( X,Y ) // Event
End EventHandler
EventHandler Sub MouseUp(X As Integer, Y As Integer)
MoveAreaClicked=False
MouseUp() // Event
End EventHandler
EventHandler Sub Open()
//——————————
// The current Window
//——————————
// Must be a metal window (Frame=9)
dim w As NSWindowMBS=Self.NSWindowMBS
w.setAutorecalculatesContentBorderThickness( False, NSWindowMBS.NSMaxYEdge )
w.setContentBorderThickness( 22, NSWindowMBS.NSMaxYEdge )
w.acceptsMouseMovedEvents=True
// Current window's frame
dim themeFrame As NSViewMBS = w.contentView.superview
dim h As Integer=themeFrame.frameHeight
//————————————
// Custom window buttons
//————————————
winBt=New CocoaWindowButtons( 13,h-32, Self, StandardWindowButtonsImage )
themeFrame.addSubview( winBt, NSWindowMBS.NSWindowBelow, Nil )
//——————————
// Navigation buttons
//——————————
NavButtons=New NavSegmentedControl( 76,h-36,65,24 )
NavButtons.segmentCount=2
NavButtons.imageForSegment(0)=New NSImageMBS( nav_arrow_left )
NavButtons.imageForSegment(1)=New NSImageMBS( nav_arrow_right )
NavButtons.widthForSegment(0)=0
NavButtons.widthForSegment(1)=0
NavButtons.tagForSegment(0)=0
NavButtons.tagForSegment(1)=1
NavButtons.segmentStyle=NSSegmentedControlMBS.NSSegmentStyleRoundRect
NavButtons.autoresizingMask=NSViewMBS.NSViewMinYMargin
NavButtons.trackingMode=NavButtons.NSSegmentSwitchTrackingMomentary
themeFrame.addSubview( NavButtons )
//——————————
// Toolbar SearchField
//——————————
SearchField=New NSSearchFieldMBS( Self.Width-158,h-34,150,22 )
SearchField.autoresizingMask=NSViewMBS.NSViewMinXMargin+NSViewMBS.NSViewMinYMargin
themeFrame.addSubview( SearchField )
Open() // Event
End EventHandler
EventHandler Sub Paint(g As Graphics)
// Draw the content background
g.ForeColor=&cEDEDED00
g.FillRect 0,22,g.Width,g.Height-22
// Top line
if Active then g.ForeColor=&c6D6D6D else g.ForeColor=&cA0A0A0
g.DrawLine 0,22,g.Width,22
Paint( g ) // Event
End EventHandler
Property Private Active As Boolean
Property Private MoveAreaClicked As Boolean
Property NavButtons As NavSegmentedControl
Property Private ScreenHeight As Integer
Property SearchField As NSSearchFieldMBS
Property Private clickDX As Integer
Property Private clickDY As Integer
Property Private movePoint As NSPointMBS
Property Private winBt As CocoaWindowButtons
End Class
Class CocoaWindowButtons Inherits CustomNSViewMBS
Const ButtonHorizontalPadding = 7
Const ButtonVerticalPadding = 20
Const btHeight = 16
Const btLeft = 2
Const btTop = 2
Const btTotalWidth = 54
Const btWidth = 14
EventHandler Sub DrawRect(g as NSGraphicsMBS, left as double, top as double, width as double, height as double)
g.saveGraphicsState
dim dx,dy As Integer
Active=window.isKeyWindow
if ButtonImage<>Nil then
if Dirty then dx=AppearenceDX+btWidth else dx=AppearenceDX
if Active and ButtonCloseEnabled then
if clicked=0 then
dy=btHeight*2
elseif hover=0 then
dy=btHeight*3
else
dy=btHeight*4
end if
elseif Not Active then
dy=0
else
dy=btHeight
end if
g.drawInRect ButtonImage, btLeft,btTop, btWidth,btHeight, dx,dy, btWidth,btHeight, NSGraphicsMBS.NSCompositeSourceAtop, 1.0
dx=AppearenceDX+(btWidth*2)
if Active and ButtonMiniaturizeEnabled then
if clicked=1 then
dy=btHeight*2
elseif hover=0 then
dy=btHeight*3
else
dy=btHeight*4
end if
elseif Not Active then
dy=0
else
dy=btHeight
end if
g.drawInRect ButtonImage, btLeft+20,btTop, btWidth,btHeight, dx,dy, btWidth,btHeight, NSGraphicsMBS.NSCompositeSourceAtop, 1.0
dx=AppearenceDX+(btWidth*3)
if Active and ButtonZoomEnabled then
if clicked=2 then
dy=btHeight*2
elseif hover=0 then
dy=btHeight*3
else
dy=btHeight*4
end if
elseif Not Active then
dy=0
else
dy=btHeight
end if
g.drawInRect ButtonImage, btLeft+40,btTop, btWidth,btHeight, dx,dy, btWidth,btHeight, NSGraphicsMBS.NSCompositeSourceAtop, 1.0
end if
g.restoreGraphicsState
End EventHandler
EventHandler Function acceptsFirstMouse(e as NSEventMBS) As boolean
Return True
End EventHandler
EventHandler Function acceptsFirstResponder() As boolean
Return True
End EventHandler
EventHandler Function canBecomeKeyView() As boolean
Return True
End EventHandler
EventHandler Function mouseDown(e as NSEventMBS, x as double, y as double) As boolean
if x>btLeft and x<btLeft+btWidth and y>btTop and y<btTop+btHeight then // Close button
clicked=0
elseif x>btLeft+20 and x<btLeft+btWidth+20 and y>btTop and y<btTop+btHeight then // Miniaturize button
clicked=1
elseif x>btLeft+40 and x<btLeft+btWidth+40 and y>btTop and y<btTop+btHeight then // Zoom button
clicked=2
end if
needsDisplay=True
Return True
End EventHandler
EventHandler Function mouseDragged(e as NSEventMBS, x as double, y as double) As boolean
// Cancels clic if the mouse goes out of the clicked button
if clicked=0 then
if X<btLeft or X>btLeft+btWidth or y<=btTop or y>=btTop+btHeight then // Close button
clicked=-1
needsDisplay=True
end if
elseif clicked=1 then
if X<btLeft+20 or X>btLeft+btWidth+20 or y<=btTop or y>=btTop+btHeight then // Miniaturize button
clicked=-1
needsDisplay=True
end if
elseif clicked=2 then
if X<btLeft+40 or X>btLeft+btWidth+40 or y<=btTop or y>=btTop+btHeight then // Zoom button
clicked=-1
needsDisplay=True
end if
end if
Return True
End EventHandler
EventHandler Function mouseMoved(e as NSEventMBS, x as double, y as double) As boolean
// mouse is over the window buttons
if x>btLeft and x<btTotalWidth and y>btTop and y<btTop+btHeight then
hover=0
needsDisplay=True
elseif hover<>-1 then
hover=-1
needsDisplay=True
end if
End EventHandler
EventHandler Function mouseUp(e as NSEventMBS, x as double, y as double) As boolean
if clicked<>-1 then
dim n As Integer=clicked
clicked=-1
needsDisplay=True
// Perform window action
Select case n
case 0
window.performClose
case 1
window.performMiniaturize
case 2
window.performZoom
End Select
Return True
end if
End EventHandler
EventHandler Sub viewDidMoveToWindow()
if window<>Nil then
// Hide current window buttons
dim bt As NSButtonMBS
bt=window.standardWindowButton( NSWindowMBS.NSWindowCloseButton )
if bt<>Nil then bt.isHidden=True
bt=window.standardWindowButton( NSWindowMBS.NSWindowMiniaturizeButton )
if bt<>Nil then bt.isHidden=True
bt=window.standardWindowButton( NSWindowMBS.NSWindowZoomButton )
if bt<>Nil then bt.isHidden=True
// Important to get mouse events in this view at startup
window.initialFirstResponder = Self
end if
End EventHandler
Sub Constructor(left As double, top As double, w As Window, BtImage As Picture)
// Calling the overridden superclass constructor.
//———————————————————————
// Default left position: use the constant ButtonHorizontalPadding
// Default top position: do superview.frameheight - ButtonVerticalPadding
// The current view is 4 pixels bigger than the button size.
Super.Constructor( left-2,top-2, btTotalWidth+4, btHeight+4 )
autoresizingMask=NSViewMBS.NSViewMinYMargin+NSViewMBS.NSViewNotSizable
ButtonCloseEnabled=w.CloseButton
ButtonMiniaturizeEnabled=w.MinimizeButton
ButtonZoomEnabled=w.MaximizeButton
// Appearence theme and Pictures
dim s As String=CurrentAppearanceThemeMBS
if s="com.apple.theme.appearance.aqua.graphite" then AppearenceDX=56
if BtImage<>Nil then
ButtonImage=New NSImageMBS( BtImage )
end if
End Sub
Note "Thanks"
Thanks to David Della Rocca for providing this example.
Property Active As Boolean
Property Private AppearenceDX As Integer
Property ButtonCloseEnabled As Boolean = True
Property ButtonImage As NSImageMBS
Property ButtonMiniaturizeEnabled As Boolean = True
Property ButtonZoomEnabled As Boolean = True
Property Dirty As Boolean
Property Private clicked As Integer = -1
Property Private hover As Integer = -1
End Class
ExternalFile StandardWindowButtonsImage
End ExternalFile
Class NavSegmentedControl Inherits NSSegmentedControlMBS
EventHandler Sub Action()
Select case Self.selectedTag
case 0 // Left
case 1// Right
end select
End EventHandler
End Class
ExternalFile nav_arrow_left
End ExternalFile
ExternalFile nav_arrow_right
End ExternalFile
End Project
See also:
The items on this page are in the following plugins: MBS MacBase Plugin.