Drawing on a Window

BlitzPlus Forums/BlitzPlus Programming/Drawing on a Window

Mental Image(Posted 2004) [#1]
Is it possible some way to use drawing comands on a window? I mean so that you can put lines/boxes/separators etc around groups of gadgets etc?

The window must be treated as some form of canvas internally, as $201 events work when clicking on a blank area of a window.....

Thanks.


Mental Image(Posted 2004) [#2]
Just thought that I could do this by having a canvas 1 pixel wide (or 1 pixel high depending on orientation), and filling it with black, but is this too much of a kludge?


soja(Posted 2004) [#3]
That would work fine (as the "Blitz" way). You could then color each canvas however you wanted.

Another way might be to use Windows' GDI, though this would be harder and perhaps use a bit more CPU (since you'd probably have to redraw every frame or so).

I've done both and they both work.


Kevin_(Posted 2004) [#4]
It would be great if you could draw to a panel as that will solve your problem. I cannot see why this hasnt been implemented yet because you can actually load an image into a panel.


CS_TBL(Posted 2004) [#5]
You can make your own command using a bank, this really works and is a great way to expand your blitz+ commandset.

MyDivider=CreateLine(x,y,length,direction,r,g,b,parent)

What you do inside the function CreateLine is defining a bank of a certain size, and put all the arguements in here. In the end you return the bank handle. Also, you create a canvas here, the size of the arguements, and fill it with a solid color (see the R,G,B, arguements) So, in this example MyDivider will have some 224633423"blah".. adress which is the bankhandle.

Next you edit some .decl file with your own custom functions, and at it... bingo.. your own new fresh command!

Ofcourse, for a simple line, you wouldn't even need to do banks with all scary stuff, but it's good exercise for the more complex work. And if you make additional functions you can have access to the arguements of your line.. (that's why you store that stuff in a bank!)

With exactly this method I created my own supercool-button, which uses images for everything. You can press it, you have dedicated gfx when moving your mouse over it.. (also see the 'tool palette' from photoshop to see what I mean). Even better.. the buttons are placed in a group automatically, so creating a grid of 8x2 buttons is peanuts.. and if you didn't add a button to this grid at a certain position, then you see a background image or color.
The only thing that makes it different compared to the rest of the gadgets is that I need my own eventcheck stuff, and that things like SetGadgetText etc. don't work with my buttons.
Again, add it to a decl file and this command looks and feels like any other B+ command! (no ugly TYPEs needed too.. I hate blitz-types! :)

All the current button-stuff is ~ 450 lines of code, including error-checks/notifications ..

However, no more bragging here :), it's just to give an impression what you can do with banks if you've the feeling that you miss a special gadget. And really, the joy you can have when working with your own advanced tailor-made gadgets is great. It speeds-up development with lightyears!


Mental Image(Posted 2004) [#6]
Weeeellll........

some source for CReateLine would be nice (and welcome!).

Pretty please?


CS_TBL(Posted 2004) [#7]
Ok, I spend some hour or so on this thingy.. I think it's way more than you ever need, but it's here anyway.

The only thing you need to do is copy/paste the CreateLine function and the 3 small functions at the bottom to some include file and there you go! That's all folks..

Notice that I don't read out personal windows GUI colors. (too lazy :)

Have fun!

; Line Gadget v1.0
;
; by CS^TBL  -  March 2004
;
; CreateLine(x, y, length, direction, thickness, parent, [contrast#], [r], [g],[b])
;
; default values: contrast#		1.2		(range 0..2)       (1=no relief, 0 and 2 = opposite maximum relief)
;                 r 			192 	(range 0..255)
;                 g 			192 	(range 0..255)
;                 b 			192 	(range 0..255)

app=CreateWindow("line gadget",0,0,640,480)

MyLine1=CreateLine(32,32,128,1,2,app,1.2,192,192,192)
MyLine2=CreateLine(40,32,160,0,3,app,0.8)


; ------------------------------------------------------------------------------
; examples:

; read out the line lengths
Notify GetLineLength(MyLine1)
Notify GetLineLength(MyLine2)

; read out a canvas from a line and make it red
c=GetLineCanvas(MyLine1)
SetBuffer CanvasBuffer(c)
	ClsColor 255,0,0:Cls
FlipCanvas c


; ------------------------------------------------------------------------------
; main loop
quit=False
Repeat
	WaitEvent()
	If EventID()=$803 quit=True
Until quit

; and clean up your mess again..
FreeBank MyLine1
FreeBank MyLine2
FreeGadget app

End ; bye!



; ------------------------------------------------------------------------------
; typical examples to read a property from the line gadget
;
; notice that the only check is whether it 'is' a bank.. it doesn't check whether it's the correct bank!
; if you read out the wrong bank (esp. non-line 'gadgets' :) then really odd things might happen..
; If the bank is not big enough then it'll crash probably :)
; 
; you can solve this by expanding the whole bank structure with 4 bytes, move all data 4 bytes forward,
; and use the first 4 bytes to add an ID .. "Line" or something, in each Get or Set function you should check
; on this ID, if it doesn't match, then use the Break command .
;
; also, you might want to split the CreateLine function in a DefineLine and DrawLine function, since you might have
; to draw to the canvas again. (for example when you make typical 'Set' functions!)
;
; For beginners, this function should be enough anyway, and it's prolly overkill already :)

Function GetLineLength(bank)
	If bank
		Return PeekShort (bank,08)
	EndIf
	Break"Bank error"
End Function

Function GetLineCanvas(bank)
	If bank
		Return PeekInt (bank,00)
	EndIf
	Break"Bank error"
End Function

; ------------------------------------------------------------------------------
; the actual function..

Function CreateLine(x,y,length,direction,thickness,parent,contrast#=1.2,r=192,g=192,b=192)

	; 00	canvas			int (4 bytes)
	; 04	x				short (2 bytes)
	; 06	y				short (2 bytes)
	; 08	length			short (2 bytes)
	; 10	direction		byte (1 byte)
	; 11	thickness		byte (1 byte)
	; 12	parent			int (4 bytes)
	; 16	contrast		float (8 bytes)
	; 24	r				byte (1 byte)
	; 25	g				byte (1 byte)
	; 26	b				byte (1 byte)


;	checks:

	If Not parent Break"Wrong parent!"

	If Not thickness Break"Thickness must be larger than 0"

	If direction<0
		direction=0
		Notify"Warning: direction must be 0 or 1, value is clipped"
	EndIf

	If direction>1
		direction=1
		Notify"Warning: direction must be 0 or 1, value is clipped"
	EndIf
	
	r=Limit(r,0,255)
	g=Limit(g,0,255)
	b=Limit(b,0,255)

; 	create:
	
	bank=CreateBank(27)
	
	If direction=0 ; horizontal
		canvas=CreateCanvas(x,y,length,thickness,parent)
	Else ; vertical
		canvas=CreateCanvas(x,y,thickness,length,parent)
	EndIf

	SetBuffer CanvasBuffer(canvas)
	
		ClsColor r,g,b:Cls
		
		r1#=r*contrast#
		r2#=r*(1-(contrast#-1))
		
		g1#=g*contrast#
		g2#=g*(1-(contrast#-1))
		
		b1#=b*contrast#
		b2#=b*(1-(contrast#-1))
		

		r1#=LimitF(r1#,0,255) 		
		g1#=LimitF(g1#,0,255) 		
		b1#=LimitF(b1#,0,255) 		
		r2#=LimitF(r2#,0,255) 		
		g2#=LimitF(g2#,0,255) 		
		b2#=LimitF(b2#,0,255) 		

		; notice: if the thickness is 1 then it's obvious that only the '2nd' line will be shown!
		If direction=0
			Color r1#,g1#,b1#
			Line 0,0,length,0
			Color r2#,g2#,b2#
			Line 0,thickness-1,length-1,thickness-1
		Else
			Color r1#,g1#,b1#
			Line 0,0,0,length
			Color r2#,g2#,b2#
			Line thickness-1,0,thickness-1,length-1
		EndIf
		
	FlipCanvas canvas
	
; poke stuff in the bank

	PokeInt bank,00,canvas
	PokeShort bank,04,x
	PokeShort bank,06,y
	PokeShort bank,08,length
	PokeByte bank,10,direction
	PokeByte bank,11,thickness
	PokeInt bank,12,parent
	PokeFloat bank,16,contrast#
	PokeByte bank,24,r
	PokeByte bank,25,g
	PokeByte bank,26,b
	
; return the bankhandle	

	Return bank

End Function ; byebye!

; ------------------------------------------------------------------------------
; Additional handy stuff for the lazy coder :)
;
; TIP:
; add these lines to your usual .decls file
;
; CreateLine(x,y,length,direction,thickness,parent,contrast#,r,g,b)
; Limit(value,Min,Max)
; LimitF(value#,Min#,Max#)
; Break(msg$)
;
; additionally you could add the Get commands, but I don't think you'll ever need them..



Function Limit(value,minvalue,maxvalue)
	If value<minvalue Return minvalue
	If value>maxvalue Return maxvalue
	Return value
End Function

Function LimitF(value#,minvalue#,maxvalue#)
	If value#<minvalue# Return minvalue#
	If value#>maxvalue# Return maxvalue#
	Return value#
End Function

Function Break(s$)
	Notify s$
	End
End Function



Mental Image(Posted 2004) [#8]
Thank you. I will be having a play tomorrow and let you know how I get on.

As I have said before...... "I LOVE this place!"

Thanks again, CS_TBL