Event_MouseDown MaxGui question

BlitzMax Forums/BlitzMax Beginners Area/Event_MouseDown MaxGui question

Galdy(Posted 2012) [#1]
When placing walls in my dungeon editor, I'd like to be able to hold the mouse down and have it place walls down as I drag the curser across the map. I can't get it to do that because Event_mousedown seems to only reqister one press event at a time. So i have to click it everytime I want to place a wall. Need some code help on how to do what I desire.


kfprimm(Posted 2012) [#2]
EVENT_MOUSEMOVE should be help you out. Just track when the user presses and releases the mouse (EVENT_MOUSEUP), and every time EVENT_MOUSEMOVE is emitted, place another wall.


Galdy(Posted 2012) [#3]
Don't think that is it. I don't want to have to press/release to set every wall. I want to be able to press, hold the button down and drag it around placeing walls.


rs22(Posted 2012) [#4]
Here is a simple example for you. It doesn't use MaxGUI, though the idea is the same.
SuperStrict

Type TWall
	Field x:Int
	Field y:Int
EndType

Global Walls:TList = New TList

Global LeftDown:Int = False

Graphics 640, 480

Repeat

	If PollEvent()
		Select CurrentEvent.ID
			Case EVENT_MOUSEDOWN
				If EventData() = MOUSE_LEFT Then LeftDown = True
			Case EVENT_MOUSEUP
				If EventData() = MOUSE_LEFT Then LeftDown = False
			Case EVENT_MOUSEMOVE
				If LeftDown = True
					Local Wall:TWall = New TWall
					Wall.x = EventX() - EventX() Mod 32
					Wall.y = EventY() - EventY() Mod 32
					Walls.AddLast(Wall)
				EndIf
		EndSelect
	EndIf
	
	Cls
	
	For Local Wall:TWall = EachIn Walls
		DrawRect(Wall.x, Wall.y, 32, 32)
	Next
	
	Flip

Until KeyHit(KEY_ESCAPE) Or AppTerminate()


Last edited 2012

Last edited 2012

Last edited 2012


Galdy(Posted 2012) [#5]
Ok. Thanks for the code example. I'll try to incorportate it in. Just don't know all that you can do with Maxgui. Very cool Mod. Is there any comprehensive tutorials anywhere? I've been following the beginners guide, but it doesn't cover all the possibilities.


Galdy(Posted 2012) [#6]
Can't figure it out incorporating your code. At best I got random wall placement and it sometimes placed walls when I was not pressing the mousebutton. This snippet doesn't have your code incorporated in it,but it does work in that I can place walls one click at a time. It places walls on a 50x50 grid made up of 20x20 pixel squares. Maybe you can see how I can incorporate what you are suggesting.

#Window_Events  
	
	Repeat
	 WaitEvent()
	    Select EventID()
	        Case EVENT_WINDOWCLOSE
	            End
	 
	        Case EVENT_MOUSEMOVE
			  
          		Mouse_X = EventX()
			   Mouse_Y = EventY()
	 			SetStatusText DungeonEditorWindow, "Mouse coords  " + Mouse_X + "," + Mouse_Y  'Information on the bottom window status bar.
	        Case EVENT_GADGETACTION
	            Select EventSource()
	                 Case MyButton1
	                    SetGadgetText(MyButton1, "Wall")
	                 SetGadgetText(DungeonEditorWindow, "Dungeon Editor    [Current Tool - Wall]")
	                    Tool = 1
	                 Case MyButton2
	                    SetGadgetText(MyButton2, "Door")
	                    SetGadgetText(DungeonEditorWindow, "Dungeon Editor    [Current Tool - Door]")
						Tool = 2
	            End Select				
			Case EVENT_MOUSEDOWN
			    mx = EventX()
	          	my = EventY()
			    GetCoordinates()
				RecordData()
	
	    End Select
		    
	        'SetGadgetText Label, CurrentEvent.ToString()
	        Drawit()
	Forever
	
	'************************************************************************************************************************************
	Function Drawit()
	    SetGraphics CanvasGraphics (MyCanvas)
	 
			Cls
		 
		    DrawImage(BackGroundColor, 0, 0)
		    Local a:Int = 0
		    Local x:Int = 0
		    Local y:Int = 0
		  
	    For a = 1 To 51
			DrawLine 0, y, 1000, y
		 	y:+20
			DrawLine x, 0, x, 1000
			x:+20
	    Next
	
		  Local xx:Int = 0, yy:Int = 0, x1:Int = 0, y1:Int = 0
	
	          For yy = 0 To 49            'y coordinates Loop
	            	For xx = 0 To 49       'x coordinates Loop		
	             		If Dungeon[xx, yy, 0].layer1 = 1 Then
	        	  			DrawImage(Wall, x1, y1)
		        		EndIf
	       			      x1:+20
	        		Next
	            x1 = 0
	     		y1:+20
	    		Next
	 
    	SetColor(192, 192, 192)
		DrawText ("  MapX," + MapX + "  MapY " + MapY, Mouse_X, Mouse_Y)
			'DrawText ("" + MapY, Mouse_X + 40, Mouse_Y)
    	Flip
	
	EndFunction
	
		
	Function DungeonBorder()
	            Local x:Int, c:Int, level:Int
	            For c = 0 To 14
	                For x = 0 To 49
		        	    Dungeon[x, 0, level].Layer1 = 1
		                Dungeon[x, 49, level].Layer1 = 1
		       		    Dungeon[0, x, level].Layer1 = 1
		       		    Dungeon[49, x, level].layer1 = 1
		            Next
	            Next
	End Function
	
	Function GetCoordinates()
		mx:/20 ; my:/20
		MapX = Floor(mx) ;MapY = Floor(my)
	End Function
	
	Function RecordData()
	    If Tool = 1
	    	Dungeon[MapX, MapY, 0].layer1 = 1
		EndIf
	End Function



Zeke(Posted 2012) [#7]
at first. put your DrawIt function to EVENT_GADGETPAINT case.
then in EVENT_MOUSEMOVE add command RedrawGadget(MyCanvas)

then make global Mouse_down and in Case EVENT_MOUSEDOWN add MOUSE_DOWN=true (if mouse is in canvas. that will tell MOUSE IS JUST PRESSED DOWN IN CANVAS)

Case EVENT_MOUSEUP add MOUSE_DOWN=false (mouse button is released.)

and now in Case EVENT_MOUSE_MOVE just check if variable MOUSE_DOWN=true.. and if it is then add wall to that position

Last edited 2012


Brucey(Posted 2012) [#8]
I still don't think procedural-based event handling is either intuitive or a good design.
You just seem to end up with lots of Select statements all over your code…

And in my experience you end up trying to wrap it in some kind of class-based hierarchical structure so you don't have to think about the fact that your events are just one endless stream of Select statements…


anyhoo…


One EVENT_GADGETPAINT is sent every time you are meant to refresh your canvas. That's when you do your drawing stuff. It tends to be about 60fps on an LCD monitor.
You are only interested in mouse events inside your canvas, so for drawing related stuff, do those checks when EventSource() is your canvas.


Zeke(Posted 2012) [#9]
yep.


Midimaster(Posted 2012) [#10]
have a look on this:

SuperStrict
Import MaxGUI.Drivers


Const ON%=1, OFF%=0
Global Window:Tgadget, Canvas:TGadget
Global MausLeft%, MausRight%, MausX%, MausY%
FormLoad
CreateTimer 20

While WaitEvent()
   Select EventID()
  	Case EVENT_TIMERTICK
		RedrawGadget Canvas
   	Case EVENT_GADGETPAINT
		Local Fenster:TGraphics=CanvasGraphics(Canvas)
			SetGraphics Fenster
			SetClsColor 255,255,255
			Cls
			SetColor 255,0,0
			If MausLeft=1
				DrawOval MausX,MausY,33,33
			EndIf	
		Flip 0	
   	Case EVENT_APPTERMINATE
			End
  	Case EVENT_MOUSEDOWN
			Print "MOUSE DOWN=" + EventData() + "   X="+ mausx + "     Y=" + mausy
			Local tmpGadget:TGadget = TGadget(EventSource())
			If tmpGadget=Canvas
				If EventData()=1
					MausLeft=ON
					Print "Picking Object"
				EndIf	
			EndIf
  	Case EVENT_MOUSEUP
			Print "MOUSE UP=" + EventData() + "   X="+ mausx + "     Y=" + mausy
			Local tmpGadget:TGadget = TGadget(EventSource())
			If tmpGadget=Canvas
				If EventData()=1
					MausLeft=OFF
					Print "Dropping Object"
				EndIf	
			EndIf
 	Case EVENT_MOUSEMOVE 
			Print "MOUSE MOVE    X="+ mausx + "     Y=" + mausy
			MausX=EventX()
			MausY=EventY()
			Local tmpGadget:TGadget = TGadget(EventSource())
			If tmpGadget=Canvas
				If MausLeft=1
					Print "DRAWING OBJECT"
				EndIf
			EndIf
 	Case EVENT_MOUSELEAVE
			Print "MOUSE LEAVE"
			Local tmpGadget:TGadget = TGadget(EventSource())
	End Select
Wend

	Function FormLoad()
		Local flags%=WINDOW_DEFAULT|WINDOW_CLIENTCOORDS'|WINDOW_CENTER
		Window= CreateWindow("AURIS {{Ear training}} (Alpha Version 0.20)" , 800 , 200 , 800 ,600 , Null , Flags%)
		Canvas=CreateCanvas(100 , 100 , 400, 400 , Window)
		SetGadgetColor window, 111,0,0
		SetGadgetLayout Canvas , 1,1,1,1
	End Function



Galdy(Posted 2012) [#11]
Thanks for the input everyone. Zeke, your explanation cut right to it for me. Working perfect now. Slowly coming to grips with maxgui.