[bmx] basic max2d window event system by skidracer [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:41

Previous topic - Next topic

BlitzBot

Title : basic max2d window event system
Author : skidracer
Posted : 1+ years ago

Description : Found this code in a very old folder (pre maxgui)...

I did just refactor TSprite to TQuad before posting, hope it didn't break.

Hit F1 key to add layer

Use mouse to position layer


Code :
Code (blitzmax) Select
' ancient code from old bmx test folder
' hit f1 to add layer
' draw window frames

Strict

Global System:TSystem

Type TQuad
Field x#,y#
Field width,height
Field image:TImage

Method Draw()
DrawImage image,x,y
End Method
End Type

Type TView Extends TQuad
Field parent:TView
Field task:TTask
Field spritelist:TList
Field originx,originy
Field background[]

Method FindView:TView(mx,my)
Local v:TView,p:TView
Local t:TList
If mx>=x And my>=y And mx<x+width And my<y+height
spritelist=spritelist.reversed()
For v=EachIn spritelist
p=v.FindView(mx,my)
If p Exit
Next
spritelist=spritelist.reversed()
If p Return p
Return Self
EndIf
End Method

Method Move(dx#,dy#)
Local v:TView
x:+dx
y:+dy
For v=EachIn spritelist
v.Move(dx,dy)
Next
End Method

Method CreateView:TView(t:TTask,x,y,w,h)
Local v:TView
Assert t
v=New TView
v.parent=Self
v.task=t
v.x=x
v.y=y
v.width=w
v.height=h
v.spritelist=New TList
spritelist.addlast v
Return v
End Method

Method CreateFrameView:TView(t:TTask,x,y,w,h)
Local frame:TView
Local view:TView
frame=CreateView(System,x-4,y-24,w+8,h+28)
frame.background=[0,255,0]
view=frame.CreateView(t,x,y,w,h)
view.background=[0,0,0]
Return view
End Method

Method Draw()
Local s:TQuad
Local vx,vy,vw,vh

vw=width;vh=height
vx=x;If vx<0 vw:+vx;vx=0
vy=y;If vy<0 vh:+vy;vy=0
SetViewport vx,vy,vw,vh
SetOrigin x+originx,y+originy
If background
SetColor background[0],background[1],background[2]
DrawRect 0,0,width,height
SetColor 255,255,255
EndIf
For s=EachIn SpriteList
s.Draw()
Next
End Method

Method CreateSprite:TQuad(image:TImage,x#=0,y#=0)
Local s:TQuad
s=New TQuad
s.x=x
s.y=y
s.width=image.width
s.height=image.height
s.image=image
spritelist.addlast s
Return s
End Method
End Type

Type TDisplay Extends TView

Method Draw()
SetViewport 0,0,width,height
Cls
Super.Draw()
Flip
End Method

Function CreateDisplay:TDisplay(t:TTask,w,h)
Local d:TDisplay
Graphics w,h',32
d=New TDisplay
d.task=t
d.width=w
d.height=h
d.spritelist=New TList
Return d
End Function
End Type

Const MOUSELCLICK=1
Const MOUSERCLICK=2
Const MOUSELDRAG=3
Const MOUSERDRAG=4
Const MOUSELRELEASE=5
Const MOUSERRELEASE=6
Const CHARKEY=7

Type TMessage
Field link:TMessage
Field id
Field MouseX,MouseY
Field MouseXSpeed,MouseYSpeed
Field view:TView
Field CHARKEY
End Type

Type TTask
Field messages:TMessage

Method Post(MSG:TMessage)
Local m:TMessage
m=messages
If m
While m.link
m=m.link
Wend
m.link=MSG
Else
messages=MSG
EndIf
End Method

Method GetMessage:TMessage()
Local m:TMessage
m=messages
If m messages=m.link
Return m
End Method

Method Update() Abstract
End Type

Type TSystem Extends TTask
Field tasklist:TList
Field display:TDisplay
Field shutdown
Field oldmx,oldmy,oldml,oldmr
Field mousefocus:TView
Field keyboardfocus:TView

Method Update()
Local m:TMessage
Local v:TView
Local t:TTask
Local mx,my,ml,mr,mouseevent,c

mx=MouseX()
my=MouseY()

ml=MouseDown(1)
mr=MouseDown(2)

If mx<>oldmx Or my<>oldmy
If ml mouseevent=MOUSELDRAG
If mr mouseevent=MOUSERDRAG
EndIf

If ml And (Not oldml) mouseevent=MOUSELCLICK
If mr And (Not oldmr) mouseevent=MOUSERCLICK

If (Not ml) And oldml mouseevent=MOUSELRELEASE
If (Not mr) And oldmr mouseevent=MOUSERRELEASE

If mouseevent
v=mousefocus
If v=Null Or (mouseevent=MOUSELCLICK Or mouseevent=MOUSERCLICK)
v=display.FindView(mx,my)
mousefocus=v
keyboardfocus=v
EndIf
If v
m=New TMessage
m.id=mouseevent
m.MouseX=mx
m.MouseY=my
m.MouseXSpeed=mx-oldmx
m.MouseYSpeed=my-oldmy
m.view=v
v.task.Post m
EndIf
If mouseevent=MOUSELRELEASE Or mouseevent=MOUSERRELEASE
mousefocus=Null
EndIf
EndIf

oldmx=mx;oldmy=my;oldml=ml;oldmr=mr

t=Self
If keyboardfocus t=keyboardfocus.task
If v
While True
c=GetChar()
If c=0 Exit
m=New TMessage
m.id=CHARKEY
m.MouseX=mx
m.MouseY=my
m.CHARKEY=c
t.Post m
Wend
EndIf

m=GetMessage()
While m
DebugLog "message says:"+m.ToString()
If m.id=MOUSELDRAG
m.view.Move(m.MouseXSpeed,m.MouseYSpeed)
EndIf
m=GetMessage()
Wend

For t=EachIn tasklist
t.Update()
Next

If KeyHit(KEY_ESCAPE) shutdown=True

End Method

Method AddTask(t:TTask)
tasklist.addlast t
End Method

Method Run()
While Not shutdown
Update()
display.Draw()
Wend
End Method

Function CreateSystem:TSystem(w,h)
Local s:TSystem
s=New TSystem
s.tasklist=New TList
s.display=TDisplay.CreateDisplay(s,w,h)
Return s
End Function
End Type



System=TSystem.CreateSystem(1024,768)
System.AddTask TBallTask.Create(1,100,100,200,200)

SetBlend ALPHABLEND

System.Run

End

Function Normalize(x#Var,y#Var,z#Var)
Local l#
l=x*x+y*y+z*z
If l
l=1.0/Sqr(l)
x:*l;y:*l;z:*l
EndIf
End Function

Function CreateSphere:TImage(d)
Local image:TImage,pixmap:TPixmap
Local pix[],x,y,r#,f#,a,pf
Local dx#,dy#,dz#,l
Local lx#,ly#,lz#

pf=PF_RGBA8888
pixmap=CreatePixmap(d,d,pf)
pix=New Int[d]
r=0.5*d
lx=0.5;ly=-0.5;lz=1.5;Normalize lx,ly,lz
For y=0 Until d
For x=0 Until d
dx=x+.5-r
dy=y+.5-r
f=dx*dx+dy*dy 'calc 3d vector for point on sphere
dx=dx/r
dy=dy/r
dz=Sqr(1.0-(dx*dx+dy*dy))
l=16+255*(lx*dx+ly*dy+lz*dz) 'calc light from dot product
l=Max(0,l)
l=Min(255,l)
l=l | (l Shl 8) | (l Shl 16)
f=Sqr(f)
a=0
If f<r
a=255*(r-f)
If a>255 a=255
EndIf
pix[x]=(a Shl 24)|l
?MACOS
pix[x]=(a)|(l Shl 8)
?
Next
CopyPixels pix,pixmap.pixelptr(0,y),pf,d
Next
image=LoadImage(pixmap)
Return image
End Function

Function CreateCircle:TImage(d)
Local image:TImage,pixmap:TPixmap
Local pix[],x,y,r#,rr#,f#,a,pf
pf=PF_RGBA8888
pixmap=CreatePixmap(d,d,pf)
pix=New Int[d]
r=0.5*d
rr=r*r
For y=0 Until d
For x=0 Until d
f=Sqr((x+.5-r)*(x+.5-r)+(y+.5-r)*(y+.5-r))
a=0
If f<r
a=255*(r-f)
If a>255 a=255
EndIf
pix[x]=(a Shl 24)|$ffffff
?MACOS
pix[x]=(a)|$ffffff00
?
Next
CopyPixels pix,pixmap.pixelptr(0,y),pf,d
Next
image=LoadImage(pixmap)
Return image
End Function

Type TBall
Field parent:TBallTask
Field sprite:TQuad
Field x#,y#,vx#,vy#

Method Update()
Local w,h
w=parent.view.width-sprite.width
h=parent.view.height-sprite.height
x:+vx
y:+vy
If x<0 x=0;vx=Abs(vx)
If y<0 y=0;vy=Abs(vy)
If x>w x=w;vx=-Abs(vx)
If y>h y=h;vy=-Abs(vy)
sprite.x=x
sprite.y=y
End Method
End Type

Type TBallTask Extends TTask
Field view:TView
Field image:TImage
Field balls:TList

Function Create:TBallTask(n,x,y,w,h)
Local b:TBallTask,i
b=New TBallTask
b.view=System.display.CreateFrameView(b,x,y,w,h)
b.image=CreateSphere(32)
' b.image=CreateCircle(32)
b.balls=New TList
For i=1 To n
b.AddBall()
Next
Return b
End Function

Method AddBall()
Local b:TBall
b=New TBall
b.parent=Self
b.x=Rnd(view.width)
b.y=Rnd(view.height)
b.vx=Rnd(-1.0,1.0)
b.vy=Rnd(-1.0,1.0)
b.sprite=view.CreateSprite(image)
balls.addlast b
End Method

Method Update()
Local b:TBall
Local m:TMessage

m=GetMessage()
While m
m=GetMessage()
Wend

If KeyHit(KEY_F1)
System.AddTask TBallTask.Create(256,100,100,400,300)
EndIf

For b=EachIn balls
b.Update()
Next
End Method
End Type


Comments :


degac(Posted 1+ years ago)

 Thanks very much, inspiring code.This is a 'kernel' of a GUI written in max2d...I think I'll bookmark this 'ancient' piece of code.