Page 1 of 1
SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 7:16 pm
by droadje
Hi Purebasic,
Busy with a guitar fretboard learning ap, how can i set the text in a button for 1 seccond?
Code: Select all
Procedure Button1_0(EventType)
If GetGadgetText(Button1_0) = ""
SetGadgetText(Button1_0, "E")
Delay(1000)
SetGadgetText(Button1_0, "")
Else
SetGadgetText(Button1_0, "")
EndIf
EndProcedure
Tried (see code) with Delay(1000) and then SetGadgetText(Button1_0, "") but then the eventloop gets sloppy.
What i want is, if i press the button, the letter E is displayed for 1 second in the button and then automaticaly empties it, or click again and the E is removed...
Is there a way to start a procedure outside the eventloop?
Thanks in advance....
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 7:46 pm
by RASHAD
Delay() stops the execution completely
Use AddWindowTimer() and #PB_Event_Timer to calculate the ElapsedMilliseconds()
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 8:10 pm
by TI-994A
droadje wrote:What i want is, if i press the button, the letter E is displayed for 1 second in the button and then automaticaly empties it, or click again and the E is removed...
This does the trick, but like RASHAD mentioned, a timer solution would be better:
Code: Select all
#buttonEvent = #PB_Event_FirstCustomValue
Procedure ButtonEvent()
caption$ = ""
If EventData() > 0
button = EventData()
Else
button = EventGadget()
EndIf
If GetGadgetText(button) = ""
Select button
Case 1
caption$ = "A"
Case 2
caption$ = "B"
Case 3
caption$ = "C"
EndSelect
EndIf
SetGadgetText(button, caption$)
If caption$ <> ""
Delay(1000)
PostEvent(#buttonEvent, 0, 0, 0, button)
EndIf
EndProcedure
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(0, #PB_Ignore, #PB_Ignore, 190, 200, "Delay Event", wFlags)
ButtonGadget(1, 10, 10, 50, 90, "")
ButtonGadget(2, 70, 10, 50, 90, "")
ButtonGadget(3, 130, 10, 50, 90, "")
BindGadgetEvent(1, @ButtonEvent())
BindGadgetEvent(2, @ButtonEvent())
BindGadgetEvent(3, @ButtonEvent())
BindEvent(#buttonEvent, @ButtonEvent())
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 8:32 pm
by droadje
thanks for the quick respond.
I tried TI-994A solution, but get the same result i already had. Perhaps because i am on Linux, will try Windows later. (hangs for 1 second with black background, not text)
So i have to learn the method Rashad has given.
Perhaps i should start smaller, because i now have a guitar fretboard made with 6 rows of 12 pushbuttons and 7 checkboxes, thats a lot of procedures and events......lol
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 8:35 pm
by Jagermeister
Code: Select all
;======================================
;WHO: JAGERMEISTER
;WHAT: SAMPLE CODE
;WHEN: 2019 03 28
;WHERE: https://www.purebasic.fr/english/viewtopic.php?f=13&t=72540
;COPYRIGHT: FOSS - FREE TO USE, MODIFY, DISTRIBUTE
;======================================
;-ENUMERATIONS
Enumeration
#window_main
#button
#font_segoe_32_b
EndEnumeration
;-FONTS
LoadFont(#font_segoe_32_b , "segoe ui" , 32 , #PB_Font_Bold)
;-PROCEDURES
Procedure button_press(x)
SetGadgetText(#button , "E")
Delay(1000)
SetGadgetText(#button, "")
EndProcedure
;-WINDOW
OpenWindow(#window_main , 0 , 0 , 200 , 100 , "Temporary Button Text Example" , #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
pad = 8 ; My favored UI padding value
ButtonGadget(#button , pad , pad , WindowWidth(window) - (pad * 2) , WindowHeight(window) - (pad * 2) , "")
SetGadgetFont(#button , FontID(#font_segoe_32_b))
;-LOOP
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_Gadget
Select EventGadget()
Case #button
If Not IsThread(thread)
thread = CreateThread(@button_press() , 0)
Else
Debug "Thread already running"
EndIf
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow
End
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 8:39 pm
by droadje
thanks, that did the trick.
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 8:49 pm
by droadje
In my program it works now also, like this:
Code: Select all
; Snaar 1 ***********************************************
Procedure Button1_0(EventType)
If GetGadgetText(Button1_0) = ""
SetGadgetText(Button1_0, "E")
CreateThread(@empty(), Button1_0)
Else
SetGadgetText(Button1_0, "")
EndIf
EndProcedure
Procedure empty(String1)
Delay(1000)
SetGadgetText(String1, "")
EndProcedure
Thanks very much!
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 8:54 pm
by mk-soft
Threads and GUI not work under Linux and macOS...
But i have a Idee...
Code: Select all
;-TOP
; Comment : DoIt Later
; Author : mk-soft
; Version : v0.02
; Create : 27.03.2019
; OS : All
Enumeration
#SetGadgetText
#SetGadgetState
#SetGadgetColor
EndEnumeration
Structure udtDoItLater
Command.i
Gadget.i
Text.s
Param.i
Param2.i
Time.i
Start.i
EndStructure
Global NewList DoItLater.udtDoItLater()
Global MutexDoItLater = CreateMutex()
Procedure SetGadgetTextDelay(Gadget, Text.s, Time)
LockMutex(MutexDoItLater)
LastElement(DoItLater())
AddElement(DoItLater())
With DoItLater()
\Command = #SetGadgetText
\Gadget = Gadget
\Text = Text
\Time = Time
\Start = ElapsedMilliseconds()
EndWith
UnlockMutex(MutexDoItLater)
EndProcedure
Procedure SetGadgetStateDelay(Gadget, State, Time)
LockMutex(MutexDoItLater)
LastElement(DoItLater())
AddElement(DoItLater())
With DoItLater()
\Command = #SetGadgetState
\Gadget = Gadget
\Param = State
\Time = Time
\Start = ElapsedMilliseconds()
EndWith
UnlockMutex(MutexDoItLater)
EndProcedure
Procedure SetGadgetColorDelay(Gadget, ColorType, Color, Time)
LockMutex(MutexDoItLater)
LastElement(DoItLater())
AddElement(DoItLater())
With DoItLater()
\Command = #SetGadgetColor
\Gadget = Gadget
\Param = ColorType
\Param2 = Color
\Time = Time
\Start = ElapsedMilliseconds()
EndWith
UnlockMutex(MutexDoItLater)
EndProcedure
Procedure DoEventDoItLater()
Protected Time = ElapsedMilliseconds()
With DoItLater()
LockMutex(MutexDoItLater)
ForEach DoItLater()
If (Time - \Start) >= \Time
If IsGadget(\Gadget)
Select \Command
Case #SetGadgetText
SetGadgetText(\Gadget, \Text)
Case #SetGadgetState
SetGadgetState(\Gadget, \Param)
Case #SetGadgetColor
SetGadgetColor(\Gadget, \Param, \Param2)
EndSelect
EndIf
DeleteElement(DoItLater(), 1)
EndIf
Next
UnlockMutex(MutexDoItLater)
EndWith
EndProcedure
;- Example
Procedure Main()
Protected event, index, x, y
If OpenWindow(0 , #PB_Ignore, #PB_Ignore, 620, 80, "Do It Later", #PB_Window_SystemMenu)
x = 10
y = 10
For index = 0 To 9
ButtonGadget(index, x, y, 55, 25, "---")
x + 60
Next
StringGadget(10, 10, 45, 120, 25, "")
BindEvent(#PB_Event_Timer, @DoEventDoItLater(), 0, 999)
AddWindowTimer(0, 999, 50)
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_CloseWindow
Break
Case #PB_Event_Gadget
index = EventGadget()
Select index
Case 0 To 9
SetGadgetText(index, "-" + index + "-")
SetGadgetTextDelay(index, "---", 800)
Case 10
If EventType() = #PB_EventType_Focus
SetGadgetColor(10, #PB_Gadget_BackColor, #Red)
SetGadgetColorDelay(10, #PB_Gadget_BackColor, #PB_Default, 150)
EndIf
EndSelect
EndSelect
ForEver
EndIf
EndProcedure : Main()
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 8:56 pm
by TI-994A
This one uses the timer, and works on Linux as well:
Code: Select all
Procedure ButtonTimerEvent()
For button = 1 To 3
buttonDown = GetGadgetData(button)
If buttonDown > 0
If (ElapsedMilliseconds() - buttonDown) > 1000
SetGadgetData(button, 0)
SetGadgetText(button, "")
EndIf
EndIf
Next button
EndProcedure
Procedure ButtonEvent()
caption$ = ""
button = EventGadget()
If GetGadgetText(button) = ""
Select button
Case 1
caption$ = "A"
Case 2
caption$ = "B"
Case 3
caption$ = "C"
EndSelect
EndIf
SetGadgetText(button, caption$)
SetGadgetData(button, ElapsedMilliseconds())
EndProcedure
wFlags = #PB_Window_SystemMenu | #PB_Window_ScreenCentered
OpenWindow(0, #PB_Ignore, #PB_Ignore, 190, 200, "Delay Event", wFlags)
AddWindowTimer(0, 0, 100)
ButtonGadget(1, 10, 10, 50, 90, "")
ButtonGadget(2, 70, 10, 50, 90, "")
ButtonGadget(3, 130, 10, 50, 90, "")
BindGadgetEvent(1, @ButtonEvent())
BindGadgetEvent(2, @ButtonEvent())
BindGadgetEvent(3, @ButtonEvent())
BindEvent(#PB_Event_Timer, @ButtonTimerEvent())
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 9:05 pm
by #NULL
Code: Select all
win = OpenWindow(#PB_Any, 50,100, 100, 50, "title")
AddKeyboardShortcut(win, #PB_Shortcut_Escape, 10)
button = ButtonGadget(#PB_Any, 10, 10, 80, 30, "button")
Repeat
WaitWindowEvent()
If Event() = #PB_Event_Gadget
If EventGadget() = button
SetGadgetText(button, "clicked")
AddWindowTimer(win, 123, 1000)
EndIf
ElseIf Event() = #PB_Event_Timer
If EventTimer() = 123
SetGadgetText(button, "button")
RemoveWindowTimer(win, 123)
EndIf
EndIf
Until Event() = #PB_Event_CloseWindow Or Event() = #PB_Event_Menu
<edit>
I forgot RemoveWindowTimer()
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 9:12 pm
by droadje
Ha, boys, thanks, all your code works and looks like it does the same thing.
And threads and gui DO seem to work on my Manajaro Linux
Plenty to learn now from the code you have given, thanks.
Re: SetGadgetText for 1 second, howto?
Posted: Thu Mar 28, 2019 9:22 pm
by mk-soft
droadje wrote:
And threads and gui DO seem to work on my Manajaro Linux
Is not running stable... Show my Link to ThreadToGUI