Page 1 of 2
TimeSpin Gadget - Is there a better/easier way
Posted: Tue Jul 08, 2008 1:54 am
by Perkin
I would like a TimeSpin gadget, but with Hours/Mins/Secs/Centis
I've created the following program, utilising 4 spin gadgets, however I would like to know if there is an better/easier way, or an all-in-one gagdet that does what I want
Here's the code
Code: Select all
;TimeSpin Gadget Test - I Need Hours:Mins:Secs:Centis
#SP_Hours=1
#SP_Mins=2
#SP_Secs=3
#SP_Centis=4
Procedure UpdateHours()
valh.w = GetGadgetState(#SP_Hours)
If valh=-1
valh=11
EndIf
If valh=12
valh=0
EndIf
SetGadgetState(#SP_Hours,valh)
SetGadgetText(#SP_Hours,RSet(Str(valh),2,"0"))
EndProcedure
Procedure UpdateMinutes()
valm.w = GetGadgetState(#SP_Mins)
If valm=-1
valm=059
SetGadgetState(#SP_Hours,GetGadgetState(#SP_Hours)-1)
UpdateHours()
EndIf
If valm=60
valm=0
SetGadgetState(#SP_Hours,GetGadgetState(#SP_Hours)+1)
UpdateHours()
EndIf
SetGadgetState(#SP_Mins,valm)
SetGadgetText(#SP_Mins,RSet(Str(valm),2,"0"))
EndProcedure
Procedure UpdateSeconds()
vals.w = GetGadgetState(#SP_Secs)
If vals=-1
vals=059
SetGadgetState(#SP_Mins,GetGadgetState(#SP_Mins)-1)
UpdateMinutes()
EndIf
If vals=60
vals=0
SetGadgetState(#SP_Mins,GetGadgetState(#SP_Mins)+1)
UpdateMinutes()
EndIf
SetGadgetState(#SP_Secs,vals)
SetGadgetText(#SP_Secs,RSet(Str(vals),2,"0"))
EndProcedure
Procedure UpdateCentis()
valc.w = GetGadgetState(#SP_Centis)
If valc=-1
valc=099
SetGadgetState(#SP_Secs,GetGadgetState(#SP_Secs)-1)
UpdateSeconds()
EndIf
If valc=100
valc=0
SetGadgetState(#SP_Secs,GetGadgetState(#SP_Secs)+1)
UpdateSeconds()
EndIf
SetGadgetState(#SP_Centis,valc)
SetGadgetText(#SP_Centis,RSet(Str(valc),2,"0"))
EndProcedure
If OpenWindow(0, 0, 0, 200, 70, "TimeSpin Gadget Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
SpinGadget(#SP_Hours, 20, 20, 30, 20, -1, 12, #PB_Spin_ReadOnly | #PB_Spin_Numeric)
SetGadgetState (#SP_Hours, 0)
SetGadgetText(#SP_Hours, "00")
SpinGadget(#SP_Mins, 60, 20, 30, 20, -1, 60, #PB_Spin_ReadOnly | #PB_Spin_Numeric)
SetGadgetState (#SP_Mins, 0)
SetGadgetText(#SP_Mins, "00")
SpinGadget(#SP_Secs, 100, 20, 30, 20, -1, 60, #PB_Spin_ReadOnly | #PB_Spin_Numeric)
SetGadgetState (#SP_Secs, 0)
SetGadgetText(#SP_Secs, "00")
SpinGadget(#SP_Centis, 140, 20, 30, 20, -1, 100, #PB_Spin_ReadOnly | #PB_Spin_Numeric)
SetGadgetState (#SP_Centis, 0)
SetGadgetText(#SP_Centis, "00")
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget
Select EventGadget()
Case #SP_Hours
UpdateHours()
Case #SP_Mins
UpdateMinutes()
Case #SP_Secs
UpdateSeconds()
Case #SP_Centis
UpdateCentis()
EndSelect
EndIf
Until event = #PB_Event_CloseWindow
EndIf
I'm also going to add the required seperators, and info etc, but you only need the above to see what I would like.
Any thoughts?
Posted: Tue Jul 08, 2008 3:25 am
by Ollivier
Is good?
Code: Select all
;TimeSpin Gadget Test - I Need Hours:Mins:Secs:Centis
Enumeration
#SP_Hours=1
#SP_Mins
#SP_Secs
#SP_Centis
EndEnumeration
Global Dim SP_Max(4)
SP_Max(1) = 11
SP_Max(2) = 59
SP_Max(3) = 59
SP_Max(4) = 99
Procedure UpDate(Object.L)
Protected Change.L
Value.W = GetGadgetState(Object)
If Value < 0
Value + (SP_Max(Object) + 1): Change = -1
EndIf
If Value > SP_Max(Object)
Value - (SP_Max(Object) + 1): Change = 1
EndIf
SetGadgetState(Object, Value)
SetGadgetText(Object, RSet(Str(Value), 2, "0") )
If Change And Object > #SP_Hours
SetGadgetState(Object - 1, GetGadgetState(Object - 1) + Change)
UpDate(Object - 1)
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 200, 70, "TimeSpin Gadget Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
For i = #SP_Hours To #SP_Hours + 3
SpinGadget(i, 20 + 40 * (i - #SP_Hours), 20, 30, 20, -1, SP_Max(i) + 1, #PB_Spin_ReadOnly | #PB_Spin_Numeric)
SetGadgetState (i, 0)
SetGadgetText(i, "00")
Next
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget
UpDate(EventGadget() )
EndIf
Until event = #PB_Event_CloseWindow
EndIf
Posted: Tue Jul 08, 2008 9:10 am
by Perkin
That does what I want

, but I would, if possible, have just one gadget which does the same thing, rather than using the four gadgets (as I am going to need four of these on a panel - 16 spin gadgets in all, I'd rather have just four of the combined gadgets).
Is there a Single gadget (or a modified one)which can do what is required.
Posted: Tue Jul 08, 2008 10:18 am
by gnozal
With a dategadget you get hours / minutes / seconds, but no milliseconds.
Code: Select all
Enumeration
#Window_0
EndEnumeration
Enumeration
#Window_0_Date_0
EndEnumeration
Define.l Event, EventWindow, EventGadget, EventType, EventMenu
Procedure OpenWindow_Window_0()
If OpenWindow(#Window_0, 450, 200, 400, 400, "Window_0", #PB_Window_SystemMenu|#PB_Window_SizeGadget|#PB_Window_MinimizeGadget|#PB_Window_TitleBar)
If CreateGadgetList(WindowID(#Window_0))
; DateGadget(#Window_0_Date_0, 110, 40, 110, 25, "%hh:%ii:%ss", Date(), #PB_Date_UpDown) ; -> no seconds !?
DateGadget(#Window_0_Date_0, 110, 40, 110, 25, "", Date(), #PB_Date_UpDown)
SetWindowLong_(GadgetID(#Window_0_Date_0), #GWL_STYLE, GetWindowLong_(GadgetID(#Window_0_Date_0), #GWL_STYLE) | #DTS_TIMEFORMAT)
EndIf
EndIf
EndProcedure
OpenWindow_Window_0()
Repeat
Event = WaitWindowEvent()
Select Event
Case #PB_Event_CloseWindow
EventWindow = EventWindow()
If EventWindow = #Window_0
CloseWindow(#Window_0)
Break
EndIf
EndSelect
ForEver
Posted: Tue Jul 08, 2008 11:30 am
by Perkin
gnozal - I've seen the dategadget, however do require the milliseconds units as well, that's why I'm looking for a modified/custom gadget.
I've got a couple of routines which convert hh:mm:ss:cc (string) into millis(long) and back again, but would like a gadget allowing easy altering of time (including the millisecs)
Posted: Tue Jul 08, 2008 2:57 pm
by Foz
Posted: Tue Jul 08, 2008 3:56 pm
by Ollivier
There is no lots of changes to do to have the 16 gadgets. PerkinRef contains the No of the first gadget if you don't want they start at #0
Code: Select all
; TimeSpin Gadget Test - I Need Hours:Mins:Secs:Centis
Enumeration
#SP_Hours
#SP_Mins
#SP_Secs
#SP_Centis
EndEnumeration
Structure OBJECT
Type.L
EndStructure
Global Dim SP_Max(3)
Global Dim Object.OBJECT(15)
Global PerkinRef.L
PerkinRef = 0 ; Gadget numero start at #0 (Here, it finish at #0 + 15 = #15)
SP_Max(0) = 11
SP_Max(1) = 59
SP_Max(2) = 59
SP_Max(3) = 99
Procedure UpDate(Object.L)
If Object => PerkinRef And Object <= PerkinRef + 15
ObjectType = (Object - PerkinRef) & 3
EndIf
Protected Change.L
Value.W = GetGadgetState(Object)
If Value < 0
Value + (SP_Max(ObjectType) + 1): Change = -1
EndIf
If Value > SP_Max(ObjectType)
Value - (SP_Max(ObjectType) + 1): Change = 1
EndIf
SetGadgetState(Object, Value)
SetGadgetText(Object, RSet(Str(Value), 2, "0") )
If Change And ObjectType <> #SP_Hours
SetGadgetState(Object - 1, GetGadgetState(Object - 1) + Change)
UpDate(Object - 1)
EndIf
EndProcedure
If OpenWindow(0, 0, 0, 200, 150, "TimeSpin Gadget Test", #PB_Window_SystemMenu | #PB_Window_ScreenCentered) And CreateGadgetList(WindowID(0))
PerkinRef = 0
For j = 0 To 3
Base = PerkinRef + j << 2
For i = 0 To 3
SpinGadget(Base + i, 20 + 40 * i, 20 + 32 * j, 30, 20, -1, SP_Max(i) + 1, #PB_Spin_ReadOnly | #PB_Spin_Numeric)
Object(Base + i)\Type = i
SetGadgetState (Base + i, 0)
SetGadgetText(Base + i, "00")
Next
Next
Repeat
event = WaitWindowEvent()
If event = #PB_Event_Gadget
UpDate(EventGadget() )
EndIf
Until event = #PB_Event_CloseWindow
EndIf
Posted: Tue Jul 08, 2008 4:37 pm
by dhouston
Perkin wrote:gnozal - I've seen the dategadget, however do require the milliseconds units as well, that's why I'm looking for a modified/custom gadget.
Some months back I made a feature request for a general purpose multi-field spin control (like the date gadget) but there was no response. As I recall, my need was for longitude latitude, time zone with 2 fields each.
Posted: Tue Jul 08, 2008 4:56 pm
by Perkin
Thanks to all
Foz - looked at topic, couldn't get my head round it
I'll re-read it and try some experiments when I get some time.
Ollivier - I'll be using this till I can sort out something better (i.e. One gadget each not the set of four)
dhouston - saw that topic whilst searching for help over this, it looked to have been answered, maybe re-requesting help again - bump the topic.
Any other ideas?
Posted: Tue Jul 08, 2008 10:51 pm
by Foz
Enjoy!
Code: Select all
EnableExplicit
;{- private variables
Global __TimerSpinGadget_TotalNumber.l
Global Dim __TimerSpinGadget_spnControl.l(3, 0)
Global Dim __TimerSpinGadget_SP_Max(3)
__TimerSpinGadget_SP_Max(0) = 23
__TimerSpinGadget_SP_Max(1) = 59
__TimerSpinGadget_SP_Max(2) = 59
__TimerSpinGadget_SP_Max(3) = 99
;}
;{- private procedures
Procedure __TimerSpinGadget_Update(pTimerSpinControlID.l, pSpinGadgetID.l)
Protected Change.L
Protected Value.W = GetGadgetState(__TimerSpinGadget_spnControl(pTimerSpinControlID, pSpinGadgetID))
If Value<0
Value + (__TimerSpinGadget_SP_Max(pTimerSpinControlID) + 1) : Change = -1
EndIf
Protected MaxValue.l = GetGadgetAttribute(__TimerSpinGadget_spnControl(pTimerSpinControlID, pSpinGadgetID), #PB_Spin_Maximum)-1
If Value>__TimerSpinGadget_SP_Max(pTimerSpinControlID)
Value-(__TimerSpinGadget_SP_Max(pTimerSpinControlID) + 1) : Change = 1
EndIf
SetGadgetState(__TimerSpinGadget_spnControl(pTimerSpinControlID, pSpinGadgetID), Value)
SetGadgetText(__TimerSpinGadget_spnControl(pTimerSpinControlID, pSpinGadgetID), RSet(Str(Value), 2, "0") )
If Change And pTimerSpinControlID>0
SetGadgetState(__TimerSpinGadget_spnControl(pTimerSpinControlID-1, pSpinGadgetID), GetGadgetState(__TimerSpinGadget_spnControl(pTimerSpinControlID-1, pSpinGadgetID)) + Change)
__TimerSpinGadget_Update(pTimerSpinControlID-1, pSpinGadgetID)
EndIf
EndProcedure
;}
;{ public procedures
Procedure TimerSpinGadget_SetNumberOfInstances(pCount.l)
__TimerSpinGadget_TotalNumber = pCount-1
ReDim __TimerSpinGadget_spnControl(3, __TimerSpinGadget_TotalNumber)
EndProcedure
Procedure TimerSpinGadget_New(pGadgetArea.l, pOffsetX.l, pOffsetY.l, pInstanceNumber.l = 0)
UseGadgetList(pGadgetArea)
Protected i.l
For i = 0 To 3
__TimerSpinGadget_spnControl(i, pInstanceNumber) = SpinGadget(#PB_Any, pOffsetX + 32*(i), pOffsetY, 30, 20, -1, __TimerSpinGadget_SP_Max(i) + 1, #PB_Spin_ReadOnly | #PB_Spin_Numeric)
SetGadgetState(__TimerSpinGadget_spnControl(i, pInstanceNumber), 0)
SetGadgetText(__TimerSpinGadget_spnControl(i, pInstanceNumber), "00")
Next
EndProcedure
Procedure TimerSpinGadget_Release()
Protected i.l, j.l
For j = 0 To __TimerSpinGadget_TotalNumber
For i = 0 To 3
FreeGadget(__TimerSpinGadget_spnControl(i, j))
Next
Next
EndProcedure
Procedure TimerSpinGadget_Event(Event.l, WindowID.l, GadgetID.l, EventType.l)
If event = #PB_Event_Gadget
Protected i.l, j.l
For j = 0 To __TimerSpinGadget_TotalNumber
For i = 0 To 3
If __TimerSpinGadget_spnControl(i, j) = GadgetID
__TimerSpinGadget_Update(i, j)
EndIf
Next
Next
EndIf
EndProcedure
Procedure.s TimerSpinGadget_GetTime(pInstanceNumber.l)
Protected rv.s = ""
rv + GetGadgetText(__TimerSpinGadget_spnControl(0, pInstanceNumber)) + ":"
rv + GetGadgetText(__TimerSpinGadget_spnControl(1, pInstanceNumber)) + ":"
rv + GetGadgetText(__TimerSpinGadget_spnControl(2, pInstanceNumber)) + ":"
rv + GetGadgetText(__TimerSpinGadget_spnControl(3, pInstanceNumber))
ProcedureReturn rv
EndProcedure
;}
; This section can be in another file, just include the code above as an XInclude
CompilerIf #PB_Compiler_Debugger
OpenWindow(0, 216, 0, 300, 150, "New window ( 0 )", #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_TitleBar | #PB_Window_WindowCentered)
TimerSpinGadget_SetNumberOfInstances(4)
TimerSpinGadget_New(WindowID(0), 10, 10, 0)
TimerSpinGadget_New(WindowID(0), 150, 10, 1)
TimerSpinGadget_New(WindowID(0), 10, 50, 2)
TimerSpinGadget_New(WindowID(0), 150, 50, 3)
Define btnListValues.l = ButtonGadget(#PB_Any, 80, 90, 100, 24, "Display Values")
Define Event
Define WindowID
Define GadgetID
Define EventType
Repeat ; Start of the event loop
Event = WaitWindowEvent() ; This line waits until an event is received from Windows
WindowID = EventWindow() ; The Window where the event is generated, can be used in the gadget procedures
GadgetID = EventGadget() ; Is it a gadget event?
EventType = EventType() ; The event type
TimerSpinGadget_Event(Event, WindowID, GadgetID, EventType)
If Event = #PB_Event_Gadget
If GadgetID = btnListValues
Define display.s = ""
display + TimerSpinGadget_GetTime(0) + Chr(13) + Chr(10)
display + TimerSpinGadget_GetTime(1) + Chr(13) + Chr(10)
display + TimerSpinGadget_GetTime(2) + Chr(13) + Chr(10)
display + TimerSpinGadget_GetTime(3)
MessageRequester("", display)
GadgetID = 0
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
TimerSpinGadget_Release()
CompilerEndIf
Posted: Tue Jul 08, 2008 11:40 pm
by Perkin
@Foz - Brilliant,

works well, and each is a set, Thanks a lot for this.
I re-read tthe topic you posted earlier, still confuses me

, I'll keep trying till I understand it, just out of sheer bloody-mindedness
Thanks

Perkin

Posted: Wed Jul 09, 2008 10:05 am
by Perkin
I've made a couple of changes to Foz's code
Ive Changed
'TimerSpinGadget_GetTime' --> 'TimerSpinGadget_GetTimeS'
Added
'__TimerSpinGadget_SP_Mult(3)' (Array of multipliers to get millis)
'TimerSpinGadget_GetTimeL' (Returns milliseconds - removes need for conversion routine)
Here's the code added :-
Code: Select all
Global Dim __TimerSpinGadget_SP_Mult(3)
__TimerSpinGadget_SP_Mult(0) = 3600000
__TimerSpinGadget_SP_Mult(1) = 60000
__TimerSpinGadget_SP_Mult(2) = 1000
__TimerSpinGadget_SP_Mult(3) = 10
; -Return value in millis
Procedure.l TimerSpinGadget_GetTimeL(pInstanceNumber.l)
Protected rv.l = 0
rv + GetGadgetState(__TimerSpinGadget_spnControl(0, pInstanceNumber)) * __TimerSpinGadget_SP_Mult(0)
rv + GetGadgetState(__TimerSpinGadget_spnControl(1, pInstanceNumber)) * __TimerSpinGadget_SP_Mult(1)
rv + GetGadgetState(__TimerSpinGadget_spnControl(2, pInstanceNumber)) * __TimerSpinGadget_SP_Mult(2)
rv + GetGadgetState(__TimerSpinGadget_spnControl(3, pInstanceNumber)) * __TimerSpinGadget_SP_Mult(3)
ProcedureReturn rv
EndProcedure
I also added a few lines to the display reslts event, they now read (with the other four lines included)
Code: Select all
display + TimerSpinGadget_GetTimeS(0) + Chr(13) + Chr(10)
display + TimerSpinGadget_GetTimeS(1) + Chr(13) + Chr(10)
display + TimerSpinGadget_GetTimeS(2) + Chr(13) + Chr(10)
display + TimerSpinGadget_GetTimeS(3) + Chr(13) + Chr(10)
display + Str(TimerSpinGadget_GetTimeL(0)) + Chr(13) + Chr(10)
display + Str(TimerSpinGadget_GetTimeL(1)) + Chr(13) + Chr(10)
display + Str(TimerSpinGadget_GetTimeL(2)) + Chr(13) + Chr(10)
display + Str(TimerSpinGadget_GetTimeL(3))
Posted: Wed Jul 09, 2008 10:08 am
by Foz
Community code - building on the shoulders of others

Posted: Wed Jul 09, 2008 10:25 am
by Perkin
Foz wrote
Community code - building on the shoulders of others
Building on the shoulders of the few (Foz, srod, gnozal to name just 3, I know there's more

)
Posted: Wed Jul 09, 2008 10:35 am
by Foz
Well, you brought the idea.
Ollivier brought a trimmed version.
I separated it into a "user control"
You have extended it.
That's four steps and 3 users to get it to where it is now
