Borderless mini icon

Mac OSX specific forum
User avatar
rndrei
Enthusiast
Enthusiast
Posts: 203
Joined: Thu Dec 28, 2023 9:04 pm

Borderless mini icon

Post by rndrei »

How to make small buttons on the window title?
You can create a window with the #PB_Window_BorderLess parameter and draw your own buttons!
But maybe we can somehow through Cocoa?
User avatar
Shardik
Addict
Addict
Posts: 2074
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Borderless mini icon

Post by Shardik »

You can even place small buttons into the title bar. 11 years ago I already posted these two examples. And here is another until now unpublished example from 5 years ago which places a circular help button at the right side of the title bar. Both examples were just succussfully tested on MacOS 15.7.1 'Sequoia' (with Intel processor).

Code: Select all

EnableExplicit

#NSCircularBezelStyle = 7

Define FrameView.I
Define TitlebarButton.I
Define TitlebarButtonFrame.NSRect

OpenWindow(0, 270, 100, 370, 100, "Window with button in titlebar")
TitlebarButton = ButtonGadget(#PB_Any, WindowWidth(0) - 28,
  WindowHeight(0) + 4, 21, 21, "?")
CocoaMessage(@TitlebarButtonFrame, GadgetID(TitlebarButton), "frame")
CocoaMessage(0, GadgetID(TitlebarButton),
  "setBezelStyle:", #NSCircularBezelStyle)
FrameView = CocoaMessage(0, CocoaMessage(0, WindowID(0), "contentView"),
  "superview")
CocoaMessage(0, FrameView, "addSubview:", GadgetID(TitlebarButton))

Repeat
  Select  WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Gadget
      If EventGadget() = TitlebarButton
        Debug "Left click onto titlebar help button"
      EndIf
  EndSelect
ForEver
Last edited by Shardik on Sat Nov 15, 2025 12:03 pm, edited 1 time in total.
Collection of cross-platform examples with API functions to extend PureBasic
User avatar
rndrei
Enthusiast
Enthusiast
Posts: 203
Joined: Thu Dec 28, 2023 9:04 pm

Re: Borderless mini icon

Post by rndrei »

The link is broken!
User avatar
Shardik
Addict
Addict
Posts: 2074
Joined: Thu Apr 21, 2005 2:38 pm
Location: Germany

Re: Borderless mini icon

Post by Shardik »

rndrei wrote: The link is broken!
Sorry, I had forgotten to insert the URL into the link. I have repaired the link now.
Collection of cross-platform examples with API functions to extend PureBasic
User avatar
rndrei
Enthusiast
Enthusiast
Posts: 203
Joined: Thu Dec 28, 2023 9:04 pm

Re: Borderless mini icon

Post by rndrei »

Fine! Thank's!
User avatar
mk-soft
Always Here
Always Here
Posts: 6388
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Borderless mini icon

Post by mk-soft »

You can move the ToolBar to the TitleBar on macOS.

Link: ToolBarStandardButton
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
rndrei
Enthusiast
Enthusiast
Posts: 203
Joined: Thu Dec 28, 2023 9:04 pm

Re: Borderless mini icon

Post by rndrei »

And how to remove the standard buttons from the window to close to minimize to maximize, but to save the parameter #PB_Window_SizeGadget ???
User avatar
mk-soft
Always Here
Always Here
Posts: 6388
Joined: Fri May 12, 2006 6:51 pm
Location: Germany

Re: Borderless mini icon

Post by mk-soft »

With helper Dump Methods

Code: Select all

;-TOP Dump Object Methods

; by mk-soft, 29.12.2019 - 06.10.2023, v1.09.1

Declare.s DumpObjectMethods(*Object, SuperLevel = 0, HidePrivate = #True, ShowEncoding = #False, FirstArgument = 2)

Structure ArrayOfMethods
  i.i[0]
EndStructure

ImportC ""
  class_copyMethodList(*Class, *p_methodCount)
  ; -> An array of pointers of type Method describing
  ;    the instance methods implemented by the class
  ;    Any instance methods implemented by superclasses are Not included
  ;    You must free the array with free()
  class_getName(*Class) ; -> UnsafePointer<Int8> -> *string
  sel_getName(*Selector); -> const char *
  method_getName(*Method) ; -> Selector
  method_getTypeEncoding(*Method) ; -> const char *
  method_getReturnType(*Method, *dst, dst_len) ; -> void
  method_getNumberOfArguments(*Method)         ; -> unsigned int
  method_getArgumentType(*Method, index, *dst, dst_len) ; -> void
  
  NSGetSizeAndAlignment(*StringPtr, *p_size, *p_align) 
  ; -> const char *
  ;    Obtains the actual size and the aligned size of an encoded type.
EndImport

; ----

Procedure.s GetArgumentType(*String)
  Protected r1.s, arg.s, size.i, ofs.i
  
  arg = PeekS(*String, -1, #PB_UTF8)
  r1 + arg + " - "
  If Left(arg, 1) = "^"
    r1 + "A pointer to type of "
    arg = Mid(arg, 2)
  EndIf
  Select arg
    Case "c" : r1 + "A char "
    Case "i" : r1 + "An int "
    Case "s" : r1 + "A short "
    Case "l" : r1 + "A long "
    Case "q" : r1 + "A long long"
    Case "C" : r1 + "An unsigned char "
    Case "I" : r1 + "An unsigned int "
    Case "S" : r1 + "An unsigned short "
    Case "L" : r1 + "An unsigned long "
    Case "Q" : r1 + "An unsigned long long "
    Case "f" : r1 + "A float "
    Case "d" : r1 + "A double "
    Case "B" : r1 + "A C++ bool Or a C99 _Bool "
    Case "v" : r1 + "A void"
    Case "*" : r1 + "A character string (char *) "
    Case "@" : r1 + "An object (whether statically typed Or typed id) "
    Case "#" : r1 + "A class object (Class) "
    Case ":" : r1 + "A method selector (SEL) "
    Default:
      NSGetSizeAndAlignment(*String, @size, @ofs)
      r1 + "[" + Str(size) + " bytes]"
  EndSelect
  If Right(arg, 1) = "?"
    r1 + "An unknown type (e.g. function pointer)"
  EndIf
  ProcedureReturn r1
EndProcedure

; ----

Procedure.s DumpObjectMethods(*Object, SuperLevel = 0, HidePrivate = #True, ShowEncoding = #False, FirstArgument = 2)
  Protected result.s, r1.s, i, c, n, methodCount, Method.s
  Protected *Class, *SuperClass, *Method, *Methods.ArrayOfMethods
  Protected *String
  
  *Class = object_getclass_(*Object)
  If *Class
    *String = AllocateMemory(1024)
    r1 = PeekS(class_getName(*Class), -1, #PB_UTF8)
    If SuperLevel
      For i = 1 To SuperLevel
        *SuperClass = class_getsuperclass_(*Class)
        If *SuperClass
          *Class = *SuperClass
          r1 + " -> " + PeekS(class_getName(*Class), -1, #PB_UTF8)
        Else
          Break
        EndIf
      Next
    EndIf
    *Methods = class_copyMethodList(*Class, @methodCount)
    r1 + #LF$ + #LF$ + "Count of Methods: " + methodCount + #LF$
    result = r1 + #LF$
    Debug r1
    r1 = ""
    For i = 0 To methodCount - 1
      *Method = *Methods\i[i];
      Method = PeekS(sel_getName(method_getName(*Method)), -1, #PB_UTF8)
      If HidePrivate And Left(Method, 1) = "_"
        Continue
      EndIf
      r1 + "Method " + Method + #LF$
      If ShowEncoding
        r1 + " * Encoding " + PeekS(method_getTypeEncoding(*Method), -1, #PB_UTF8) + #LF$
      EndIf
      method_getReturnType(*Method, *String, 1024)
      r1 + " -- ReturnType = " + GetArgumentType(*String) + #LF$
      c = method_getNumberOfArguments(*Method)
      For n = FirstArgument To c - 1
        method_getArgumentType(*Method, n, *String, 1024)
        r1 + " -- Argument " + Str(n - FirstArgument + 1) + " = " + GetArgumentType(*String) + #LF$
      Next
      result + r1 + #LF$
      Debug r1
      r1 = ""
    Next
    r1 + "End Class" + #LF$
    result + r1 + #LF$
    Debug r1
    If *Methods
      free_(*Methods)
    EndIf
    FreeMemory(*String)
  Else
    r1 = "Object is nil" + #LF$
    result = r1
    Debug r1
  EndIf
  ProcedureReturn result
EndProcedure

; ****

;-TOP

Procedure UpdateWindow()
  Protected dx, dy
  dx = WindowWidth(0)
  dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
  ; Resize Gadgets
EndProcedure

Procedure Main()
  Protected dx, dy
  
  #WinStyle = #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget | #PB_Window_MinimizeGadget
  
  If OpenWindow(0, #PB_Ignore, #PB_Ignore, 600, 400, "Test Window", #WinStyle)
    ; MenuBar
    CreateMenu(0, WindowID(0))
    MenuTitle("&File")
    MenuItem(99, "E&xit")
    
    ; StatusBar
    CreateStatusBar(0, WindowID(0))
    AddStatusBarField(#PB_Ignore)
    
    ; Gadgets
    dx = WindowWidth(0)
    dy = WindowHeight(0) - StatusBarHeight(0) - MenuHeight()
    
    ; Bind Events
    BindEvent(#PB_Event_SizeWindow, @UpdateWindow(), 0)
    
    obj = WindowID(0)
    ;DumpObjectMethods(obj,1)
    
    objCloseBtn = CocoaMessage(0, obj, "standardWindowButton:", 0)
    CocoaMessage(0, objCloseBtn, "setHidden:", #True)
    objMinimizeBtn = CocoaMessage(0, obj, "standardWindowButton:", 1)
    CocoaMessage(0, objMinimizeBtn, "setHidden:", #True)
    objMaximizeBtn = CocoaMessage(0, obj, "standardWindowButton:", 2)
    CocoaMessage(0, objMaximizeBtn, "setHidden:", #True)
    
    DumpObjectMethods(objCloseBtn, 0)
    DumpObjectMethods(objCloseBtn, 1)
    
    
    ; Main Loop
    Repeat
      Select WaitWindowEvent()
        Case #PB_Event_CloseWindow
          Select EventWindow()
            Case 0
              Break
          EndSelect
          
        Case #PB_Event_Menu
          Select EventMenu()
            Case 99
              PostEvent(#PB_Event_CloseWindow, 0, 0)
              
          EndSelect
          
        Case #PB_Event_Gadget
          Select EventGadget()
              
          EndSelect
          
      EndSelect
    ForEver
    
  EndIf
  
EndProcedure : Main()
My Projects ThreadToGUI / OOP-BaseClass / EventDesigner V3
PB v3.30 / v5.75 - OS Mac Mini OSX 10.xx - VM Window Pro / Linux Ubuntu
Downloads on my Webspace / OneDrive
User avatar
rndrei
Enthusiast
Enthusiast
Posts: 203
Joined: Thu Dec 28, 2023 9:04 pm

Re: Borderless mini icon

Post by rndrei »

Fine works! Thank's!
Post Reply