Live resize ?

Mac OSX specific forum
cas
Enthusiast
Enthusiast
Posts: 597
Joined: Mon Nov 03, 2008 9:56 pm

Live resize ?

Post by cas »

When i resize window with mouse then i get this rectangle that shows new size:

Image

How can i create window that will automatically resize with every mouse move (?), not only when i release mouse button, like in windows.
I have a lot of apps installed on my mac and neither one of them is behaving like this one created in purebasic.
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

Post by Airr »

Try this after the OpenWindow statement:

Code: Select all

ChangeWindowAttributes_(WindowID(0),(1 << 28),0)
The kWindowLiveResizeAttribute property (whose value is 1 << 28 ) doesn't appear to be enabled by default.

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

Post by WilliamL »

ChangeWindowAttributes_(WindowID(0),(1 << 28 ),0)
I didn't see this command in the 'commands list'. I'm wondering what other attributes can be changed?
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:

Post by Airr »

It's a Carbon API function.

To see what other attributes can be altered, use the Developer documentation that comes with Xcode and search for "Window Manager Reference".

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

Post by WilliamL »

That's very interesting. I found the info and was inspired to try this but it didn't work.

Code: Select all

setwindowmodified_(WindowID(0),1)
[later]

I discovered this thread:

http://www.purebasic.fr/english/viewtop ... d&start=30

and they seem to be covering this territory back in 2005. It appeared that this function was added (by Fred?).

Code: Select all

err = SetWindowModified_(WindowID(0),#C_TRUE) 
but it doesn't seem to work either.

The links to Carbonx seem to be no longer pointing to it... I assume it is dead?

It's too bad this wasn't all worked out back in '05 with 'pbsoimporter' and the data file. (page one in link above). That seems like the way to go but those links don't work either.
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:

Post by Airr »

SetWindowModified is a Carbon API call which allows you to set or clear the modification state of a Window's contents (not the window itself).

From the Developer Documentation:
Your application can use the functions SetWindowModified and IsWindowModified instead of maintaining its own separate record of the modification state of the content of a window. The modification state of a window is visually represented by a dot in the window’s close box. If the dot is present, the window is modified; if the dot is absent, the window is not modified.

Your application should distinguish between the modification state of the window and the modification state of the window’s contents, typically a document. The modification state of the window contents are what should affect SetWindowModified. For example, in the case of a word processing document, you call SetWindowModified (passing true in the modified parameter) whenever the user types new characters into the document. However, you do not call SetWindowModified when the user moves the window, because that change does not affect the document contents. If you need to track whether the window position has changed, you need to do this with your own flag.
You'll need to import it along with IsWindowModified (to check the status):

Code: Select all

ImportC "/System/Library/Frameworks/Carbon.framework/Carbon"
  SetWindowModified(WindowRef.l, State.l)
  IsWindowModified(WindowRef.l) ; returns Boolean
EndImport  
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

Post by WilliamL »

Using 'ImportC' worked fine and the button was set. I'm not sure why ChangeWindowAttributes_ works without the 'ImportC' command but I guess some of the commands are already in PB and others need to be called with 'ImportC'.

So now I can use the whole Carbon toolbox with using your 'ImportC' form?
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:

Post by Airr »

For the most part, I believe the answer would be yes.

Since the windows aren't composited, I don't think you can use all of the HIView functions.

A bigger issue is (are?) some of the CF types (CF = CoreFoundation). For example a CFString, which is what is needed for some of the API function parameters. PureBasic uses Cstrings, I think, which need to be converted over before (or during, by doing it "inline") the function call.

Btw, I think you could also provide a linker options file (Compiler>Compiler Options) and do away with the ImportC block(s). Then you should be able to call the functions using the trailing-underscore syntax.

AIR.
"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:

Post by Airr »

Ok, CFStrings can be handled with:

Code: Select all

Procedure CFSTR(cString.s)
  ProcedureReturn CFStringCreateWithCString_(0, cString, 0)
EndProcedure
And you would call it like this:

Code: Select all

CFPreferencesSetAppValue(CFSTR(key),CFSTR(value),CFSTR(plist))
I originally wrote the CFSTR procedure as a Macro (which is how Carbon does it in it's headers), but for the sake of smaller code converted it to a procedure...

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: Live resize ?

Post by wilbert »

I use PB for Windows sometimes and now are trying PB 4.40 (x86) for OSX (OSX 10.6.2, Xcode 3.2.1).
So far it's kind of a frustrating experience. Just like in Windows I would like a live resize.
I used the GadgetSplitterAdvanced example that comes with PB to test things.
The unmodified example sometimes works fine but most of the times crashes with a "Invalid memory access." after closing the compiled example.
ChangeWindowAttributes does result in a live resize but the gadgets inside the window aren't resized because the event broadcasted while resizing isn't listened for.
I think InstallWindowEventHandler would be required to install a handler that detects the event but I have no idea how to import this function.
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Live resize ?

Post by wilbert »

Never mind, I got it working.
It works on OSX 10.6.2 . From what I understand so far, it should also work on OSX 10.2 or higher.
If someone has a OSX version from 10.2 to 10.5 and wants to test it, I would appreciate it if you let me know if it works.

Code: Select all

#kEventClassWindow = 'wind'
#kEventParamCurrentBounds = 'crct'
#kEventParamPreviousBounds = 'prct'
#kEventWindowBoundsChanging = 26
#kWindowNoAttributes = $0
#kWindowLiveResizeAttribute = $10000000
#noErr = 0
#typeHIRect = 'hirc'
     
ImportC "/System/Library/Frameworks/Carbon.framework/Carbon"
  ChangeWindowAttributes (window, setTheseAttributes, clearTheseAttributes)
  GetEventParameter (event, name, desiredType, ptrActualType, bufferSize, ptrActualSize, ptrData)
  GetWindowEventTarget (target)
  InstallEventHandler (target, handler, numTypes, ptrList, userData, outHandlerRef)
  NewEventHandlerUPP (userRoutine)
  SetWindowResizeLimits (window, minLimits, maxLimits)
EndImport

Macro InstallWindowEventHandler (target, handler, numTypes, ptrList, userData, outHandlerRef)
  InstallEventHandler(GetWindowEventTarget(target), handler, numTypes, ptrList, userData, outHandlerRef)
EndMacro

Structure EventTypeSpec
  eventClass.l
  eventKind.l
EndStructure

Structure HIRect
  x.f
  y.f
  width.f
  height.f
EndStructure

Structure HISize
  width.f
  height.f
EndStructure

ProcedureC.l ResizeHandler (nextHandler, theEvent, ptrUserData)
  GetEventParameter(theEvent, #kEventParamCurrentBounds, #typeHIRect, #Null, SizeOf(HIRect), #Null, @current.HIRect)  
  GetEventParameter(theEvent, #kEventParamPreviousBounds, #typeHIRect, #Null, SizeOf(HIRect), #Null, @previous.HIRect)  
  If current\width <> previous\width Or current\height <> previous\height
    ResizeGadget(0, 10, 10, current\width - 20, current\height - 50)
  EndIf
  ProcedureReturn #noErr
EndProcedure

WindowRef.l = OpenWindow(0, 0, 0, 640, 480, "PureBasic - Live Resize", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
If WindowRef

  minSize.HISize\width = 120
  minSize\height = 150
  maxSize.HISize\width = 1024
  maxSize\height = 768
  SetWindowResizeLimits(WindowRef, @minSize, @maxSize)
  ChangeWindowAttributes(WindowRef, #kWindowLiveResizeAttribute, #kWindowNoAttributes)
  EventList.EventTypeSpec\eventClass = #kEventClassWindow
  EventList\eventKind = #kEventWindowBoundsChanging
  InstallWindowEventHandler(WindowRef, NewEventHandlerUPP(@ResizeHandler()), 1, @EventList, #Null, #Null)

  WebGadget(0, 10, 10, 620, 430, "http://www.purebasic.com")
  Repeat
    EventID = WaitWindowEvent()
  Until EventID = #PB_Event_CloseWindow

EndIf
End
Last edited by wilbert on Sat Dec 26, 2009 7:29 am, edited 1 time in total.
User avatar
Airr
User
User
Posts: 49
Joined: Tue Oct 04, 2005 4:29 am
Contact:

Re: Live resize ?

Post by Airr »

wilbert wrote:Never mind, I got it working.
It works on OSX 10.6.2 . From what I understand so far, it should also work on OSX 10.2 or higher.
If someone has a OSX version from 10.2 to 10.5 and wants to test it, I would appreciate it if you let me know if it works.
Nice, it works under 10.5.8 here using PureBasic 4.30 x86.

Code: Select all

     
ImportC "/System/Library/Frameworks/Carbon.framework/Carbon"
  ;ChangeWindowAttributes (window, setTheseAttributes, clearTheseAttributes)
  ;GetEventParameter (event, name, desiredType, ptrActualType, bufferSize, ptrActualSize, ptrData)
  ;;GetWindowEventTarget (target)
  ;InstallEventHandler (target, handler, numTypes, ptrList, userData, outHandlerRef)
  SetWindowResizeLimits (window, minLimits, maxLimits)
EndImport
The commented API functions don't need to be imported; they're already "included". Just append an underscore when you call the function { for ex, ChangeWindowAttribute_(...) }

If you view the files located in the purelibraries/macos/ folder with a file viewer (an editor might modify the files if you're not careful) you'll see which MacOS specific API functions are already available.


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: Live resize ?

Post by wilbert »

Thanks for mentioning.
I didn't know those files were there.
User avatar
michel51
Enthusiast
Enthusiast
Posts: 290
Joined: Mon Nov 21, 2005 10:21 pm
Location: Germany

Re: Live resize ?

Post by michel51 »

wilbert wrote:Never mind, I got it working.
It works on OSX 10.6.2 . From what I understand so far, it should also work on OSX 10.2 or higher.
If someone has a OSX version from 10.2 to 10.5 and wants to test it, I would appreciate it if you let me know if it works.

Code: Select all

#kEventClassWindow = 'wind'
#kEventParamCurrentBounds = 'crct'
#kEventParamPreviousBounds = 'prct'
#kEventWindowBoundsChanging = 26
#kWindowNoAttributes = $0
#kWindowLiveResizeAttribute = $10000000
#noErr = 0
#typeHIRect = 'hirc'
     
ImportC "/System/Library/Frameworks/Carbon.framework/Carbon"
  ChangeWindowAttributes (window, setTheseAttributes, clearTheseAttributes)
  GetEventParameter (event, name, desiredType, ptrActualType, bufferSize, ptrActualSize, ptrData)
  GetWindowEventTarget (target)
  InstallEventHandler (target, handler, numTypes, ptrList, userData, outHandlerRef)
  NewEventHandlerUPP (userRoutine)
  SetWindowResizeLimits (window, minLimits, maxLimits)
EndImport

Macro InstallWindowEventHandler (target, handler, numTypes, ptrList, userData, outHandlerRef)
  InstallEventHandler(GetWindowEventTarget(target), handler, numTypes, ptrList, userData, outHandlerRef)
EndMacro

Structure EventTypeSpec
  eventClass.l
  eventKind.l
EndStructure

Structure HIRect
  x.f
  y.f
  width.f
  height.f
EndStructure

Structure HISize
  width.f
  height.f
EndStructure

ProcedureC.l ResizeHandler (nextHandler, theEvent, ptrUserData)
  GetEventParameter(theEvent, #kEventParamCurrentBounds, #typeHIRect, #Null, SizeOf(HIRect), #Null, @current.HIRect)  
  GetEventParameter(theEvent, #kEventParamPreviousBounds, #typeHIRect, #Null, SizeOf(HIRect), #Null, @previous.HIRect)  
  If current\width <> previous\width Or current\height <> previous\height
    ResizeGadget(0, 10, 10, current\width - 20, current\height - 50)
  EndIf
  ProcedureReturn #noErr
EndProcedure

WindowRef.l = OpenWindow(0, 0, 0, 640, 480, "PureBasic - Live Resize", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget)
If WindowRef

  minSize.HISize\width = 120
  minSize\height = 150
  maxSize.HISize\width = 1024
  maxSize\height = 768
  SetWindowResizeLimits(WindowRef, @minSize, @maxSize)
  ChangeWindowAttributes(WindowRef, #kWindowLiveResizeAttribute, #kWindowNoAttributes)
  EventList.EventTypeSpec\eventClass = #kEventClassWindow
  EventList\eventKind = #kEventWindowBoundsChanging
  InstallWindowEventHandler(WindowRef, NewEventHandlerUPP(@ResizeHandler()), 1, @EventList, #Null, #Null)

  WebGadget(0, 10, 10, 620, 430, "http://www.purebasic.com")
  Repeat
    EventID = WaitWindowEvent()
  Until EventID = #PB_Event_CloseWindow

EndIf
End
Great job, thanks for sharing :!:
Live resizing works on my Mac PPC, 10.4.11 :D
michel51

Mac OS X Snow Leopard (10.6.8 ) Intel
PureBasic V 5.21(x64), V 5.22beta
wilbert
PureBasic Expert
PureBasic Expert
Posts: 3870
Joined: Sun Aug 08, 2004 5:21 am
Location: Netherlands

Re: Live resize ?

Post by wilbert »

Thanks for mentioning it also works on PPC.

For myself what I wanted (if possible) is a cross platform ( Win32 / OSX_x86 ) solution so I created a cross-platform userlib.
Since the lib is written in ASM, it isn't working on a PPC. For those who are using OSX_x86 and Win32, here it is
http://www.w73.nl/pb/wxl_Lib.zip
The zip file contains a userlib for Win32 and one for OSX_x86.

Example code that works on both platforms

Code: Select all

Procedure LiveResizeHandler (newWidth.l, newHeight.l)
  ResizeGadget(0, 10, 10, newWidth - 20, newHeight - 50)
EndProcedure

If OpenWindow(0, 0, 0, 640, 480, "PureBasic - Live Resize", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)

  wxl_AddLiveResizeEventHandler(WindowID(0), @LiveResizeHandler())

  WindowBounds(0, 120, 150, 1024, 768)
  WebGadget(0, 10, 10, 620, 430, "http://www.purebasic.com")

  Repeat
    EventID = WaitWindowEvent()
  Until EventID = #PB_Event_CloseWindow

EndIf

End
The handler must be a procedure with two parameters.
The windows lib has the restriction that it can only handle 16 event handlers at the same time and all windows that want to use this function need to be created from the main thread.
Last edited by wilbert on Wed May 31, 2017 3:15 pm, edited 1 time in total.
Post Reply