Let's say I have a window that I opened with WINDOW_CLIENTCOORDS. Then I added a canvas which covers the whole client area. Shouldn't calls to GadgetX(window) and GadgetY(window) return the topleft coordinates, relative to the screen edge, of the canvas, and not the window?
Otherwise, when you do this:
the window jumps `up` by the height of the title bar. The above code should not move the window or change its size at all. But GadgetX() and GadgetY() are returning the top left corner of the window border itself, not the gadget, yet trying to set the window's shape with SetGadgetShape() is taking into account that you asked for CLIENTCOORDS and is thus pushing the titlebar outside of what it thinks is the client area.
??????
Or is there some other way that I can a) read the window position and b) use that position in SetGadgetShape so that the top left of the window doesn't actually move? Does it mean I have to take out WINDOW_CLIENTCOORDS and try working based on ClientWidth(window) and ClientHeight(window) to get the size of the canvas, rather than being able to specify the exact canvas size?
Here is the original program in question - the SetGadgetShape() in the MOUSEMOVE event is where the problem is.
Otherwise, when you do this:
SetGadgetShape window,GadgetX(window),GadgetY(window),CanvasWidth(window),CanvasHeight(window)
the window jumps `up` by the height of the title bar. The above code should not move the window or change its size at all. But GadgetX() and GadgetY() are returning the top left corner of the window border itself, not the gadget, yet trying to set the window's shape with SetGadgetShape() is taking into account that you asked for CLIENTCOORDS and is thus pushing the titlebar outside of what it thinks is the client area.
??????
Or is there some other way that I can a) read the window position and b) use that position in SetGadgetShape so that the top left of the window doesn't actually move? Does it mean I have to take out WINDOW_CLIENTCOORDS and try working based on ClientWidth(window) and ClientHeight(window) to get the size of the canvas, rather than being able to specify the exact canvas size?
Here is the original program in question - the SetGadgetShape() in the MOUSEMOVE event is where the problem is.
'MOUSEMOVE event with SetGadgetShape() is making the window jump up by the height of the title bar or more, due to GadgetY() returning the topleft of the window title bar, and 'SetGadgetShape() using the CLIENTCOORDS topleft of the canvas instead. Strict Global GAME_WIDTH=320'ClientWidth(Desktop()) Global GAME_HEIGHT=240'ClientHeight(Desktop()) Local wx=(GadgetWidth(Desktop())-GAME_WIDTH)/2 Local wy=(GadgetHeight(Desktop())-GAME_HEIGHT)/2 Global lastdw:Int=GadgetWidth(Desktop()) Global lastdh:Int=GadgetHeight(Desktop()) 'make a window Global window:TGadget=CreateWindow("My Canvas",wx,wy,GAME_WIDTH,GAME_HEIGHT,Null,WINDOW_TITLEBAR|WINDOW_CLIENTCOORDS)'|WINDOW_RESIZABLE) 'SetMinWindowSize window,150,100 Global MinX:Int=150 'Minimum canvas size Global MinY:Int=100 Global MaxX:Int=640 'Maximum canvas size Global MaxY:Int=480 ' create a canvas for our game Global canvas:TGadget=CreateCanvas(0,0,GAME_WIDTH,GAME_HEIGHT,window) SetGraphics CanvasGraphics(canvas) SetGadgetLayout canvas,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED,EDGE_ALIGNED CreateTimer 60 Global xm:Int,ym:Int Global oldwidth:Int,oldheight:Int Global Resizing:Int=False Global Paused:Int=False Function MyHook:Object(id:Int,tData:Object,tContext:Object) Local Event:TEvent=TEvent(tData) If Event=Null Then Return Null 'Dont interpret if null Select Event.ID 'Misc events Case EVENT_WINDOWACTIVATE Print "Window activated hook!" Return Null Case EVENT_APPSUSPEND Print "App suspend hook! - clicked on another window/desktop" DrawText "Paused",Rand(0,GadgetWidth(canvas)),Rand(0,GadgetHeight(canvas)) Flip 1 RedrawGadget canvas ActivateGadget canvas Paused=True Return Null Case EVENT_APPRESUME Print "App resume hook! - clicked back in our window" Paused=False Return Null Case EVENT_WINDOWCLOSE FreeGadget canvas Print "Window Closed hook!" End Case EVENT_APPTERMINATE Print "App terminated hook! It's all over." End EndSelect Select Event.source 'Events from the window Case window Select Event.ID Case EVENT_WINDOWSIZE 'Minimized/maximized? If WindowMinimized(window)=True Print "Window minimized!" DrawText "Paused",Rand(0,GadgetWidth(canvas)),Rand(0,GadgetHeight(canvas)) Flip 1 RedrawGadget canvas Paused=True Else Paused=False EndIf Return Null Case EVENT_WINDOWMOVE 'WHILE the user is still moving the window, 'update the game (updates onle when the user stopped moving) Print "Window Move Hook! "+Event.ToString() Return Null End Select 'Events from the canvas Case canvas Select Event.ID Case EVENT_MOUSEDOWN 'Begin resizing the window, activated by clicking in the zone 'Could be detected with a custom resize gadget sending an event xm=Event.x ym=Event.y If xm>GadgetWidth(canvas)-20 And xm<GadgetWidth(canvas) If ym>GadgetHeight(canvas)-20 And ym<GadgetHeight(canvas) Print "Custom ReSize Hook begins! "+Event.ToString() Print "Mouse: "+xm+","+ym Print "Canvas: "+GadgetWidth(canvas)+","+GadgetHeight(canvas) Resizing=True oldwidth=ClientWidth(canvas) oldheight=ClientHeight(canvas) EndIf EndIf Return Null Case EVENT_MOUSEUP If Resizing=True Resizing=False 'Resizing ended Print "Window resizing complete" EndIf Return Null Case EVENT_MOUSEMOVE 'Custom window resize gadget Print "Move Hook! Moved! "+Event.ToString() If Resizing=True 'redraw game Print "Resized window - mouse moved to "+Event.x+","+Event.y SetGadgetShape window,GadgetX(window),GadgetY(window),Min(Max(oldwidth+(Event.x-xm),MinX),MaxX),Min(Max(oldheight+(Event.y-ym),MinY),MaxY) EndIf Return Null Case EVENT_GADGETPAINT 'o/s requested refresh SetGraphics CanvasGraphics(canvas) SetViewport 0,0,GadgetWidth(canvas),GadgetHeight(canvas) SetOrigin GadgetWidth(canvas)/2,GadgetHeight(canvas)/2 SetLineWidth 5*(GadgetWidth(canvas)/Float(GadgetWidth(Desktop()))) Cls If Paused=True DrawText "Paused",Rand(0,GadgetWidth(canvas)),Rand(0,GadgetHeight(canvas)) Flip 1 Else Local t=MilliSecs() DrawLine 0,0,520*Cos(t),520*Sin(t) DrawLine 0,0,580*Cos(t/60),580*Sin(t/60) SetOrigin 0,0 DrawLine 0,GadgetHeight(canvas)-50,GadgetWidth(canvas),GadgetHeight(canvas)-50 DrawLine GadgetWidth(canvas)-20,GadgetHeight(canvas)-20,GadgetWidth(canvas),GadgetHeight(canvas)-20 DrawLine GadgetWidth(canvas)-20,GadgetHeight(canvas)-20,GadgetWidth(canvas)-20,GadgetHeight(canvas) Flip 1 EndIf Return Null EndSelect EndSelect If Event.ID=EVENT_TIMERTICK 'Timer says time to update If GadgetWidth(Desktop())<>lastdw Or GadgetHeight(Desktop())<>lastdh 'Desktop resized by user using o/s? lastdw=ClientWidth(Desktop()) lastdh=ClientHeight(Desktop()) GAME_WIDTH=lastdw GAME_HEIGHT=lastdh SetGadgetShape(window,0,0,lastdw,lastdh) 'resize EndIf If Paused=True DrawText "Paused",Rand(0,GadgetWidth(canvas)),Rand(0,GadgetHeight(canvas)) Flip EndIf RedrawGadget canvas 'Generate GADGETPAINT event Return Null EndIf Print "Unused Event - "+Event.ToString() Return tData 'Pass back unused events End Function 'Add our hook to the system AddHook EmitEventHook,MyHook While True WaitEvent() 'Handle unhooked or passed-through events Select EventID() End Select Wend