MouseX(), MouseY()

BlitzMax Forums/BlitzMax Programming/MouseX(), MouseY()

CS_TBL(Posted 2006) [#1]
We need proper ones in BMaxgui, one that *always* gives the mousecoord relative to your desktop, rather than a Graphics window or GUI Window. Again in B+ it worked, in Bmax it doesn't work that way. Things like custom-built dragable windows are right now impossible.


Perturbatio(Posted 2006) [#2]
Can't you do something in combination with the Desktop Gadget?


CS_TBL(Posted 2006) [#3]
like?


Perturbatio(Posted 2006) [#4]
Dunno, I'd need to play around for a while to see if there was anything I could do. Maybe capture mousemove events on it, something like that.


CS_TBL(Posted 2006) [#5]
Let's make things a bit easier.. first one to make this B+ example run in BMaxgui wins a candybar! :P

window=CreateWindow(".",0,0,640,480,0,1)

canvas=CreateCanvas(48,48,48,48,window)


Repeat
	WaitEvent()
	If EventID()=$803 quit=True

	If EventSource()=canvas
	
		If EventID()=$201 ; mousedown
			oldx=MouseX()
			oldy=MouseY()
			drag=1
		EndIf
		
		If EventID()=$202 ; mouseup
			drag=0
		EndIf

		If drag
			If EventID()=$203 ; mousemove
				x=MouseX()
				y=MouseY()
				SetGadgetShape window,GadgetX(window)+x-oldx,GadgetY(window)+y-oldy,GadgetWidth(window),GadgetHeight(window)
				oldx=x
				oldy=y
			EndIf
		EndIf
		
	EndIf
	
Until quit
End



tonyg(Posted 2006) [#6]
Not sure what the B+ code is doing but does this help?
MYwindow:TGadget=CreateWindow("Candy_test",0,0,640,480,0,1)

MYcanvas:TGadget=CreateCanvas(48,48,48,48,MYwindow)

Repeat
	WaitEvent()
	Select EventID()
		Case EVENT_WINDOWCLOSE
			DebugLog "CLOSING WINDOW"
			End
		Case EVENT_MOUSEDOWN
			 Select EventSource()
			 	Case MYCANVAS
					DebugLog EventX() + " " + EventY()
					drag = 1
			End Select
		 Case event_mouseup
			drag=0
		Case EVENT_GADGETPAINT
	  	    SetGraphics CanvasGraphics (MyCanvas)
    		DrawRect  20,20,50,80
        	Flip
		Case event_mousemove
			If drag
			 DebugLog "canvs : " + GadgetX(mycanvas) + " " + GadgetY(mycanvas)
			DebugLog "window : " + GadgetX(mywindow) + " " + GadgetY(mywindow)
			DebugLog MouseX() + " " + MouseY()
				x = EventX() + GadgetX(mycanvas) 
				y = EventY() + GadgetY(mycanvas)
				SetGadgetShape (mycanvas, x,y,GadgetWidth(mycanvas),GadgetHeight(mycanvas))
	        EndIf
	End Select
	
Forever
End



Replacement if you want the whole window to move...
		Case event_mousemove
			If drag
				x = EventX() + GadgetX(mywindow) 
				y = EventY() + GadgetY(mywindow)
				SetGadgetShape (mywindow, x,y,GadgetWidth(mywindow),GadgetHeight(mywindow))
	        EndIf



CS_TBL(Posted 2006) [#7]
As you see there's a short jump when you start dragging. And apart from that: the mousepointer is reset to the upper-left corner of the canvas..

A mere half peanut, no candy yet! :P


tonyg(Posted 2006) [#8]
<edit> Ooops maybe not.


Dreamora(Posted 2006) [#9]
The jumping is because the code is simply bugged.
It positions the top left corner at the mouse cursor, no mather where you clicked it.

Here is the correct code:

MYwindow:TGadget=CreateWindow("Candy_test",0,0,640,480,0,1)

MYcanvas:TGadget=CreateCanvas(48,48,48,48,MYwindow)

Global mx:Int, my:Int
Repeat
	WaitEvent()
	Select EventID()
		Case EVENT_WINDOWCLOSE
			DebugLog "CLOSING WINDOW"
			End
		Case EVENT_MOUSEDOWN
			 Select EventSource()
			 	Case MYCANVAS
					DebugLog EventX() + " " + EventY()
					mx	= EventX()
					my	= EventY()
					drag = 1
			End Select
		 Case event_mouseup
			drag=0
		Case EVENT_GADGETPAINT
	  	    SetGraphics CanvasGraphics (MyCanvas)
    		DrawRect  20,20,50,80
        	Flip
		Case event_mousemove
			If drag
			 DebugLog "canvs : " + GadgetX(mycanvas) + " " + GadgetY(mycanvas)
			DebugLog "window : " + GadgetX(mywindow) + " " + GadgetY(mywindow)
			DebugLog MouseX() + " " + MouseY()
				x = EventX() + GadgetX(mycanvas) - mx
				y = EventY() + GadgetY(mycanvas) - my
				SetGadgetShape (mycanvas, x,y,GadgetWidth(mycanvas),GadgetHeight(mycanvas))
	        EndIf
	End Select
	
Forever
End



CS_TBL(Posted 2006) [#10]
Somehow I don't believe X,Y events from a canvas are here to solve the problem, I really think we need x,y from the whole desktop, like in B+.. that's why the topic was started anyway!


CS_TBL(Posted 2006) [#11]
Dreamora, also no candy for you, unless you can make the window move without hickup and without moving the cursors to the canvas-corner. :P


tonyg(Posted 2006) [#12]
Thanks Dreamora, I was getting to that bit but thought showing it was close to possible might prompt CS_TBL to share some of the attempts made already.
CS_TBL, I'm guessing you've already done a lot of work on this and come to the conclusion it's not possible (hence the bug report). Did you get as far as Dreamora's code?
If so, what did you try next?


CS_TBL(Posted 2006) [#13]
Dreamora's code sofar only moves the canvas. Since I intend to move the window where the canvas is on, one can forsee that weird stuff will happen if you move the parent of the canvas which you use to move the parent. :P I dunno, it just sounds .. scary .. fragile .. :P

Therefore one needs screen x/y, not canvas x/y!


Dreamora(Posted 2006) [#14]
What is the exact problem?

Mouse Move events are only generated for Panels on active and canvas as well as window. So unless you clearly specify what strange bugged thing you try to create, its nearly impossible to show you a small source that works ... (and what do you mean by hickup)

Do you want to move the window from within its border?!


CS_TBL(Posted 2006) [#15]
Uh, nevermind, f1x0rred! Had to change your canvas-related things to window-related things.. *st00pid*.

While I'm still under the impression we need screen-related x,y in BMax, for the moment the issue is gone here!




tonyg(Posted 2006) [#16]
Dreamora, I get a slight blurry effect when moving the canvas and/or the window.
CS_TBL if you change mycanvas to mywindow in the case event_mousemove code it moves the window OK.


Grey Alien(Posted 2006) [#17]
I assume making your own function to get the coords relative to desktop isn't good enough? Here's a win32 version:

?win32
Extern "win32"
	Function GetCursorPos%(point: Byte Ptr)
End Extern
?

Type TPoint
	Field X
	Field Y
	
	Method Set(tx,ty)
		X = tx
		Y = ty
	End Method
End Type

' -----------------------------------------------------------------------------
' ccGetCursorPos
' -----------------------------------------------------------------------------
Function ccGetCursorPos:TPoint()
	'Returns a TPoint
	Local point:TPoint = New TPoint
	?Win32 
	If Not GetCursorPos(point) Then
    	RunTimeError ("Error Getting Cursor Pos")	
		Return Null
	Else
		Return point
	EndIf
	?
	Return point 'safety for non-windows
End Function


So you can just do ccGetCursorPos().x etc.

This works fine for me.


ImaginaryHuman(Posted 2006) [#18]
Use MaxGUI. You can easily do your own window moving and resizing. You use SetGadgetShape to move/resize stuff and GadgetX() and GadgetY() to read the window's position.


CS_TBL(Posted 2006) [#19]
???

we *are* using MaxGUI :P


marksibly(Posted 2006) [#20]
Hi,

Not really a bug report, but here's a Windows-only solution for now...
Strict

Extern "win32"
Function GetCursorPos( point:Byte Ptr )
End Extern

Type TPoint
	Field x,y
End Type

Local point:TPoint=New TPoint

Repeat
	GetCursorPos point
	Print point.x+","+point.y
	Delay 100
Forever

...but I don't like your chances of doing 'custom-built windows'...


CS_TBL(Posted 2006) [#21]
What's against them?

IMHO here are the pros:
- can look more fancy
- can have major additional functionality
- can be more screen-efficient

cons:
- it's not according to the OS settings

The problems start when you're doing brutesque things like map-editors, gfx-editors and other things which are huge and where you need all the pixels there are at once. Often enough ppl have pumped-up titlebars, windowmenus and suddenly your app doesn't fit the window. Buttons with texts on them? What about people with big ugly fonts, then you get cut-off words. (that's why ppl want imagebuttons ever since B+, since icons are small, international and efficient :P)

The whole point is that the Windows interface is quite limited. I've made custom gadgets for years already, and just by combing LMB and RMB things, keyboard things and combinations, there're so much functionality to add to a single gadget. This extra functionality can actually replace a lot of other gadgets this way. A simple scrollbar for example is really far too simple, there're so many ways one can enhance a scrollbar with the aid of extra mouse functionality, keyboard functionality. My aim is to create flexible instruments out of gadgets, not just dull devices!

About the con, that it's not according to one's OS settings.. well, their OS settings might also not be according to the requirements of my app. And with evertone having different settings there's no telling what I should rely on. Rather than them ruining my interface, I rather have my own interface with guaranteed sizes and dimensions.


ImaginaryHuman(Posted 2006) [#22]
Umm ... it's simple enough, I don't see what the fuss is about.

Use GadgetX() and GadgetY() to get the position of the Window gadget. This is relative to the desktop in absolute coords. Then get the GadgetX() and GadgetY() of the top left of the canvas which covers the whole client area of the window, and subtract it from the window topleft. This gives you the size of the title bar and/or border. Then get your relative mouse coords and add the window coords plus the title bar size to get the absolute coords. Then use SetGadgetShape() to position the window.


tonyg(Posted 2006) [#23]
???
Isn't that what the code posted earlier is doing?


Picklesworth(Posted 2006) [#24]
Well, I can voice another reason to prefer GUIs that use the OS's native API:
With recent versions of Gnome, it is possible to set a window to be always on top of or always below others.
The very cool thing here is that if I then run Photoshop with Wine in Ubuntu, the program becomes easier to deal with than before since I can have one document always on top of all the others. (If I'm using it to grab stuff from and would otherwise need to keep recovering it after it's fallen behind all the other windows).

So... please, at least do real windows!

Another thing I might add is that, in most cases, introducing the user to any more key presses than there already are can easily scare them off.
Same with small buttons (who here has tried to teach themselves Truespace without a guide?) and, in some cases, new gadgets.

Windows's GUI is a bit lacking at the higher level, and lots of those other features that we see in MS Office and the like are a bit obscure and not very common in GUI libraries.
However, its simplicity really isn't a bad thing: The GUI is built around accessibility.
When a program uses the Windows GUI, people who rely on hotkeys can trust these that they can control it to a reasonable extent without a mouse.
More realistically, someone who needs bigger text can get that bigger text. I would be surprised if I saw a single custom GUI which made note of the OS's text size, colour and font options.
Then there's voice recognition... Vista has a really excellent speech recognition system, handy for presentations by weirdos and disabled people. (Consequences of not using the OS's own GUI for this are obvious - the program misses out on a lot of fun. For instance, a nuclear reactor simulator can get pretty intense once there's voice command going on!).


Of course, for map editors the like, it may be the best solution. (Games, of course, should obviously barely ever use the native GUI)
Just head my warnings if anyone plans to use a non-native UI for a program whose users have the slightest chance of using any of the above features.


CS_TBL(Posted 2006) [#25]
But it *is* a window technically, it just would have another dragbar and another set o' [_][ ][X] buttons. It's just CreateWindow with flags to 0|WINDOW_ACCEPTFILES. All these thing are canvases, e.g. official things I'd guess.


Grey Alien(Posted 2006) [#26]
hey Mark just copied my code and made it smaller! ;-)


CS_TBL(Posted 2006) [#27]
The problem is that Windows (or any GUI for that matter) is a Jack of all trades and a master of none. In most cases, apps are quite simple, made for simple people. Also, quite a bunch o' ppl don't care for rapid working. A simple UI for simple people..
Things are a bit different when you're using a creative tool, for example to create gfx, audio, music, maps, 3d etc. etc. Those ppl are the expert users who want to apply functions with the press of a key, rather than go into some menu, a submenu etc. The most obvious comparison I can draw is composing with a track vs drag/drop notes in some score editor. That workflow difference is so damn obvious, and it's exactly that superfast workflow I want to insert in my apps. Therefor I require multi-functional gadgets and oodles o' hotkeys... to really make an instrument of the app. Maybe you need to learn the instrument, but in the end you'll be quickly jumping around in the app like a deer. So, in the end the pros outrule the cons imho.
(naturally my apps are no dull wordprocessors, databases or other simple consumer products, all are retro gfx/games/maps-apps, e.g. apps where I need workspace and fast operation.)


Picklesworth(Posted 2006) [#28]
CS_TBL:
I agree with you in that respect, for sure!
As I think I said (I never really know...) it really depends on the type of app being made, and whether or not it is avoidable. (Is the GUI just mimicking Windows and doing a bad job of it, or is something new being done?)

I know there are a good number apps that could not do with a native API, but lots of the time an even ground can be found.
For example, poking around in Photoshop reveals that it uses Windows's native menus, combo boxes, tool windows and text boxes, but most of the other gadgets are custom. (The tool windows are canvases... tabs are custom too, for some reason, with the only apparent reason being that they have a fancy shape).
This way, all the gadgets that people are used to and expect to behave in a certain way (all those hotkeys and Copy/Paste) will work as expected, but other gadgets that are specific to the program such as the colour swatches thing, colour slider bars and the brushes menu (which still incorporates native GUI elements, like the scroll bar and appropriate font) can behave however they want, since nobody is really used to how they "should" behave.
An example of this freedom is that the brushes menu does not scroll with the arrow keys like most menus.

Fast operation is a tricky one.
If Cinema 4d wasn't powered by a non-native GUI (does weird things like letting me detach window menus and place them as toolbars :P... that's about it -- I guess the reason they did it was for easy cross-platform and the material editor), its quick-access menu (mouse 4 for me... not sure about everyone else) would still be possible by placing native buttons on top of the canvas which automatically spawn native popup menus when they are hovered over.
No pain, and far more user accessibility without having to worry about it.

So, in terms of 3d modellers:
Rotation / movement widgets, file browsers with 3d preview, etc... I am always glad to see working even if they're not native.
But the thing is: They couldn't be native :)

Drag and drop music stuff:
Definietly the most obvious thing that isn't possible with a native GUI. It's sort of potentially doable with Windows's drag and drop operations, but it would be messy, clunky, and a lot of unnecessary work to get right.
Still, as with Photoshop, text boxes, alert boxes, file open / save menus and popup menus don't really have to change. (Except between different users using different fonts and colours for their UI).


CS_TBL(Posted 2006) [#29]
BlitzMax Forums/BlitzMax Programming/MaxGUI cross platformness

It's this crap I want to avoid! :P :P :P

Anyway, I made some progress on my TSmartwindow, only need to add a menubutton, minimizebutton and closebutton and then it's fully usable! It even has a glowing dragbar when hovering over it!


Smokey(Posted 2006) [#30]
Hi

long since someone post something... anyway

hey Mark you call the function GetCursorPos but it's
not working in a bmax windows If I pass the mouse over a button it's stop printing the coord how this can be since it's a win32 function , things I would like is to get mouse position event if I pass over a gadget. it will let me have more control on the current window and control.