Event_MouseDown MaxGui question
BlitzMax Forums/BlitzMax Beginners Area/Event_MouseDown MaxGui question| 
 | ||
| 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. | 
| 
 | ||
| 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. | 
| 
 | ||
| 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. | 
| 
 | ||
| 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 | 
| 
 | ||
| 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. | 
| 
 | ||
| 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
 | 
| 
 | ||
| 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 | 
| 
 | ||
| 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. | 
| 
 | ||
| yep. | 
| 
 | ||
| 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
 | 
| 
 | ||
| Thanks for the input everyone. Zeke, your explanation cut right to it for me. Working perfect now. Slowly coming to grips with maxgui. |