Page 1 of 1

SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 5:04 pm
by charvista
Hello :)

CanvasGadget() is still new for me, and would like to use it.
I do not know what to put at the SetGadgetState() so the canvas gadget is updated with the new text.
For images, I know that I need to use ImageID() as second parameter, but there is no CanvasID(), so I am puzzled.

Here an example: (the text of the clock should be cleared, that's where is my problem)

Code: Select all

OpenWindow(0,0,0,300,200,"Clock",#PB_Window_ScreenCentered)

F1=LoadFont(#PB_Any,"Tahoma",8,#PB_Font_Bold)

Can2=CanvasGadget(#PB_Any,0,0,180,30)
StartDrawing(CanvasOutput(Can2))
FillArea(0,0,-1,$46596E)
StopDrawing()

c=0
Repeat
    Text.s=FormatDate("%hh : %ii : %ss",Date())
    StartDrawing(CanvasOutput(Can2))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawingFont(F1)
    DrawText(12+1,8+1,Text.s,$000000); shadows always black
    DrawText(12,8,Text,$FFFFFF)
    StopDrawing()
    SetGadgetState(Can2,0); how to update this? <<<<<<<<<<<<<<
    Delay(50)
    C+1
Until C>=60; about 3 seconds
Thanks.

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 5:31 pm
by Lothar Schirm
According to the PB Help, SetGadgetState cannot be used for a CanvasGadget. Perhaps this is a solution:

Code: Select all

OpenWindow(0,0,0,300,200,"Clock",#PB_Window_ScreenCentered)

F1=LoadFont(#PB_Any,"Tahoma",8,#PB_Font_Bold)

Can2=CanvasGadget(#PB_Any,0,0,180,30)
StartDrawing(CanvasOutput(Can2))
FillArea(0,0,-1,$46596E)
StopDrawing()

c=0
Repeat
    Text.s=FormatDate("%hh : %ii : %ss",Date())
    StartDrawing(CanvasOutput(Can2))
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawingFont(F1)
    Box(0, 0, 180, 30, $46596E)           ; <<<<<<<< delete the contents of the CanvasGadget
    DrawText(12+1,8+1,Text.s,$000000); shadows always black
    DrawText(12,8,Text,$FFFFFF)
    StopDrawing()
    ;SetGadgetState(Can2,0); how to update this? <<<<<<<<<<<<<<  this will not work
    Delay(50)
    C+1
Until C>=60; about 3 seconds

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 5:35 pm
by RASHAD
Graaeh Ya Gedaan :mrgreen:
Too much coffee and no sleep I think

Code: Select all

OpenWindow(0,0,0,300,200,"Clock",#PB_Window_ScreenCentered)

  F1=LoadFont(#PB_Any,"Tahoma",12,#PB_Font_Bold)
  Text.s=FormatDate("%hh : %ii : %ss",Date())
  Can2=CanvasGadget(#PB_Any,0,0,180,30)
  StartDrawing(CanvasOutput(Can2))
  FillArea(0,0,-1,$46596E)
  StopDrawing()
  c=0
Repeat
  Text.s=FormatDate("%hh : %ii : %ss",Date())
  StartDrawing(CanvasOutput(Can2))
  DrawingFont(FontID(F1))
  DrawText(12+1,8+1,Text.s,$000000,$46596E); shadows always black
  DrawingMode(#PB_2DDrawing_Transparent)
  DrawText(12,8,Text,$FFFFFF);,$46596E)
  StopDrawing()
  Delay(50)
  C+1
ForEver
Edit :Updated again

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 5:38 pm
by charvista
Very nice workaround for this case, Lothar! Thank you :D Good point!

However, I am still wondering if there is no way to use SetGadgetState to refresh the contents of the canvas gadget?....

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 5:50 pm
by charvista
Hi RASHAD :mrgreen:
Too much sleep and no coffee at all :mrgreen:
You are a magician, it works without SetGadgetState :shock:
Thank you for revealing your secret :mrgreen:

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 6:08 pm
by RASHAD
Hi charvista
Updated again for DrawingFont(FontID(F1))

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 6:17 pm
by charvista
Thank you again my friend! I also noticed that the shadow was no longer there.
You edited the code before I had the chance to complain! :D

Conclusion:
- if the canvas gadget has an image as background, we must use SetGadgetState(#Gadget,ImageID(#Image)) to update the gadget.
- if the canvas gadget has plain color, do as RASHAD did.

Excellent.

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 9:57 pm
by STARGÅTE
this is a wrong way zu upate the gadget, you need a WindowEvent(), else freeze the window!

here a right way:

Code: Select all

OpenWindow(0,0,0,300,200,"Clock",#PB_Window_ScreenCentered)

F1=LoadFont(#PB_Any,"Tahoma",8,#PB_Font_Bold)

Can2=CanvasGadget(#PB_Any,0,0,180,30)

AddWindowTimer(0, 1, 50)

Repeat
	Select WaitWindowEvent()
		Case #PB_Event_Timer
			Text.s=FormatDate("%hh : %ii : %ss",Date())
			If StartDrawing(CanvasOutput(Can2))
				Box(0,0,OutputWidth(), OutputHeight(),$46596E)
				DrawingMode(#PB_2DDrawing_Transparent)
				DrawingFont(F1)
				DrawText(12+1,8+1,Text.s,$000000); shadows always black
				DrawText(12,8,Text,$FFFFFF)
				StopDrawing()
			EndIf
	EndSelect
ForEver

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 10:52 pm
by charvista
you need a WindowEvent(), else freeze the window!
Stargåte,
You are correct. I tried the code from Rashad again, and when I want to move the window with the mouse, it hangs. Sorry Rashad...
With your code, when we move the window, the clock is suspended, and continues when the user has released the mouse. Yup, Windows is like a cat we hold above his neck :mrgreen:
The truth is, in my program, the clock would run in a thread, so I think it would never need a WindowEvent(). Or am I wrong here too?

And you changed as well the Delay(50) to a AddWindowTimer(0,1,50). Is it better? Is it the same as WaitWindowEvent(50)?

Cheers!

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 11:27 pm
by STARGÅTE
Delay(50) stop the program for 50ms, not good.

AddWindowTimer() is the safe way, to run a code all 50ms.
With a Thread you can use Delay(50) and it looks like this one:

Enable: Compiler: Thread-Safe!

Code: Select all

OpenWindow(0,0,0,300,200,"Clock",#PB_Window_ScreenCentered)

Global F1=LoadFont(#PB_Any,"Tahoma",8,#PB_Font_Bold)

Can2=CanvasGadget(#PB_Any,0,0,180,30)

Procedure Update(Gadget)
	Protected Text.s
	Repeat
		Text = FormatDate("%hh : %ii : %ss",Date())
		If StartDrawing(CanvasOutput(Gadget))
			Box(0,0,OutputWidth(), OutputHeight(),$46596E)
			DrawingMode(#PB_2DDrawing_Transparent)
			DrawingFont(F1)
			DrawText(12+1,8+1,Text.s,$000000)
			DrawText(12,8,Text,$FFFFFF)
			StopDrawing()
		EndIf
		Delay(50)
	ForEver
EndProcedure

CreateThread(@Update(), Can2)

Repeat
   Select WaitWindowEvent()
      Case #PB_Event_CloseWindow
         End
   EndSelect
ForEver
then you can move the window and update runs

Re: SetGadgetState problem with CanvasGadget

Posted: Mon Mar 18, 2013 11:58 pm
by charvista
Super.
Thread is really a good invention.
Runs fine, window can be moved safely and clock continues to run, no hang-up and nothing can stop the time :o
Thanks Stargåte for your time, I have documented it so I hope to always remember.
Live long and prosper!

Re: SetGadgetState problem with CanvasGadget

Posted: Tue Mar 19, 2013 11:17 am
by Joris
What is the difference between the PB-Timer AddWindowTimer(0, 1, 50) and the windows api-timer (timeGetDevCaps etc.) ?
They look (act) quit the same imo, as they both seem to create a thread no ?
If the same, AddWindowTimer is always the best solution here, imo.