setAutoresizingMask

Mac OSX specific forum
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

setAutoresizingMask

Post by Airr »

It's been a long time since I've visited this forum, amazing how far PB has come since my last visit!

One of the things I've always wanted to be able to do is auto-size/anchor Gadgets like Interface Builder allows one to do.

So I downloaded the latest Mac beta of PB last night, and started playing. Here's what I have:

Code: Select all

;
; ------------------------------------------------------------
;
;   Live Gadget Auto Resizing Demo
;
; ------------------------------------------------------------
;

;
; Open a window, and try resizing it...
;

Enumeration
  #Window
  #Entry
  #Button
  #Editor
  #Combo
EndEnumeration

Enumeration
  #akNone
  #akRight                        ; anchor to right side of Window, no resize
  #akWidth                        ; resize width of Gadget, based on width of Window
  #akLeft = 4                     ; anchor to left side of Window, no resize
  #akTop = 8                      ; anchor to top of Window, no resize
  #akHeight = 16                  ; resize height of Gadget, based on height of Window
  #akFull = #akWidth | #akHeight  ; resize width/height of Gadget, based on width/height of Window
EndEnumeration


Procedure Anchor (handle, value)
  Define tmp
  Select GadgetType(handle)
    Case  #PB_GadgetType_Editor
      ; EDITOR GADGET IS COMPOSED OF NSTEXTVIEW->NSCLIPVIEW->NSSCROLLVIEW HIERARCHY
      ; So we have to traverse the hierarchy to get the actual NSScrollView object
      tmp = CocoaMessage(0,CocoaMessage(0, GadgetID(handle),"superview"),"superview")
      
    Default
      tmp = GadgetID(handle)
  EndSelect
  
  CocoaMessage(0,tmp, "setAutoresizingMask:", value)  
EndProcedure

If OpenWindow(#Window, 100, 200, 800, 600, "Live Gadget Auto Resizing Demo", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  ; Set minimum window size
  Define con.CGSize
  con\width = 800
  con\height = 622
  CocoaMessage(0,WindowID(#Window), "setMinSize:@", @con)
  
  Top = 16
  GadgetHeight = 24

  StringGadget(#Entry,  20, Top, 670, GadgetHeight, "Hello, World")
  ButtonGadget(#Button, 710, Top-2, 70, GadgetHeight+4, "Click")
  
  ComboBoxGadget(#Combo, 573, 50, 120, GadgetHeight)
  AddGadgetItem(#Combo, -1, "Apples")
  AddGadgetItem(#Combo, -1, "Oranges")
  AddGadgetItem(#Combo, -1, "Peaches")
  SetGadgetState(#Combo,1)
  
  EditorGadget(#Editor, 20, 90,670, 480)
  
  ; Set up auto-resizing by specifying how Gadget is to be anchored in Window
  Anchor(#Button,#akRight)
  Anchor(#Entry,#akWidth)
  Anchor(#Combo, #akRight)
  Anchor(#Editor, #akFull)

  Repeat
    Event = WaitWindowEvent()
  
    If Event = #PB_Event_CloseWindow
      Quit = 1
    EndIf

  Until Quit = 1
  
EndIf

End
What I like about this, is that the native Cocoa runtime is handling the resizing, so it's generally flicker-free.

I'd be interested in hearing what everyone thinks, and please excuse any sloppiness on my part.

AIR.
"Programming is like Poetry. Sometimes the words just escape you..." -me, to my manager.
WilliamL
Addict
Addict
Posts: 1224
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: setAutoresizingMask

Post by WilliamL »

Interesting

How about an ImageGadget()?
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

Re: setAutoresizingMask

Post by Airr »

WilliamL wrote:How about an ImageGadget()?

Code: Select all

Procedure Anchor (handle, value)
  Define tmp
  Select GadgetType(handle)
    Case  #PB_GadgetType_Editor
      ; EDITOR GADGET IS COMPOSED OF NSTEXTVIEW->NSCLIPVIEW->NSSCROLLVIEW HIERARCHY
      ; So we have to traverse the hierarchy to get the actual NSScrollView object
      tmp = CocoaMessage(0,CocoaMessage(0, GadgetID(handle),"superview"),"superview")
      
    Case #PB_GadgetType_Image
      ; This will cause the image to scale proportionally
      ; To scale-to-fit, use "1"
      CocoaMessage(0,GadgetID(handle),"setImageScaling:",3)
      tmp = GadgetID(handle)   
      
    Default
      tmp = GadgetID(handle)
  EndSelect
  
  CocoaMessage(0,tmp, "setAutoresizingMask:", value)  
EndProcedure
"Programming is like Poetry. Sometimes the words just escape you..." -me, to my manager.
WilliamL
Addict
Addict
Posts: 1224
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: setAutoresizingMask

Post by WilliamL »

Works great! I like the use of the constants to define where the field goes and how small the code is.

Here is your code with some of additions:

Code: Select all

Enumeration
  #Window
  #Entry
  #Button
  #Editor
  #Combo
  #imagegadget
EndEnumeration

Enumeration
  #akNone
  #akRight                        ; anchor to right side of Window, no resize
  #akWidth                        ; resize width of Gadget, based on width of Window
  #akLeft = 4                     ; anchor to left side of Window, no resize
  #akTop = 8                      ; anchor to top of Window, no resize
  #akHeight = 16                  ; resize height of Gadget, based on height of Window
  #akFull = #akWidth | #akHeight  ; resize width/height of Gadget, based on width/height of Window
  #akBottom = #akTop|#akWidth     ; attached to bottom of window
EndEnumeration

Procedure Anchor (handle, value)
  Define tmp
  Select GadgetType(handle)
    Case  #PB_GadgetType_Editor,#PB_GadgetType_ListView, #PB_GadgetType_ListIcon, #PB_GadgetType_Tree
      ; EDITOR GADGET IS COMPOSED OF NSTEXTVIEW->NSCLIPVIEW->NSSCROLLVIEW HIERARCHY
      ; So we have to traverse the hierarchy to get the actual NSScrollView object
        tmp = CocoaMessage(0, GadgetID(handle),"enclosingScrollView")
    Case #PB_GadgetType_Image
      ; This will cause the image to scale proportionally
      ; To scale-to-fit, use "1"
      CocoaMessage(0,GadgetID(handle),"setImageScaling:",1)
      tmp = GadgetID(handle)  ;   Live Gadget Auto Resizing Demo
    Default
      tmp = GadgetID(handle)
  EndSelect
  
  CocoaMessage(0,tmp, "setAutoresizingMask:", value)  
EndProcedure

If OpenWindow(#Window, 100, 200, 800, 600, "Live Gadget Auto Resizing Demo", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  ; Set minimum window size
  WindowBounds(#Window, 800, 622, #PB_Default, #PB_Default)
  
  Top = 16
  GadgetHeight = 24

  StringGadget(#Entry,  20, Top, 670, GadgetHeight, "Hello, World")
  ButtonGadget(#Button, 710, Top-2, 70, GadgetHeight+4, "Click")
  
  ComboBoxGadget(#Combo, 573, 50, 120, GadgetHeight)
  AddGadgetItem(#Combo, -1, "Apples")
  AddGadgetItem(#Combo, -1, "Oranges")
  AddGadgetItem(#Combo, -1, "Peaches")
  SetGadgetState(#Combo,1)
  
  ;EditorGadget(#Editor, 20, 90,670, 280)
  ListViewGadget(#Editor, 20, 90,670, 280)
  
  CreateImage(image_id,200,200)
  StartDrawing(ImageOutput(image_id))
  Box(0,0,100,100,0)
  StopDrawing()
  ImageGadget(#ImageGadget,20,380,670,200,ImageID(image_id))
  
  ; Set up auto-resizing by specifying how Gadget is to be anchored in Window
  Anchor(#Button,#akRight)
  Anchor(#Entry,#akWidth)
  Anchor(#Combo, #akRight)
  Anchor(#Editor, #akFull)
  ;Anchor(#ImageGadget, #akFull) ; works but top is over-laid by above
  Anchor(#ImageGadget,#akBottom) ; width only changes
  
  Repeat
    Event = WaitWindowEvent()
  
    If Event = #PB_Event_CloseWindow
      Quit = 1
    EndIf

  Until Quit = 1
EndIf
Last edited by WilliamL on Thu Dec 01, 2016 11:33 pm, edited 2 times in total.
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

Re: setAutoresizingMask

Post by Airr »

Ok, in the Anchor proc, change the "3" to a "1" in the call to "setImageScaling"

Then change

Code: Select all

Anchor(#ImageGadget, #akFull)
to

Code: Select all

Anchor(#ImageGadget, #akTop|#akWidth)
I should note that "#akTop" anchors the widget proportionally to the top or the "Y" axis. So it will push the gadget towards the bottom as the window grows. I guess it might make more sense to define it as "#akBottom" so that it's more intuitive.
"Programming is like Poetry. Sometimes the words just escape you..." -me, to my manager.
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

Re: setAutoresizingMask

Post by Airr »

I decided to give this a try with the PureBasic Gadget Demo source.

Since I couldn't attach files, I created a Gist instead

Give it a try and let me know what you think....

AIR
"Programming is like Poetry. Sometimes the words just escape you..." -me, to my manager.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: setAutoresizingMask

Post by wilbert »

The common way to get the scroll view is like this

Code: Select all

  Select GadgetType(handle)
    Case  #PB_GadgetType_Editor
      tmp = CocoaMessage(0, GadgetID(handle),"enclosingScrollView")
    Default
      tmp = GadgetID(handle)
  EndSelect
Windows (x64)
Raspberry Pi OS (Arm64)
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

Re: setAutoresizingMask

Post by Airr »

tmp = CocoaMessage(0, GadgetID(handle),"enclosingScrollView")
Thanks! Much cleaner!

AIR.
"Programming is like Poetry. Sometimes the words just escape you..." -me, to my manager.
WilliamL
Addict
Addict
Posts: 1224
Joined: Mon Aug 04, 2008 10:56 pm
Location: Seattle, USA

Re: setAutoresizingMask

Post by WilliamL »

this appears to work with the ListViewGadget also...

Code: Select all

    Case  #PB_GadgetType_Editor,#PB_GadgetType_ListView
        tmp = CocoaMessage(0, GadgetID(handle),"enclosingScrollView")
MacBook Pro-M1 (2021), Sonoma 14.4.1, PB 6.10LTS M1
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

Re: setAutoresizingMask

Post by Airr »

Yes, updated the Gist last night with the following:

Code: Select all

    Case  #PB_GadgetType_Editor, #PB_GadgetType_ListView, #PB_GadgetType_ListIcon, #PB_GadgetType_Tree
      ; THE GADGETS ABOVE ARE COMPOSED OF PBGADGET->NSCLIPVIEW->NSSCROLLVIEW HIERARCHY
      ; So we have to retrieve the actual NSScrollView object to resize
      tmp = CocoaMessage(0, GadgetID(handle),"enclosingScrollView")
"Programming is like Poetry. Sometimes the words just escape you..." -me, to my manager.
User avatar
fsw
Addict
Addict
Posts: 1572
Joined: Tue Apr 29, 2003 9:18 pm
Location: North by Northwest

Re: setAutoresizingMask

Post by fsw »

Cool stuff :!:

One thing:

This is not really needed:

Code: Select all

  ; Set minimum window size
  Define con.CGSize
  con\width = 800
  con\height = 622
  CocoaMessage(0,WindowID(#Window), "setMinSize:@", @con)
as there is the built-in WindowBounds() command:

Code: Select all

  ; Set minimum window size
  WindowBounds(#Window, 800, 622, #PB_Default, #PB_Default)
Keep up the good work :D

I am to provide the public with beneficial shocks.
Alfred Hitshock
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

Re: setAutoresizingMask

Post by Airr »

Thanks, will replace what I have with the built-in command.
"Programming is like Poetry. Sometimes the words just escape you..." -me, to my manager.
Post Reply