"Gadget(s)" für Zeiteingabe gesucht
"Gadget(s)" für Zeiteingabe gesucht
Ich suche z.Zt. ein einfache (und platzsparende) Möglichkeit Uhrzeiten eingegeben, wenn möglich ohne 3 SpinGadgets für Std., Min., Sek. zu bemühen. DateGadget und CalendarGadget bieten die Möglichkeit (zumindest unter Linux) ja nicht.
In Windows sieht man gelegentlich folgende (nicht unpraktische) Möglichkeit die jeweils das Segment, in dem Cursor steht mit den Pfeilen verstellt:
http://www.chabba.de/temp/Windows_TimeControl.jpg (kurzzeitig sichtbar)
Weiß jemand, ob dies ein komplettes Windows-API-Control oder eine Programmierer-Bastelei ist?
Oder kennt jemand einen praktischen PB-Code (mind. für Windows + Linux) in den Foren (wurde bisher nicht fündig.)
Gruß, Charly
In Windows sieht man gelegentlich folgende (nicht unpraktische) Möglichkeit die jeweils das Segment, in dem Cursor steht mit den Pfeilen verstellt:
http://www.chabba.de/temp/Windows_TimeControl.jpg (kurzzeitig sichtbar)
Weiß jemand, ob dies ein komplettes Windows-API-Control oder eine Programmierer-Bastelei ist?
Oder kennt jemand einen praktischen PB-Code (mind. für Windows + Linux) in den Foren (wurde bisher nicht fündig.)
Gruß, Charly
PureBasic Linux-API-Library: http://www.chabba.de
Re: "Gadget(s)" für Zeiteingabe gesucht
Hallo!
Unter Linux (mit Gtk+) wäre es eine kleine Bastelei aus verschiedenen Widgets.
Unter Windows empfehle ich diesen Link:
https://docs.microsoft.com/en-us/window ... r-controls
Unter Linux (mit Gtk+) wäre es eine kleine Bastelei aus verschiedenen Widgets.
Unter Windows empfehle ich diesen Link:
https://docs.microsoft.com/en-us/window ... r-controls
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
Re: "Gadget(s)" für Zeiteingabe gesucht
Ich würde es evtl. etwa wie folgt machen.
//edit: Code vervollständigt.
//edit: Code vervollständigt.
Code: Alles auswählen
EnableExplicit
Procedure.s NewTime (time$, SecondsChanged)
Protected.i hrs, min, sec
hrs = Val(StringField(time$, 1, ":"))
min = Val(StringField(time$, 2, ":"))
sec = Val(StringField(time$, 3, ":")) + SecondsChanged
min + Int(sec/60)
sec % 60
If sec < 0
sec + 60
min - 1
EndIf
hrs + Int(min/60)
min % 60
If min < 0
min + 60
hrs - 1
EndIf
hrs % 24
If hrs < 0
hrs + 24
EndIf
ProcedureReturn RSet(Str(hrs), 2, "0") + ":" + RSet(Str(min), 2, "0") + ":" + RSet(Str(sec), 2, "0")
EndProcedure
Define Event
OpenWindow(0, 0, 0, 140, 70, "SpinGadget", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
SpinGadget (0, 20, 20, 100, 25, 0, 1000)
SetGadgetText(0, "11:29:53") ; set initial value
Repeat
Event = WaitWindowEvent()
If Event = #PB_Event_Gadget
If EventGadget() = 0
Select EventType()
Case #PB_EventType_Up
SetGadgetText(0, NewTime(GetGadgetText(0), 1))
Case #PB_EventType_Down
SetGadgetText(0, NewTime(GetGadgetText(0), -1))
EndSelect
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
Re: "Gadget(s)" für Zeiteingabe gesucht
Huhu!
Ich habe hier einmal einen kleinen Testcode erstellt. (Überarbeitung des Codes von Nino)
Der Code funktioniert noch nicht korrekt!
Aber jetzt stellt sich für mich die Frage wie man das hier ersichtliche Fokus-Ändere-Dich (Nicht) - Problem umschiffen/ bzw. lösen kann.
(Anbei: Noch recht unsauber programmiert.)
Ich habe hier einmal einen kleinen Testcode erstellt. (Überarbeitung des Codes von Nino)
Der Code funktioniert noch nicht korrekt!
Aber jetzt stellt sich für mich die Frage wie man das hier ersichtliche Fokus-Ändere-Dich (Nicht) - Problem umschiffen/ bzw. lösen kann.
(Anbei: Noch recht unsauber programmiert.)
Code: Alles auswählen
EnableExplicit
;Für Windows:
; OpenWindow(0,0,0,220,50,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
; tWnd = CreateWindowEx_(0,"SysDateTimePick32","",#WS_CHILD|#WS_VISIBLE| #DTS_TIMEFORMAT,10,10,200,25,WindowID(0),0, GetModuleHandle_(0),0)
; SendMessage_(tWnd,#DTM_SETSYSTEMTIME,#GDT_NONE,@time.SYSTEMTIME )
; Repeat : Until WaitWindowEvent() = #PB_Event_CloseWindow
;Oder es wird selber gemacht/ bzw. erweitert:
;Ich brauche hier mal Tipps für das Focus-Change-Problem !!!
Global tpos.i = 0, tUp.b = #False, tDown.b = #False
Global.i Box1, Box2, Box3, Box4
Procedure.s NewTime (time$, SecondsChanged)
Protected.i hrs, min, sec
hrs = Val(StringField(time$, 1, ":"))
min = Val(StringField(time$, 2, ":"))
sec = Val(StringField(time$, 3, ":")) + SecondsChanged
min + Int(sec/60)
sec % 60
If sec < 0
sec + 60
min - 1
EndIf
hrs + Int(min/60)
min % 60
If min < 0
min + 60
hrs - 1
EndIf
hrs % 24
If hrs < 0
hrs + 24
EndIf
ProcedureReturn RSet(Str(hrs), 2, "0") + ":" + RSet(Str(min), 2, "0") + ":" + RSet(Str(sec), 2, "0")
EndProcedure
Procedure.i GetHour(timeStr.s)
Protected.i regex, pass.b = #False, h, rh
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, timeStr)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
h = Val(StringField(timeStr, 1, ":"))
If h < 25
rh = h
EndIf
EndIf
ProcedureReturn rh
EndProcedure
Procedure.i GetMinute(timeStr.s)
Protected.i regex, pass.b = #False, m, rm
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, timeStr)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
m = Val(StringField(timeStr, 2, ":"))
If m < 60
rm = m
EndIf
EndIf
ProcedureReturn rm
EndProcedure
Procedure.i GetSecond(timeStr.s)
Protected.i regex, pass.b = #False, s, rs
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, timeStr)
While NextRegularExpressionMatch(regex)
;Debug "ok"
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
s = Val(StringField(timeStr, 3, ":"))
If s < 60
rs = s
EndIf
EndIf
ProcedureReturn rs
EndProcedure
Procedure SetHour(gadget.i, h.i)
Protected atimeStr.s, ntimeStr.s
atimeStr = GetGadgetText(gadget)
If h >= 0 And h < 25
ntimeStr = RSet(Str(h), 2, "0") + ":" + RSet(Str(GetMinute(atimeStr)), 2, "0") + ":" + RSet(Str(GetSecond(atimeStr)), 2, "0")
SetGadgetText(gadget, ntimeStr)
EndIf
EndProcedure
Procedure SetMinute(gadget.i, m.i)
Protected atimeStr.s, ntimeStr.s
atimeStr = GetGadgetText(gadget)
If m >= 0 And m < 60
ntimeStr = RSet(Str(GetHour(atimeStr)), 2, "0") + ":" + RSet(Str(m), 2, "0") + ":" + RSet(Str(GetSecond(atimeStr)), 2, "0")
SetGadgetText(gadget, ntimeStr)
EndIf
EndProcedure
Procedure SetSecond(gadget.i, s.i)
Protected atimeStr.s, ntimeStr.s
atimeStr = GetGadgetText(gadget)
If s >= 0 And s < 60
ntimeStr = RSet(Str(GetHour(atimeStr)), 2, "0") + ":" + RSet(Str(GetMinute(atimeStr)), 2, "0") + ":" + RSet(Str(s), 2, "0")
SetGadgetText(gadget, ntimeStr)
EndIf
EndProcedure
Procedure ChangeTimeInControl(gadget.i, pos.i, down.b = #False)
Protected.i aSec = 0, aMin = 0, aHrs = 0
If pos >= 0 And pos < 3
aHrs = GetHour(GetGadgetText(gadget))
If down = #False
SetHour(gadget, aHrs+1)
ElseIf down = #True
SetHour(gadget, aHrs-1)
EndIf
ElseIf pos > 2 And pos < 6
aMin = GetMinute(GetGadgetText(gadget))
If down = #False
SetMinute(gadget, aMin+1)
ElseIf down = #True
SetMinute(gadget, aMin-1)
EndIf
ElseIf pos > 5 And pos < 9
aSec = GetSecond(GetGadgetText(gadget))
If down = #False
SetSecond(gadget, aSec+1)
ElseIf down = #True
SetSecond(gadget, aSec-1)
EndIf
EndIf
EndProcedure
Define Event
OpenWindow(0, 0, 0, 140, 70, "Time-Control", #PB_Window_SystemMenu | #PB_Window_ScreenCentered)
AddKeyboardShortcut(0, #PB_Shortcut_Up, 1)
AddKeyboardShortcut(0, #PB_Shortcut_Down, 2)
SpinGadget(0, 20, 20, 100, 25, 0, 1000)
SetGadgetText(0, "11:29:00") ;nn:nn:nn Format ist Pflicht! (Eine 60. Leap-Second gibt es bei mir nicht! (No Astro-Time !!!))
Debug GetMinute("00:24:00")
;Für Linux-Insider
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
;Na wir gucken mal was sich unter Linux dahinter verbirgt. (Es sieht ja irgendwie stark nach einem gtk_entry aus.)
Debug PeekS(gtk_widget_get_name_(GadgetID(0)), -1, #PB_UTF8)
;Ah! Das ist ja etwas zusammengebasteltes in einem GtkBox-Container.
;Wir schauen also noch etwas genauer hin:
Box1 = g_list_nth_data_(gtk_container_get_children_(WindowID(0)), 0) ;GtkBox
Debug PeekS(gtk_widget_get_name_(Box1), -1, #PB_UTF8)
Box2 = g_list_nth_data_(gtk_container_get_children_(Box1), 0) ;GtkLayout
Debug PeekS(gtk_widget_get_name_(Box2), -1, #PB_UTF8)
Box3 = g_list_nth_data_(gtk_container_get_children_(Box2), 0) ;GtkBox
Debug PeekS(gtk_widget_get_name_(Box3), -1, #PB_UTF8)
Box4 = g_list_nth_data_(gtk_container_get_children_(Box3), 0) ;GtkEntry
Debug PeekS(gtk_widget_get_name_(Box4), -1, #PB_UTF8)
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
Procedure Get_Edit_Pos(gadget)
Protected Min, Max
SendMessage_(GadgetID(gadget),#EM_GETSEL,@Min,@Max)
ProcedureReturn Max-SendMessage_(GadgetID(gadget),#EM_LINEINDEX,SendMessage_(GadgetID(gadget),#EM_LINEFROMCHAR,Min,0),0)
EndProcedure
CompilerEndIf
Repeat
Event = WaitWindowEvent()
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
tpos = gtk_editable_get_position_(Box4) ;Linux
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
tpos = Get_Edit_Pos(0) ;Windows
CompilerEndIf
If Event = #PB_Event_Menu
If EventMenu() = 1
ChangeTimeInControl(0, tpos, #False)
ElseIf EventMenu() = 2
ChangeTimeInControl(0, tpos, #True)
EndIf
EndIf
If Event = #PB_Event_Gadget
If EventGadget() = 0
Select EventType()
Case #PB_EventType_Up
;SetGadgetText(0, NewTime(GetGadgetText(0), 1))
ChangeTimeInControl(0, tpos, #False)
Case #PB_EventType_Down
;SetGadgetText(0, NewTime(GetGadgetText(0), -1))
ChangeTimeInControl(0, tpos, #True)
EndSelect
EndIf
EndIf
Until Event = #PB_Event_CloseWindow
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
Re: "Gadget(s)" für Zeiteingabe gesucht
Das SpinGadget ist nur für Zahlenwerte ausgelegt.
Wenn man jetzt Zeichenketten wie z.B. 11:00:01 oder ähnlich verwendet (also mit : -Zeichen) funktioniert die Auswertung des Minimalwertes und Maximalwertes nicht mehr.
Also der bessere Weg ist die Verwendung eines StringGadgets, aber dort gibt es natürlich auch das Fokusproblem.
Aber es gibt natürlich eine Lösung dafür.
Mit der Verwendung des Canvas-Gadgets kann man die Zeicheneingabefläche und die dazugehörigen UP/Down-Knöpfe fokusunabhängig auswerten. (Alles ist ein Gadget!)
Naja so ist das halt.
Gute Nacht!
Anbei: Ich melde mich sicherlich auch Morgen wieder mal.
Wenn man jetzt Zeichenketten wie z.B. 11:00:01 oder ähnlich verwendet (also mit : -Zeichen) funktioniert die Auswertung des Minimalwertes und Maximalwertes nicht mehr.
Also der bessere Weg ist die Verwendung eines StringGadgets, aber dort gibt es natürlich auch das Fokusproblem.
Aber es gibt natürlich eine Lösung dafür.
Mit der Verwendung des Canvas-Gadgets kann man die Zeicheneingabefläche und die dazugehörigen UP/Down-Knöpfe fokusunabhängig auswerten. (Alles ist ein Gadget!)
Naja so ist das halt.
Gute Nacht!
Anbei: Ich melde mich sicherlich auch Morgen wieder mal.
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
Re: "Gadget(s)" für Zeiteingabe gesucht
Vielen Dank schon mal für eure Bemühungen - und bitte nicht nachlassen .
@Nino: Dein Einheiten-Übertrag ist sehr elegant gelöst. Ich hab mir im Laufe der Jahre auch so einige Tricks erarbeitet - auf diesen wäre ich nicht gekommen.
Bei ersten Test Deiner Routine trat meine Maus jedoch der Gewerkschaft bei: 86400 Klicks (auf Linux einzelgeklickt) um einen Tag durchzuscrollen war ihr ein zu dicker Verstoß gegen den Arbeitsschutz.
Außerdem tritt auf Linux beim PB-Spezial-SpinGadget eben nachfolgendes Problem mit dem Down-Pfeil auf ...
EIN SpinGadget für h, m + s habe ich erst mal verworfen, da ich das Problem mit Nicht-Integer-Inhalten auch bemerkte -> der DownPfeil ist deaktiviert, falls ein nicht nummerisches Zeichen enthalten ist, d.h. es wird seitens PB als value= 0 interpretiert.
Auch der native GtkSpinButton ist nur auf Integer und Float ausgelegt und dürfte zur Sackgasse werden.
@ ccode_new: Wow, Du hast dich wirklich schon reingehängt und es würde schon mal so aussehen wie gedacht (und hast die Linux-Sache langsam gut im Griff). Ich werd' Dich mal als 'AKK' fürs Linux-API-Lib-Dings vorsehen . Das Fokussierung / Cursorpositionierungsproblem wäre, glaube ich, in den Griff zu kriegen - evtl. auch mit Markierung des jeweils bearbeiteten Segments.
Ich bin aber vor der Umsetzung zurückgeschreckt wegen des PB-SpinGadget-Integer-Problems und da keine String-Maske (Vorformatierung) möglich ist. D.h. manuelle Eingaben zerstören das erforderliche Stringformat völlig. Eine gute Sofort-Korrektur ist auch sehr aufwändig inkl. der Gefahr der Unbedienbarkeit bei unbedachten String-Konstellationen (aus der Erfahrung). Man wird aber nicht Drum-Rum-Kommen fürchte ich.
Momentanes Fazit:
Auf Windows wäre die API-Version wohl vorzuziehen (hier fehlt es mir jedoch mittlerweile an API-Erfahrung und einem aktuellerem OS). Mit 'altem XP-Rechner umstöpseln' und/oder 'Wine' tue ich es mir nicht an.
Auf Linux muss man das Problem noch wirken lassen - ich tendiere auch zu einer eigenen 'StringGadget + Pfeile-Kombi'. Eine - wie gewünscht - einfache Umsetzung wird's wohl nicht geben können.
Um hier keinen Stress aufkommen zu lassen (lieber im Rahmen der Möglichkeiten gut als schnell) und damit es nicht so aussieht, als würde ich mich bedienen lassen, stelle ich hier mal meine erste Notfall-Backup-Version für Test und Feinschliff rein (die, die eigentlich verbessert werden soll). Ist halt das '3½-Tonner-SUV zum-Brötchen-holen'-Modell.
Es bügelt zumindest einige Linux-Bedien-Handicaps und das mögliche Falschwerte-Direkteingabe-Probleme in Windows-SpinGadgets aus. Vielleicht läuft's ja auch (mit wenig oder keiner Anpassung) auf dem Mac.
Ich muss mich jetzt erst mal ums Vorweihnachtliche (darunter u.a. auch um ein nicht allzu fehlerhaftes Mini-API-Library-Update) kümmern.
Danke bisher, Charly
ps-ps:
So, hier mal die ungelenke-handarbeits-dicke-Hose Version ...
@Nino: Dein Einheiten-Übertrag ist sehr elegant gelöst. Ich hab mir im Laufe der Jahre auch so einige Tricks erarbeitet - auf diesen wäre ich nicht gekommen.
Bei ersten Test Deiner Routine trat meine Maus jedoch der Gewerkschaft bei: 86400 Klicks (auf Linux einzelgeklickt) um einen Tag durchzuscrollen war ihr ein zu dicker Verstoß gegen den Arbeitsschutz.
Außerdem tritt auf Linux beim PB-Spezial-SpinGadget eben nachfolgendes Problem mit dem Down-Pfeil auf ...
EIN SpinGadget für h, m + s habe ich erst mal verworfen, da ich das Problem mit Nicht-Integer-Inhalten auch bemerkte -> der DownPfeil ist deaktiviert, falls ein nicht nummerisches Zeichen enthalten ist, d.h. es wird seitens PB als value= 0 interpretiert.
Auch der native GtkSpinButton ist nur auf Integer und Float ausgelegt und dürfte zur Sackgasse werden.
@ ccode_new: Wow, Du hast dich wirklich schon reingehängt und es würde schon mal so aussehen wie gedacht (und hast die Linux-Sache langsam gut im Griff). Ich werd' Dich mal als 'AKK' fürs Linux-API-Lib-Dings vorsehen . Das Fokussierung / Cursorpositionierungsproblem wäre, glaube ich, in den Griff zu kriegen - evtl. auch mit Markierung des jeweils bearbeiteten Segments.
Ich bin aber vor der Umsetzung zurückgeschreckt wegen des PB-SpinGadget-Integer-Problems und da keine String-Maske (Vorformatierung) möglich ist. D.h. manuelle Eingaben zerstören das erforderliche Stringformat völlig. Eine gute Sofort-Korrektur ist auch sehr aufwändig inkl. der Gefahr der Unbedienbarkeit bei unbedachten String-Konstellationen (aus der Erfahrung). Man wird aber nicht Drum-Rum-Kommen fürchte ich.
Momentanes Fazit:
Auf Windows wäre die API-Version wohl vorzuziehen (hier fehlt es mir jedoch mittlerweile an API-Erfahrung und einem aktuellerem OS). Mit 'altem XP-Rechner umstöpseln' und/oder 'Wine' tue ich es mir nicht an.
Auf Linux muss man das Problem noch wirken lassen - ich tendiere auch zu einer eigenen 'StringGadget + Pfeile-Kombi'. Eine - wie gewünscht - einfache Umsetzung wird's wohl nicht geben können.
Um hier keinen Stress aufkommen zu lassen (lieber im Rahmen der Möglichkeiten gut als schnell) und damit es nicht so aussieht, als würde ich mich bedienen lassen, stelle ich hier mal meine erste Notfall-Backup-Version für Test und Feinschliff rein (die, die eigentlich verbessert werden soll). Ist halt das '3½-Tonner-SUV zum-Brötchen-holen'-Modell.
Es bügelt zumindest einige Linux-Bedien-Handicaps und das mögliche Falschwerte-Direkteingabe-Probleme in Windows-SpinGadgets aus. Vielleicht läuft's ja auch (mit wenig oder keiner Anpassung) auf dem Mac.
Ich muss mich jetzt erst mal ums Vorweihnachtliche (darunter u.a. auch um ein nicht allzu fehlerhaftes Mini-API-Library-Update) kümmern.
Danke bisher, Charly
ps-ps:
Na gerne.Anbei: Ich melde mich sicherlich auch Morgen wieder mal.
So, hier mal die ungelenke-handarbeits-dicke-Hose Version ...
Code: Alles auswählen
EnableExplicit
; Object constants
#Win_Main = 0
Enumeration TimeGadgets
#SpGTimeH
#SpGTimeM
#SpGTimeS
#TxGShowTime
#TxGShowTimeNo
EndEnumeration
Global.i gEvent, gEventGadget, gQuit
;- Part for tweaked SpinGadgets ...
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
ImportC ""
g_signal_connect(*instance, detailed_signal.p-utf8, *c_handler, *data, destroy= 0, flags= 0) As "g_signal_connect_data"
gtk_entry_set_alignment(*entry.GtkEntry, xalign.f)
EndImport
;see https://git.gnome.org/browse/gtk+/plain/gdk/gdkkeysyms.h
#GDK_KEY_Up = $FF52
#GDK_KEY_Down= $FF54
Structure CALLBACKDATA
GadgetNo.i
WindowNo.i
EndStructure
Global NewList GadgetData.CALLBACKDATA()
ProcedureC Callback_SpinGadgetScroll(*widget.GtkWidget, *Event.GdkEventAny, *user_data.CALLBACKDATA); match callback name with the call in SpinGadget_Tweak
Protected *ev_scroll.GdkEventScroll
Protected *ev_keypress.GdkEventKey
Protected Ret= #False
If *Event\type = #GDK_SCROLL
*ev_scroll= *Event
ElseIf *Event\type = #GDK_KEY_PRESS
*ev_keypress= *Event
EndIf
If (*ev_scroll And *ev_scroll\direction = #GDK_SCROLL_UP) Or (*ev_keypress And *ev_keypress\keyval = #GDK_KEY_Up)
SetGadgetText(*user_data\GadgetNo, Str(Val(GetGadgetText(*user_data\GadgetNo))+ 1))
PostEvent(#PB_Event_Gadget, *user_data\WindowNo, *user_data\GadgetNo, #PB_EventType_Up)
PostEvent(#PB_Event_Gadget, *user_data\WindowNo, *user_data\GadgetNo, #PB_EventType_Change)
Ret= #True; avoids focus change on up/down key
ElseIf (*ev_scroll And *ev_scroll\direction = #GDK_SCROLL_DOWN) Or (*ev_keypress And *ev_keypress\keyval = #GDK_KEY_Down)
SetGadgetText(*user_data\GadgetNo, Str(Val(GetGadgetText(*user_data\GadgetNo))- 1))
PostEvent(#PB_Event_Gadget, *user_data\WindowNo, *user_data\GadgetNo, #PB_EventType_Down)
PostEvent(#PB_Event_Gadget, *user_data\WindowNo, *user_data\GadgetNo, #PB_EventType_Change)
Ret= #True; avoids focus change on up/down key
EndIf
ProcedureReturn Ret
EndProcedure
Procedure.i SpinGadget_GetEntry(Gadget)
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
If GadgetType(Gadget) = #PB_GadgetType_Spin
Protected *entry = g_list_nth_data_(gtk_container_get_children_(GadgetID(Gadget)), 0)
ProcedureReturn *entry
EndIf
CompilerEndIf
EndProcedure
Procedure SpinGadget_Tweak(Window, Gadget)
If GadgetType(Gadget) = #PB_GadgetType_Spin
Protected *entry.GtkEntry = g_list_nth_data_(gtk_container_get_children_(GadgetID(Gadget)), 0)
AddElement(GadgetData())
GadgetData()\GadgetNo= Gadget
GadgetData()\WindowNo= Window
gtk_widget_add_events_(*entry, #GDK_SCROLL_MASK | #GDK_KEY_PRESS_MASK)
g_signal_connect_(*entry, "scroll-event", @Callback_SpinGadgetScroll(), @GadgetData()); event on wheelscrolling over entry
g_signal_connect_(*entry, "key-press-event", @Callback_SpinGadgetScroll(), @GadgetData()); event on key up/down on focussed entry
EndIf
EndProcedure
CompilerEndIf
;- ... End of part
Procedure TimeGadget_Check(Gadget)
CompilerIf #PB_Compiler_OS = #PB_OS_Windows
If Val(GetGadgetText(Gadget)) > GetGadgetAttribute(Gadget, #PB_Spin_Maximum)
SetGadgetState(Gadget, GetGadgetAttribute (Gadget, #PB_Spin_Maximum))
SetGadgetText(Gadget, Str(GetGadgetAttribute(Gadget, #PB_Spin_Maximum)))
ElseIf Val(GetGadgetText(Gadget)) < GetGadgetAttribute(Gadget, #PB_Spin_Minimum)
SetGadgetState(Gadget, GetGadgetAttribute (Gadget, #PB_Spin_Minimum))
SetGadgetText(Gadget, Str(GetGadgetAttribute(Gadget, #PB_Spin_Minimum)))
EndIf
CompilerEndIf
EndProcedure
Procedure Create_WinMain()
If OpenWindow(#Win_Main, 300, 200, 400, 200, "Set time ", #PB_Window_SystemMenu | #PB_Window_ScreenCentered | #PB_Window_SizeGadget | #PB_Window_MaximizeGadget)
TextGadget(#PB_Any, 5, 14, 130, 22, "Set time (h:m:s)")
SpinGadget(#SpGTimeH, 140, 10, 54, 28, 0, 23, #PB_Spin_Numeric)
SetGadgetState(#SpGTimeH, 8)
SpinGadget(#SpGTimeM, 200, 10, 54, 28, 0, 59, #PB_Spin_Numeric)
SetGadgetState(#SpGTimeM, 30)
SpinGadget(#SpGTimeS, 260, 10, 54, 28, 0, 59, #PB_Spin_Numeric)
SetGadgetState(#SpGTimeS, 0)
TextGadget(#PB_Any, 5, 50, 130, 22, "Time set")
TextGadget(#TxGShowTime, 140, 50, 130, 22, " 8:30:00")
TextGadget(#PB_Any, 5, 80, 130, 22, "Time value")
TextGadget(#TxGShowTimeNo, 140, 80, 130, 22, "")
CompilerIf #PB_Compiler_OS = #PB_OS_Linux
gtk_entry_set_alignment(SpinGadget_GetEntry(#SpGTimeH), 1.0)
gtk_entry_set_alignment(SpinGadget_GetEntry(#SpGTimeM), 1.0)
gtk_entry_set_alignment(SpinGadget_GetEntry(#SpGTimeS), 1.0)
SpinGadget_Tweak(#Win_Main, #SpGTimeH)
SpinGadget_Tweak(#Win_Main, #SpGTimeM)
SpinGadget_Tweak(#Win_Main, #SpGTimeS)
CompilerEndIf
EndIf
EndProcedure
Create_WinMain()
Repeat
gEvent= WaitWindowEvent()
Select gEvent
Case #PB_Event_CloseWindow
gQuit= #True
Case #PB_Event_Gadget
gEventGadget= EventGadget()
Select gEventGadget
Case #SpGTimeH, #SpGTimeM, #SpGTimeS
TimeGadget_Check(gEventGadget)
SetGadgetText(#TxGShowTime, RSet(GetGadgetText(#SpGTimeH), 2) + ":" + RSet(GetGadgetText(#SpGTimeM), 2, "0") + ":" + RSet(GetGadgetText(#SpGTimeS), 2, "0"))
SetGadgetText(#TxGShowTimeNo, Str(ParseDate("%hh:%ii:%ss", RSet(GetGadgetText(#SpGTimeH), 2, "0") + ":" + RSet(GetGadgetText(#SpGTimeM), 2, "0") + ":" + RSet(GetGadgetText(#SpGTimeS), 2, "0"))))
EndSelect
EndSelect
Until gQuit
PureBasic Linux-API-Library: http://www.chabba.de
Re: "Gadget(s)" für Zeiteingabe gesucht
Hallo Omi!
Mein Betrag sollte nur eine Gedankenanregung sein und war v.a. darauf ausgerichtet, dass Du zuvor geschrieben hattest
Schönen 3. Advent, Nino
Danke! Ich war selbst ein wenig überrascht, dass die Lösung so elegant war.Omi hat geschrieben:@Nino: Dein Einheiten-Übertrag ist sehr elegant gelöst. Ich hab mir im Laufe der Jahre auch so einige Tricks erarbeitet - auf diesen wäre ich nicht gekommen.
Als Katzenfreund bin ich dagegen, dass Mäuse in Gewerkschaften eintreten!Omi hat geschrieben:Bei ersten Test Deiner Routine trat meine Maus jedoch der Gewerkschaft bei: 86400 Klicks (auf Linux einzelgeklickt) um einen Tag durchzuscrollen war ihr ein zu dicker Verstoß gegen den Arbeitsschutz.
Mein Betrag sollte nur eine Gedankenanregung sein und war v.a. darauf ausgerichtet, dass Du zuvor geschrieben hattest
wenn möglich ohne 3 SpinGadgets für Std., Min., Sek. zu bemühen
Unter Windows funktioniert es mit 1 Spingadget. Dass unter Linux dieses Problem auftritt, damit hatte ich nicht gerechnet. Das ist natürlich inakzeptabel.Omi hat geschrieben:Außerdem tritt auf Linux beim PB-Spezial-SpinGadget eben nachfolgendes Problem mit dem Down-Pfeil auf ...
EIN SpinGadget für h, m + s habe ich erst mal verworfen, da ich das Problem mit Nicht-Integer-Inhalten auch bemerkte -> der DownPfeil ist deaktiviert, falls ein nicht nummerisches Zeichen enthalten ist, d.h. es wird seitens PB als value= 0 interpretiert.
Schönen 3. Advent, Nino
Re: "Gadget(s)" für Zeiteingabe gesucht
Eine schönen restlichen 3. Advent noch!
Hallo "Omi" !
Ich habe mich an die Umsetzung über das Canvas-Gadget gewagt.
Dabei hatte ich noch einen tollen Einfall.
Ich verwende bei dieser 1. Version (ich nenne sie mal:"Alpha-Version") meines "TimeGadget"-Modules eine PopUp-Menü-Lösung, weil mir die Sache mit den Pfeilen noch zu doof war.
Hier mein erstelltes Programm:
-Es braucht noch Resize-Funktionen.
-Es braucht noch Font/Color - Set/Get - Funktionen.
-etc.
Zeile:
dürfte für Tests noch nützlich sein. :wink
Anbei:
Die Bugsuche kann weiter gehen.
Hallo "Omi" !
Ich habe mich an die Umsetzung über das Canvas-Gadget gewagt.
Dabei hatte ich noch einen tollen Einfall.
Ich verwende bei dieser 1. Version (ich nenne sie mal:"Alpha-Version") meines "TimeGadget"-Modules eine PopUp-Menü-Lösung, weil mir die Sache mit den Pfeilen noch zu doof war.
Hier mein erstelltes Programm:
Code: Alles auswählen
;Time-Gadget-Module (mit Canvas-Gadget)
;Einmal ganz ohne Pfeile, aber dafür mit PopUp-Menü. :)
DeclareModule TimeGadget
Structure TTimeValue
hour.i
minute.i
second.i
EndStructure
Structure TCursor
pos.i
fpos.i
length.i
EndStructure
Structure TTimeInput
gid.i
value.s
length.i
isfocus.b
x.i
y.i
h.i
w.i
time.TTimeValue
cursor.TCursor
EndStructure
Global m1_id.i, m2_id.i
;PopUp-Select
m1_id = CreatePopupMenu(#PB_Any)
If m1_id
For k = 0 To 23
MenuItem(k, Str(k))
Next k
EndIf
m2_id = CreatePopupMenu(#PB_Any)
If m2_id
For k = 0 To 59
MenuItem(k, Str(k))
Next k
EndIf
Declare.i TimeGadget(gid.i, xpos.i, ypos.i, width.i, height.i, timeStr.s, flags.i = 0)
Declare TimeInput_Destroy(*pTimeGadget.TTimeInput)
Declare TimeInput_Event(*pTimeGadget.TTimeInput, Win.i, WindowEvent.i)
Declare TimeInput_Update(*pTimeGadget.TTimeInput, show_cursor.b = #False)
Declare.i TimeInput_GetMousePosition(*pTimeGadget.TTimeInput, x.i, y.i)
Declare.i TimeInput_GetHour(*pTimeGadget.TTimeInput)
Declare.i TimeInput_GetMinute(*pTimeGadget.TTimeInput)
Declare.i TimeInput_GetSecond(*pTimeGadget.TTimeInput)
Declare.s TimeInput_GetTimeString(*pTimeGadget.TTimeInput)
Declare TimeInput_SetTimeString(*pTimeGadget.TTimeInput, timeStr.s)
Declare TimeInput_SetHour(*pTimeGadget.TTimeInput, hour.i)
Declare TimeInput_SetMinute(*pTimeGadget.TTimeInput, minute.i)
Declare TimeInput_SetSecond(*pTimeGadget.TTimeInput, second.i)
Declare.i TimeInput_GetCursorPosition(*pTimeGadget.TTimeInput)
Declare TimeInput_ChangeTime(*pTimeGadget.TTimeInput, pos.i, down.b = #False)
EndDeclareModule
Module TimeGadget
Procedure TimeInput_GetHour(*pTimeGadget.TTimeInput)
Protected.i regex, pass.b = #False, h, rh
If IsGadget(*pTimeGadget\gid)
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, *pTimeGadget\value)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
h = Val(StringField(*pTimeGadget\value, 1, ":"))
If h < 24 And h >= 0
rh = h
ProcedureReturn rh
EndIf
EndIf
EndIf
ProcedureReturn -1
EndProcedure
Procedure TimeInput_GetMinute(*pTimeGadget.TTimeInput)
Protected.i regex, pass.b = #False, m, rm
If IsGadget(*pTimeGadget\gid)
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, *pTimeGadget\value)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
m = Val(StringField(*pTimeGadget\value, 2, ":"))
If m < 60 And m >= 0
rm = m
ProcedureReturn rm
EndIf
EndIf
EndIf
ProcedureReturn -1
EndProcedure
Procedure TimeInput_GetSecond(*pTimeGadget.TTimeInput)
Protected.i regex, pass.b = #False, s, rs
If IsGadget(*pTimeGadget\gid)
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, *pTimeGadget\value)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
s = Val(StringField(*pTimeGadget\value, 3, ":"))
If s < 60 And s >= 0
rs = s
ProcedureReturn rs
EndIf
EndIf
EndIf
ProcedureReturn -1
EndProcedure
Procedure.s TimeInput_GetTimeString(*pTimeGadget.TTimeInput)
If IsGadget(*pTimeGadget\gid)
ProcedureReturn *pTimeGadget\value
Else
ProcedureReturn "-1"
EndIf
EndProcedure
Procedure TimeInput_SetTimeString(*pTimeGadget.TTimeInput, timeStr.s)
Protected.i regex, pass.b = #False
If IsGadget(*pTimeGadget\gid)
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, *pTimeGadget\value)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
*pTimeGadget\value = timeStr
Else
*pTimeGadget\value = "00:00:00"
EndIf
EndIf
EndProcedure
Procedure TimeInput_SetHour(*pTimeGadget.TTimeInput, hour.i)
Protected ntimeStr.s
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
If hour >= 0 And hour < 24
\time\hour = hour
\time\minute = TimeInput_GetMinute(*pTimeGadget)
\time\second = TimeInput_GetSecond(*pTimeGadget)
ntimeStr = RSet(Str(\time\hour), 2, "0") + ":" + RSet(Str(\time\minute), 2, "0") + ":" + RSet(Str(\time\second), 2, "0")
TimeInput_SetTimeString(*pTimeGadget, ntimeStr)
EndIf
EndWith
EndIf
EndProcedure
Procedure TimeInput_SetMinute(*pTimeGadget.TTimeInput, minute.i)
Protected ntimeStr.s
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
If minute >= 0 And minute < 60
\time\hour = TimeInput_GetHour(*pTimeGadget)
\time\minute = minute
\time\second = TimeInput_GetSecond(*pTimeGadget)
ntimeStr = RSet(Str(\time\hour), 2, "0") + ":" + RSet(Str(\time\minute), 2, "0") + ":" + RSet(Str(\time\second), 2, "0")
TimeInput_SetTimeString(*pTimeGadget, ntimeStr)
EndIf
EndWith
EndIf
EndProcedure
Procedure TimeInput_SetSecond(*pTimeGadget.TTimeInput, second.i)
Protected ntimeStr.s
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
If second >= 0 And second < 60
\time\hour = TimeInput_GetHour(*pTimeGadget)
\time\minute = TimeInput_GetMinute(*pTimeGadget)
\time\second = second
ntimeStr = RSet(Str(\time\hour), 2, "0") + ":" + RSet(Str(\time\minute), 2, "0") + ":" + RSet(Str(\time\second), 2, "0")
TimeInput_SetTimeString(*pTimeGadget, ntimeStr)
EndIf
EndWith
EndIf
EndProcedure
Procedure TimeInput_ChangeTime(*pTimeGadget.TTimeInput, pos.i, down.b = #False)
Protected.i aSec = 0, aMin = 0, aHrs = 0
If IsGadget(*pTimeGadget\gid)
If pos >= 0 And pos < 3
aHrs = TimeInput_GetHour(*pTimeGadget)
If down = #False And aHrs > -1
TimeInput_SetHour(*pTimeGadget, aHrs + 1)
ElseIf down = #True And aHrs > 0
TimeInput_SetHour(*pTimeGadget, aHrs - 1)
EndIf
ElseIf pos > 2 And pos < 6
aMin = TimeInput_GetMinute(*pTimeGadget)
If down = #False And aMin > -1
TimeInput_SetMinute(*pTimeGadget, aMin + 1)
ElseIf down = #True And aMin > 0
TimeInput_SetMinute(*pTimeGadget, aMin - 1)
EndIf
ElseIf pos > 5 And pos < 9
aSec = TimeInput_GetSecond(*pTimeGadget)
If down = #False And aSec > -1
TimeInput_SetSecond(*pTimeGadget, aSec + 1)
ElseIf down = #True And aSec > 0
TimeInput_SetSecond(*pTimeGadget, aSec - 1)
EndIf
EndIf
EndIf
EndProcedure
Procedure TimeInput_GetMousePosition(*pTimeGadget.TTimeInput, x.i, y.i)
Protected mouse_x.i, mouse_y.i, min_distance.f = Infinity(), distance.f, cursor_pos.i, cursor_x.i, cursor_y.i, i.i
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
mouse_x = GetGadgetAttribute(\gid, #PB_Canvas_MouseX)
mouse_y = GetGadgetAttribute(\gid, #PB_Canvas_MouseY)
\length = Len(\value)
StartDrawing(CanvasOutput(\gid))
cursor_y = y + TextHeight(\value) / 2
For i = 0 To \length
cursor_x = x + TextWidth(Left(\value, i))
distance = (mouse_x - cursor_x) * (mouse_x - cursor_x) + (mouse_y - cursor_y) * (mouse_y - cursor_y)
If distance < min_distance
min_distance = distance
cursor_pos = i
EndIf
Next
StopDrawing()
If Not IsInfinity(min_distance)
ProcedureReturn cursor_pos
Else
ProcedureReturn -1
EndIf
EndWith
ProcedureReturn -1
EndIf
EndProcedure
Procedure TimeInput_DeleteSelection(*pTimeGadget.TTimeInput)
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
If \cursor\length < 0
\value = Left(\value, \cursor\fpos) + Mid(\value, \cursor\pos + 1)
\cursor\pos = \cursor\fpos
\cursor\length = 0
ProcedureReturn #True
ElseIf \cursor\length > 0
\value = Left(\value, \cursor\pos) + Mid(\value, \cursor\fpos + 1)
\cursor\fpos = \cursor\pos
\cursor\length = 0
ProcedureReturn #True
EndIf
EndWith
EndIf
ProcedureReturn #False
EndProcedure
Procedure TimeInput_Event(*pTimeGadget.TTimeInput, Win.i, WindowEvent.i)
Protected evt.b = #False
Protected cursor_pos.i
Protected afocus.b = #False
Protected select_mode.b = #False
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
Select WindowEvent
Case #PB_Event_Gadget
If EventGadget() = \gid
Select EventType()
Case #PB_EventType_LeftButtonDown
cursor_pos = TimeInput_GetMousePosition(*pTimeGadget, 2, 2)
If cursor_pos <> -1
\cursor\pos = cursor_pos
\cursor\fpos = cursor_pos
\cursor\length = 0
evt = #True
EndIf
select_mode = #True
Case #PB_EventType_RightButtonDown
If \cursor\pos < 3
DisplayPopupMenu(m1_id, WindowID(Win))
ElseIf \cursor\pos > 2 And \cursor\pos < 6
DisplayPopupMenu(m2_id, WindowID(Win))
ElseIf \cursor\pos > 5 And \cursor\pos < 9
DisplayPopupMenu(m2_id, WindowID(Win))
EndIf
Case #PB_EventType_Focus
\isfocus = #True
Case #PB_EventType_LostFocus
\isfocus = #False
Case #PB_EventType_MouseMove
If select_mode = #True
cursor_pos = TimeInput_GetMousePosition(*pTimeGadget, 2, 2)
If cursor_pos <> -1 And \cursor\pos <> cursor_pos
\cursor\pos = cursor_pos
\cursor\length = \cursor\fpos - cursor_pos
evt = #True
EndIf
EndIf
Case #PB_EventType_LeftButtonUp
select_mode = #False
Case #PB_EventType_Input
TimeInput_DeleteSelection(*pTimeGadget)
\value = Left(\value, \cursor\pos) + Chr(GetGadgetAttribute(\gid, #PB_Canvas_Input)) + Mid(\value, \cursor\pos + 1)
\cursor\pos + 1
evt = #True
Case #PB_EventType_KeyDown
Select GetGadgetAttribute(\gid, #PB_Canvas_Key)
Case #PB_Shortcut_Left
If \cursor\pos > 0 : \cursor\pos - 1 : EndIf
evt = #True
Case #PB_Shortcut_Right
If \cursor\pos < Len(\value) : \cursor\pos + 1 : EndIf
evt = #True
Case #PB_Shortcut_End
\cursor\pos = Len(\value)
evt = #True
Case #PB_Shortcut_Home
\cursor\pos = 0
evt = #True
Case #PB_Shortcut_Back
If Not TimeInput_DeleteSelection(*pTimeGadget)
If \cursor\pos > 0
\value = Left(\value, \cursor\pos - 1) + Mid(\value, \cursor\pos + 1)
\cursor\pos - 1
EndIf
EndIf
evt = #True
Case #PB_Shortcut_Delete
If Not TimeInput_DeleteSelection(*pTimeGadget)
If \cursor\pos < Len(\value)
\value = Left(\value, \cursor\pos) + Mid(\value, \cursor\pos + 2)
EndIf
EndIf
evt = #True
EndSelect
EndSelect
EndIf
EndSelect
EndWith
EndIf
EndProcedure
Procedure GetCursorPosition(*pTimeGadget.TTimeInput)
ProcedureReturn TextWidth(Left(*pTimeGadget\value, *pTimeGadget\cursor\pos))
EndProcedure
Procedure GetCursorLength(*pTimeGadget.TTimeInput)
ProcedureReturn TextWidth(Left(*pTimeGadget\value, *pTimeGadget\cursor\pos + *pTimeGadget\cursor\length)) - TextWidth(Left(*pTimeGadget\value, *pTimeGadget\cursor\pos))
EndProcedure
Procedure TimeInput_GetCursorPosition(*pTimeGadget.TTimeInput)
ProcedureReturn *pTimeGadget\cursor\pos
EndProcedure
Procedure TimeInput_Update(*pTimeGadget.TTimeInput, show_cursor.b = #False)
Protected.i a
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
;a = \w / 100 * 20
StartDrawing(CanvasOutput(\gid))
Box(0, 0, \w, \h, RGB(255,255,255))
DrawText(2, (\h / 2)-(TextHeight(\value) / 2), \value, RGB(0,0,0), RGB(255,255,255))
; ;Up-Button
; LineXY(\w-a, \h/2, \w-a/2, 0, RGB(0, 0, 255))
; LineXY(\w-a, \h/2, \w, \h/2, RGB(0, 0, 255))
; LineXY(\w, \h/2, \w-a/2, 0, RGB(0, 0, 255))
; FillArea(\w-a/2, \h/2-1, RGB(0,0,255), RGB(255,0,255))
; ;Down-Button
; LineXY(\w-a, \h/2, \w-a/2, \h, RGB(0, 0, 255))
; LineXY(\w-a, \h/2, \w, \h/2, RGB(0, 0, 255))
; LineXY(\w, \h/2, \w-a/2, \h, RGB(0, 0, 255))
; FillArea(\w-a/2, \h/2+1, RGB(0,0,255), RGB(0,255,255))
DrawingMode(#PB_2DDrawing_XOr)
If \cursor\length < 0
Box(2 + GetCursorPosition(*pTimeGadget) + GetCursorLength(*pTimeGadget), (\h / 2)-(TextHeight(\value) / 2), -GetCursorLength(*pTimeGadget), TextHeight(" "))
ElseIf \cursor\length > 0
Box(2 + GetCursorPosition(*pTimeGadget) + 1, (\h / 2)-(TextHeight(\value) / 2), GetCursorLength(*pTimeGadget) - 1, TextHeight(" "))
EndIf
DrawingMode(#PB_2DDrawing_Default)
If show_cursor = #True And \isfocus = #True
Line(2 + GetCursorPosition(*pTimeGadget), (\h / 2)-(TextHeight(\value) / 2), 1, TextHeight(" "), RGB(0,0,0))
EndIf
StopDrawing()
EndWith
EndIf
EndProcedure
;Time-Gadget-Constructor
Procedure.i TimeGadget(gid.i, xpos.i, ypos.i, width.i, height.i, timeStr.s, flags.i = 0)
Protected *pTimeGadget.TTimeInput = AllocateMemory(SizeOf(TTimeInput))
Protected pid.i, k.i
pid = CanvasGadget(gid, xpos, ypos, width, height, #PB_Canvas_Keyboard)
If pid <> 0
If gid = -1
SetGadgetAttribute(pid, #PB_Canvas_Cursor, #PB_Cursor_IBeam)
Else
SetGadgetAttribute(gid, #PB_Canvas_Cursor, #PB_Cursor_IBeam)
EndIf
With *pTimeGadget
If gid = -1
\gid = pid
Else
\gid = gid
EndIf
\value = timeStr
\x = xpos
\y = ypos
\h = height
\w = width
EndWith
ProcedureReturn *pTimeGadget
EndIf
ProcedureReturn -1
EndProcedure
;Time-Gadget-Destructor
Procedure TimeInput_Destroy(*pTimeGadget.TTimeInput)
If IsGadget(*pTimeGadget\gid)
FreeGadget(*pTimeGadget\gid)
FreeMemory(*pTimeGadget)
EndIf
EndProcedure
EndModule
Enumeration
#Win
#ControlTimer
#SecondTimer
EndEnumeration
UseModule TimeGadget
Global *vTimeGadget.TTimeInput, tpos.i, atimeStr.s
Global *vTimeGadget2.TTimeInput, tpos2.i
Global aGadget.i, lastFocus.i
If OpenWindow(#Win, 0, 0, 200, 100, "Time-Control", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
AddKeyboardShortcut(0, #PB_Shortcut_Up, 1)
AddKeyboardShortcut(0, #PB_Shortcut_Down, 2)
atimeStr = RSet(Str(Hour(Date())), 2, "0") + ":" + RSet(Str(Minute(Date())), 2, "0") + ":" + RSet(Str(Second(Date())), 2, "0")
*vTimeGadget = TimeGadget(0, 10, 10, 80, 20, "00:00:00")
;Debug *vTimeGadget
*vTimeGadget2 = TimeGadget(1, 10, 50, 80, 20, "00:00:00")
;Debug *vTimeGadget2
TimeInput_SetTimeString(*vTimeGadget, atimeStr)
AddWindowTimer(#Win, #ControlTimer, 200)
AddWindowTimer(#Win, #SecondTimer, 1000) ;Durch Deaktivieren\Kommentieren läuft die Zeit nicht weiter !
Repeat
event = WaitWindowEvent()
tpos = TimeInput_GetCursorPosition(*vTimeGadget)
tpos2 = TimeInput_GetCursorPosition(*vTimeGadget2)
If TimeInput_Event(*vTimeGadget, #Win, event)
TimeInput_Update(*vTimeGadget, #False)
EndIf
If TimeInput_Event(*vTimeGadget2, #Win, event)
TimeInput_Update(*vTimeGadget2, #False)
EndIf
If *vTimeGadget\isfocus = #True
lastFocus = *vTimeGadget\gid
ElseIf *vTimeGadget2\isfocus = #True
lastFocus = *vTimeGadget2\gid
EndIf
Select event
Case #PB_Event_CloseWindow
End
Case #PB_Event_Menu
If lastFocus = 0
If EventMenu() = 1
TimeInput_ChangeTime(*vTimeGadget, tpos, #False)
ElseIf EventMenu() = 2
TimeInput_ChangeTime(*vTimeGadget, tpos, #True)
ElseIf MenuID(m1_id) And tpos < 3
TimeInput_SetHour(*vTimeGadget, Val(GetMenuItemText(m1_id, EventMenu())))
ElseIf MenuID(m2_id) And tpos > 2 And tpos < 6
TimeInput_SetMinute(*vTimeGadget, Val(GetMenuItemText(m2_id, EventMenu())))
ElseIf MenuID(m2_id) And tpos > 5 And tpos < 9
TimeInput_SetSecond(*vTimeGadget, Val(GetMenuItemText(m2_id, EventMenu())))
EndIf
Else
If EventMenu() = 1
TimeInput_ChangeTime(*vTimeGadget2, tpos2, #False)
ElseIf EventMenu() = 2 And GetActiveGadget() = 1
TimeInput_ChangeTime(*vTimeGadget2, tpos2, #True)
ElseIf MenuID(m1_id) And tpos2 < 3
TimeInput_SetHour(*vTimeGadget2, Val(GetMenuItemText(m1_id, EventMenu())))
ElseIf MenuID(m2_id) And tpos2 > 2 And tpos2 < 6
TimeInput_SetMinute(*vTimeGadget2, Val(GetMenuItemText(m2_id, EventMenu())))
ElseIf MenuID(m2_id) And tpos2 > 5 And tpos2 < 9
TimeInput_SetSecond(*vTimeGadget2, Val(GetMenuItemText(m2_id, EventMenu())))
EndIf
EndIf
Case #PB_Event_Timer
Select EventTimer()
Case #ControlTimer
TimeInput_Update(*vTimeGadget, #True)
TimeInput_Update(*vTimeGadget2, #True)
Case #SecondTimer
atimeStr = RSet(Str(Hour(Date())), 2, "0") + ":" + RSet(Str(Minute(Date())), 2, "0") + ":" + RSet(Str(Second(Date())), 2, "0")
TimeInput_SetTimeString(*vTimeGadget, atimeStr)
EndSelect
EndSelect
ForEver
TimeInput_Destroy(*vTimeGadget)
EndIf
UnuseModule TimeGadget
-Es braucht noch Font/Color - Set/Get - Funktionen.
-etc.
Zeile:
Code: Alles auswählen
AddWindowTimer(#Win, #SecondTimer, 1000) ;Durch Deaktivieren\Kommentieren läuft die Zeit nicht weiter !
Anbei:
Die Bugsuche kann weiter gehen.
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat
Re: "Gadget(s)" für Zeiteingabe gesucht
@Nino
Ich wollte ja auch nur den Mäusespruch los werden .
@ccode_new
Wow! Echt nicht schlecht und innerhalb der Zeit + Modularisiert. Die Popups fühlen sich zuerst etwas sperrig an (werd' eben schon alt und ein Gewohnheitstier) aber mit jedem Draufklicken gefallen sie einem besser.
Ich hätte in den paar Minuten in denen ich damit rumspielte mal versucht, auch beim Rechtsklick zum Popup öffnen den Cursor mit-umzusetzen, hab das ganze aber in der Zeit noch nicht genug durchschaut.
Ich würde behaupten, das Ding ist schon so weit gediehen und gut umgesetzt, dass es den finalen Feinschliff wirklich verdient hätte. Push, push, push ...
Auf alle Fälle danke ich Dir für den bisherigen Einsatz.
Ich hoffe während des Weihnachtsurlaubs neben dem (lange überfälligen und fest eingeplanten) Durchrocken meiner Gitarren und Verstärker auch für diese Thema mal Zeit und Muse zu finden - falls noch was übrig ist .
Und ich schließ' mich hinten an und wünsch noch 'nen stressfreien "Adv-endspurt".
Grüße Charly
War schon klar. Wär's in der kurzen Zeit perfekt, wär's schon in der Schublade gelegen . Allein die 'Umrechung' war schon das Posten wert.Mein Betrag sollte nur eine Gedankenanregung sein und war v.a. darauf ausgerichtet, dass Du zuvor geschrieben hattest...
Ich wollte ja auch nur den Mäusespruch los werden .
@ccode_new
Wow! Echt nicht schlecht und innerhalb der Zeit + Modularisiert. Die Popups fühlen sich zuerst etwas sperrig an (werd' eben schon alt und ein Gewohnheitstier) aber mit jedem Draufklicken gefallen sie einem besser.
Ich hätte in den paar Minuten in denen ich damit rumspielte mal versucht, auch beim Rechtsklick zum Popup öffnen den Cursor mit-umzusetzen, hab das ganze aber in der Zeit noch nicht genug durchschaut.
Ich würde behaupten, das Ding ist schon so weit gediehen und gut umgesetzt, dass es den finalen Feinschliff wirklich verdient hätte. Push, push, push ...
Auf alle Fälle danke ich Dir für den bisherigen Einsatz.
Ich hoffe während des Weihnachtsurlaubs neben dem (lange überfälligen und fest eingeplanten) Durchrocken meiner Gitarren und Verstärker auch für diese Thema mal Zeit und Muse zu finden - falls noch was übrig ist .
Und ich schließ' mich hinten an und wünsch noch 'nen stressfreien "Adv-endspurt".
Grüße Charly
PureBasic Linux-API-Library: http://www.chabba.de
Re: "Gadget(s)" für Zeiteingabe gesucht
Hallo Leute!
Hier kommt ein kleines Update.
Das mit den PopUp-Menü habe ich verworfen und Pfeile sucht man vergebens, aber man darf das Scrollrad verwenden.
Es dürfen nur Zahlen(0-9) und das Zeichen(:) eingegeben werden.
Außerdem gibt es jetzt Farb-, Schriftart- und Größenanpassungs -funktionen.
(Update - 22-12-18/15:38)
Was könnte man so alles an meiner "Wer hat an der Uhr gedreht"(TimeGadget) -Version noch alles verbessern ?
Hier kommt ein kleines Update.
Das mit den PopUp-Menü habe ich verworfen und Pfeile sucht man vergebens, aber man darf das Scrollrad verwenden.
Es dürfen nur Zahlen(0-9) und das Zeichen(:) eingegeben werden.
Außerdem gibt es jetzt Farb-, Schriftart- und Größenanpassungs -funktionen.
Code: Alles auswählen
;My Time-Gadget-Module
;Code-Name: "PinkPanther"
DeclareModule TimeGadget
ImportC ""
time(time_t = #Null)
localtime(*tm = #Null)
gmtime(time_t.i)
EndImport
Structure TTimeValue
second.l
minute.l
hour.l
mday.l
mon.l
year.l
wday.l
yday.l
isdst.l
EndStructure
Structure TCursor
pos.i
fpos.i
cheight.i
cwidth.i
length.i
EndStructure
Structure TTimeInput
gid.i
value.s
length.i
isfocus.b
center.b
x.i
y.i
h.i
w.i
bgcolor.i
fgcolor.i
font.i
time.TTimeValue
cursor.TCursor
EndStructure
Declare.i TimeGadget(gid.i, xpos.i, ypos.i, width.i, height.i, timeStr.s, flag.i = 0)
Declare TimeGadget_Destroy(*pTimeGadget.TTimeInput)
Declare TimeGadget_Event(*pTimeGadget.TTimeInput, Win.i, WindowEvent.i)
Declare TimeGadget_Update(*pTimeGadget.TTimeInput, show_cursor.b = #False)
Declare.i TimeGadget_GetHour(*pTimeGadget.TTimeInput)
Declare.i TimeGadget_GetMinute(*pTimeGadget.TTimeInput)
Declare.i TimeGadget_GetSecond(*pTimeGadget.TTimeInput)
Declare.s TimeGadget_GetTimeString(*pTimeGadget.TTimeInput)
Declare TimeGadget_SetTimeString(*pTimeGadget.TTimeInput, timeStr.s)
Declare TimeGadget_SetHour(*pTimeGadget.TTimeInput, hour.i)
Declare TimeGadget_SetMinute(*pTimeGadget.TTimeInput, minute.i)
Declare TimeGadget_SetSecond(*pTimeGadget.TTimeInput, second.i)
Declare.i TimeGadget_GetCursorPosition(*pTimeGadget.TTimeInput)
Declare TimeGadget_ChangeTime(*pTimeGadget.TTimeInput, pos.i, down.b = #False)
Declare TimeGadget_Resize(*pTimeGadget.TTimeInput, x, y, w, h)
Declare TimeGadget_SetLocalTime(*pTimeGadget.TTimeInput)
Declare TimeGadget_SetUTCTime(*pTimeGadget.TTimeInput)
Declare TimeGadget_ChangeFont(*pTimeGadget.TTimeInput, font_nr.i)
Declare TimeGadget_ChangeColor(*pTimeGadget.TTimeInput, bgcolor.i, fgcolor.i = 0)
Declare TimeGadget_SetEvent_MenuExceptions(Map MenuExceptions())
EndDeclareModule
Module TimeGadget
Global AClockWin.i
Global NewMap MenuExceptions.i()
Procedure TimeGadget_GetHour(*pTimeGadget.TTimeInput)
Protected.i regex, pass.b = #False, h, rh
If IsGadget(*pTimeGadget\gid)
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, *pTimeGadget\value)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
h = Val(StringField(*pTimeGadget\value, 1, ":"))
If h < 24 And h >= 0
rh = h
ProcedureReturn rh
EndIf
EndIf
EndIf
ProcedureReturn -1
EndProcedure
Procedure TimeGadget_GetMinute(*pTimeGadget.TTimeInput)
Protected.i regex, pass.b = #False, m, rm
If IsGadget(*pTimeGadget\gid)
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, *pTimeGadget\value)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
m = Val(StringField(*pTimeGadget\value, 2, ":"))
If m < 60 And m >= 0
rm = m
ProcedureReturn rm
EndIf
EndIf
EndIf
ProcedureReturn -1
EndProcedure
Procedure TimeGadget_GetSecond(*pTimeGadget.TTimeInput)
Protected.i regex, pass.b = #False, s, rs
If IsGadget(*pTimeGadget\gid)
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, *pTimeGadget\value)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
s = Val(StringField(*pTimeGadget\value, 3, ":"))
If s < 60 And s >= 0
rs = s
ProcedureReturn rs
EndIf
EndIf
EndIf
ProcedureReturn -1
EndProcedure
Procedure.s TimeGadget_GetTimeString(*pTimeGadget.TTimeInput)
If IsGadget(*pTimeGadget\gid)
ProcedureReturn *pTimeGadget\value
Else
ProcedureReturn "-1"
EndIf
EndProcedure
Procedure TimeGadget_SetTimeString(*pTimeGadget.TTimeInput, timeStr.s)
Protected.i regex, h, s.s, pass.b = #False
If IsGadget(*pTimeGadget\gid)
regex = CreateRegularExpression(#PB_Any, "[0-2][0-9]:[0-5][0-9]:[0-5][0-9]")
If regex
ExamineRegularExpression(regex, timeStr)
While NextRegularExpressionMatch(regex)
pass = #True
Wend
FreeRegularExpression(regex)
EndIf
If pass = #True
h = Val(StringField(timeStr, 1, ":"))
s = StringField(timeStr, 3, ":")
If h < 24 And h >= 0 And Len(s) = 2
*pTimeGadget\value = timeStr
Else
*pTimeGadget\value = "00:00:00"
EndIf
Else
*pTimeGadget\value = "00:00:00"
EndIf
EndIf
EndProcedure
Procedure TimeGadget_SetHour(*pTimeGadget.TTimeInput, hour.i)
Protected ntimeStr.s
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
If hour >= 0 And hour < 24
\time\hour = hour
\time\minute = TimeGadget_GetMinute(*pTimeGadget)
\time\second = TimeGadget_GetSecond(*pTimeGadget)
ntimeStr = RSet(Str(\time\hour), 2, "0") + ":" + RSet(Str(\time\minute), 2, "0") + ":" + RSet(Str(\time\second), 2, "0")
TimeGadget_SetTimeString(*pTimeGadget, ntimeStr)
EndIf
EndWith
EndIf
EndProcedure
Procedure TimeGadget_SetMinute(*pTimeGadget.TTimeInput, minute.i)
Protected ntimeStr.s
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
If minute >= 0 And minute < 60
\time\hour = TimeGadget_GetHour(*pTimeGadget)
\time\minute = minute
\time\second = TimeGadget_GetSecond(*pTimeGadget)
ntimeStr = RSet(Str(\time\hour), 2, "0") + ":" + RSet(Str(\time\minute), 2, "0") + ":" + RSet(Str(\time\second), 2, "0")
TimeGadget_SetTimeString(*pTimeGadget, ntimeStr)
EndIf
EndWith
EndIf
EndProcedure
Procedure TimeGadget_SetSecond(*pTimeGadget.TTimeInput, second.i)
Protected ntimeStr.s
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
If second >= 0 And second < 60
\time\hour = TimeGadget_GetHour(*pTimeGadget)
\time\minute = TimeGadget_GetMinute(*pTimeGadget)
\time\second = second
ntimeStr = RSet(Str(\time\hour), 2, "0") + ":" + RSet(Str(\time\minute), 2, "0") + ":" + RSet(Str(\time\second), 2, "0")
TimeGadget_SetTimeString(*pTimeGadget, ntimeStr)
EndIf
EndWith
EndIf
EndProcedure
Procedure TimeGadget_ChangeTime(*pTimeGadget.TTimeInput, pos.i, down.b = #False)
Protected.i aSec = 0, aMin = 0, aHrs = 0
If IsGadget(*pTimeGadget\gid)
If pos >= 0 And pos < 3
aHrs = TimeGadget_GetHour(*pTimeGadget)
If down = #False And aHrs > -1
TimeGadget_SetHour(*pTimeGadget, aHrs + 1)
ElseIf down = #True And aHrs > 0
TimeGadget_SetHour(*pTimeGadget, aHrs - 1)
EndIf
ElseIf pos > 2 And pos < 6
aMin = TimeGadget_GetMinute(*pTimeGadget)
If down = #False And aMin > -1
TimeGadget_SetMinute(*pTimeGadget, aMin + 1)
ElseIf down = #True And aMin > 0
TimeGadget_SetMinute(*pTimeGadget, aMin - 1)
EndIf
ElseIf pos > 5 And pos < 9
aSec = TimeGadget_GetSecond(*pTimeGadget)
If down = #False And aSec > -1
TimeGadget_SetSecond(*pTimeGadget, aSec + 1)
ElseIf down = #True And aSec > 0
TimeGadget_SetSecond(*pTimeGadget, aSec - 1)
EndIf
EndIf
EndIf
EndProcedure
Procedure TimeGadget_GetInputPosition(*pTimeGadget.TTimeInput, x.i, y.i)
Protected mouse_x.d, mouse_y.d, min_distance.d = Infinity(), distance.d, cursor_pos.i, cursor_x.i, cursor_y.i, i.i
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
mouse_x = GetGadgetAttribute(\gid, #PB_Canvas_MouseX)
mouse_y = GetGadgetAttribute(\gid, #PB_Canvas_MouseY)
\length = Len(\value)
StartDrawing(CanvasOutput(\gid))
cursor_y = y + TextHeight(\value) / 2
For i = 0 To \length
cursor_x = x + TextWidth(Left(\value, i))
distance = (mouse_x - cursor_x) * (mouse_x - cursor_x) + (mouse_y - cursor_y) * (mouse_y - cursor_y)
If distance < min_distance
min_distance = distance
cursor_pos = i
EndIf
Next
StopDrawing()
If Not IsInfinity(min_distance)
ProcedureReturn cursor_pos
Else
ProcedureReturn -1
EndIf
EndWith
ProcedureReturn -1
EndIf
EndProcedure
Procedure TimeGadget_DeleteSelection(*pTimeGadget.TTimeInput)
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
If \cursor\length < 0
\value = Left(\value, \cursor\fpos) + Mid(\value, \cursor\pos + 1)
\cursor\pos = \cursor\fpos
\cursor\length = 0
ProcedureReturn #True
ElseIf \cursor\length > 0
\value = Left(\value, \cursor\pos) + Mid(\value, \cursor\fpos + 1)
\cursor\fpos = \cursor\pos
\cursor\length = 0
ProcedureReturn #True
EndIf
EndWith
EndIf
ProcedureReturn #False
EndProcedure
Procedure TimeGadget_SetLocalTime(*pTimeGadget.TTimeInput)
Protected now.i, *ltime.TTimeValue, timeStr.s
time(@now)
*ltime = localtime(@now)
timeStr = RSet(Str(*ltime\hour),2,"0") + ":"+ RSet(Str(*ltime\minute),2,"0") + ":" + RSet(Str(*ltime\second),2,"0")
TimeGadget_SetTimeString(*pTimeGadget, timeStr)
EndProcedure
Procedure TimeGadget_SetUTCTime(*pTimeGadget.TTimeInput)
Protected now.i, *utime.TTimeValue, timeStr.s
time(@now)
*utime = gmtime(@now)
timeStr = RSet(Str(*utime\hour),2,"0") + ":"+ RSet(Str(*utime\minute),2,"0") + ":" + RSet(Str(*utime\second),2,"0")
TimeGadget_SetTimeString(*pTimeGadget, timeStr)
EndProcedure
Procedure DrawClock(*pTimeGadget.TTimeInput, gid)
Protected.i hour, minute, ufont
Protected.i h, m, s
h = TimeGadget_GetHour(*pTimeGadget)
m = TimeGadget_GetMinute(*pTimeGadget)
s = TimeGadget_GetSecond(*pTimeGadget)
StartVectorDrawing(CanvasVectorOutput(gid))
VectorSourceColor(RGBA(0, 0, 0, 255))
MovePathCursor(0, 0)
AddPathCircle(50, 50, 50)
FillPath()
StrokePath(1)
ClosePath()
ufont = LoadFont(#PB_Any, "Times", 8)
VectorFont(FontID(ufont))
;Stunden-Ziffern
For hour = 1 To 12
ux = 50 + Sin(Radian(360/12*hour)) * 40 - VectorTextWidth(Str(hour))/2
uy = 50 + -Cos(Radian(360/12*hour)) * 40 - VectorTextHeight(Str(hour))/2
VectorSourceColor(RGBA(255, 255, 255, 255))
MovePathCursor(ux, uy)
DrawVectorText(Str(hour))
Next
;Minuten/Sekunden
For minute = 1 To 60
ux = 50 + Sin(Radian(360/60*minute)) * 40
uy = 50 + -Cos(Radian(360/60*minute)) * 40
Next
;(Die Uhr wird auf 360 Grad (12 Uhr) oben eingestellt!)
;Die Zeiger:
;Degree = 360 / Anzahl_Ziffern * Aktuelle_Ziffer
;x = mitte_x + Sin(Rad(Degree)) * radius
;y = mitte_y + -Cos(Rad(Degree)) * radius
;Stundenzeiger
ux = 50 + Sin(Radian(360/12*(h+(m/60)))) * 30
uy = 50 + -Cos(Radian(360/12*(h+(m/60)))) * 30
MovePathCursor(50, 50)
AddPathLine(ux, uy)
StrokePath(3)
ClosePath()
;Minutenzeiger
ux = 50 + Sin(Radian(360/60*m)) * 40
uy = 50 + -Cos(Radian(360/60*m)) * 40
MovePathCursor(50, 50)
AddPathLine(ux, uy)
StrokePath(2)
ClosePath()
;Sekundenzeiger
ux = 50 + Sin(Radian(360/60*s)) * 40
uy = 50 + -Cos(Radian(360/60*s)) * 40
MovePathCursor(50, 50)
AddPathLine(ux, uy)
StrokePath(1)
ClosePath()
StopVectorDrawing()
EndProcedure
Procedure TimeGadget_ShowAnalog(*pTimeGadget.TTimeInput)
Protected.i mouse_x, mouse_y, cav
If IsGadget(*pTimeGadget\gid)
ExamineDesktops()
mouse_x = DesktopMouseX()
mouse_y = DesktopMouseY()
AClockWin = OpenWindow(#PB_Any, mouse_x, mouse_y, 100, 100, "", #PB_Window_BorderLess)
If AClockWin <> 0
cav = CanvasGadget(#PB_Any, 0, 0, 100, 100)
DrawClock(*pTimeGadget, cav)
EndIf
EndIf
EndProcedure
Procedure TimeGadget_SetEvent_MenuExceptions(Map vMenuExceptions())
CopyMap(vMenuExceptions(), MenuExceptions())
EndProcedure
Procedure TimeGadget_Event(*pTimeGadget.TTimeInput, Win.i, WindowEvent.i)
Protected evt.b = #False
Protected cursor_pos.i
Protected afocus.b = #False
Protected select_mode.b = #False
Protected regex.i
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
Select WindowEvent
Case #PB_Event_Menu
If GetActiveGadget() = \gid
ForEach MenuExceptions()
If Str(EventMenu()) = MapKey(MenuExceptions())
Select MenuExceptions()
Case #PB_Shortcut_Left
If \cursor\pos > 0 : \cursor\pos - 3 : EndIf
evt = #True
Case #PB_Shortcut_Right
If \cursor\pos < Len(\value) : \cursor\pos + 3 : EndIf
evt = #True
Case #PB_Shortcut_Down
TimeGadget_ChangeTime(*pTimeGadget, \cursor\pos, #True)
evt = #True
Case #PB_Shortcut_Up
TimeGadget_ChangeTime(*pTimeGadget, \cursor\pos, #False)
evt = #True
Case #PB_Shortcut_End
\cursor\pos = Len(\value)
evt = #True
Case #PB_Shortcut_Home
\cursor\pos = 0
evt = #True
Case #PB_Shortcut_Back
If Not TimeGadget_DeleteSelection(*pTimeGadget)
If \cursor\pos > 0
\value = Left(\value, \cursor\pos - 1) + Mid(\value, \cursor\pos + 1)
\cursor\pos - 1
EndIf
EndIf
evt = #True
Case #PB_Shortcut_Delete
If Not TimeGadget_DeleteSelection(*pTimeGadget)
If \cursor\pos < Len(\value)
\value = Left(\value, \cursor\pos) + Mid(\value, \cursor\pos + 2)
EndIf
EndIf
evt = #True
EndSelect
EndIf
Next
EndIf
Case #PB_Event_Gadget
If EventGadget() = \gid
Select EventType()
Case #PB_EventType_LeftButtonDown
If \center = #True
cursor_pos = TimeGadget_GetInputPosition(*pTimeGadget, (\w / 2)-(\cursor\cwidth / 2), (\h / 2)-(\cursor\cheight / 2))
Else
cursor_pos = TimeGadget_GetInputPosition(*pTimeGadget, 2, (\h / 2)-(\cursor\cheight / 2))
EndIf
If cursor_pos <> -1
If cursor_pos < 3
cursor_pos = 1
ElseIf cursor_pos > 2 And cursor_pos < 6
cursor_pos = 4
ElseIf cursor_pos > 5 And cursor_pos < 9
cursor_pos = 7
EndIf
\cursor\pos = cursor_pos - 1
\cursor\fpos = cursor_pos - 1
\cursor\length = 2
evt = #True
Else
\cursor\length = 0
EndIf
Case #PB_EventType_RightButtonDown
If AClockWin = 0
TimeGadget_ShowAnalog(*pTimeGadget)
ElseIf AClockWin <> 0
CloseWindow(AClockWin)
AClockWin = 0
EndIf
Case #PB_EventType_RightButtonUp
If AClockWin <> 0
CloseWindow(AClockWin)
AClockWin = 0
EndIf
Case #PB_EventType_MouseWheel
If GetGadgetAttribute(\gid, #PB_Canvas_WheelDelta) = 1
TimeGadget_ChangeTime(*pTimeGadget, \cursor\pos, #False)
ElseIf GetGadgetAttribute(\gid, #PB_Canvas_WheelDelta) = -1
TimeGadget_ChangeTime(*pTimeGadget, \cursor\pos, #True)
EndIf
Case #PB_EventType_Focus
\isfocus = #True
Case #PB_EventType_LostFocus
\isfocus = #False
\cursor\length = 0
Case #PB_EventType_LeftButtonUp
select_mode = #False
Case #PB_EventType_Input
regex = CreateRegularExpression(#PB_Any, "[0-9 :]")
If regex
ExamineRegularExpression(regex, Chr(GetGadgetAttribute(\gid, #PB_Canvas_Input)))
If Not NextRegularExpressionMatch(regex)
Debug "Input Error!"
ElseIf Len(\value) <= 8
If TimeGadget_DeleteSelection(*pTimeGadget)
\value = Left(\value, \cursor\pos) + Chr(GetGadgetAttribute(\gid, #PB_Canvas_Input)) + Mid(\value, \cursor\pos + 3)
If Len(\value) > 8
\value = Left(Left(\value, \cursor\pos) + Chr(GetGadgetAttribute(\gid, #PB_Canvas_Input)) + Mid(\value, \cursor\pos + 1), Len(\value)-1)
EndIf
Else
\value = Left(\value, \cursor\pos) + Chr(GetGadgetAttribute(\gid, #PB_Canvas_Input)) + Mid(\value, \cursor\pos + 1)
If Len(\value) > 8
\value = Left(Left(\value, \cursor\pos) + Chr(GetGadgetAttribute(\gid, #PB_Canvas_Input)) + Mid(\value, \cursor\pos + 1), Len(\value)-1)
EndIf
EndIf
\cursor\pos + 1
EndIf
FreeRegularExpression(regex)
EndIf
evt = #True
Case #PB_EventType_KeyDown
Select GetGadgetAttribute(\gid, #PB_Canvas_Key)
Case #PB_Shortcut_Left
If \cursor\pos > 0 : \cursor\pos - 3 : EndIf
evt = #True
Case #PB_Shortcut_Right
If \cursor\pos < Len(\value) : \cursor\pos + 3 : EndIf
evt = #True
Case #PB_Shortcut_Down
TimeGadget_ChangeTime(*pTimeGadget, \cursor\pos, #True)
evt = #True
Case #PB_Shortcut_Up
TimeGadget_ChangeTime(*pTimeGadget, \cursor\pos, #False)
evt = #True
Case #PB_Shortcut_End
\cursor\pos = Len(\value)
evt = #True
Case #PB_Shortcut_Home
\cursor\pos = 0
evt = #True
Case #PB_Shortcut_Back
If Not TimeGadget_DeleteSelection(*pTimeGadget)
If \cursor\pos > 0
\value = Left(\value, \cursor\pos - 1) + Mid(\value, \cursor\pos + 1)
\cursor\pos - 1
EndIf
EndIf
evt = #True
Case #PB_Shortcut_Delete
If Not TimeGadget_DeleteSelection(*pTimeGadget)
If \cursor\pos < Len(\value)
\value = Left(\value, \cursor\pos) + Mid(\value, \cursor\pos + 2)
EndIf
EndIf
evt = #True
EndSelect
EndSelect
EndIf
EndSelect
EndWith
EndIf
EndProcedure
Procedure GetCursorPosition(*pTimeGadget.TTimeInput)
ProcedureReturn TextWidth(Left(*pTimeGadget\value, *pTimeGadget\cursor\pos))
EndProcedure
Procedure GetCursorLength(*pTimeGadget.TTimeInput)
ProcedureReturn TextWidth(Left(*pTimeGadget\value, *pTimeGadget\cursor\pos + *pTimeGadget\cursor\length)) - TextWidth(Left(*pTimeGadget\value, *pTimeGadget\cursor\pos))
EndProcedure
Procedure TimeGadget_GetCursorPosition(*pTimeGadget.TTimeInput)
ProcedureReturn *pTimeGadget\cursor\pos
EndProcedure
Procedure TimeGadget_ChangeFont(*pTimeGadget.TTimeInput, font_nr.i)
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
\font = font_nr
EndWith
EndIf
EndProcedure
Procedure TimeGadget_ChangeColor(*pTimeGadget.TTimeInput, bgcolor.i, fgcolor.i = 0)
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
\bgcolor = bgcolor
\fgcolor = fgcolor
EndWith
EndIf
EndProcedure
Procedure TimeGadget_Update(*pTimeGadget.TTimeInput, show_cursor.b = #False)
Protected.i a
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
StartDrawing(CanvasOutput(\gid))
DrawingMode(#PB_2DDrawing_Default)
If IsFont(\font)
DrawingFont(FontID(\font))
EndIf
\cursor\cheight = TextHeight(\value)
\cursor\cwidth = TextWidth(\value)
Box(0, 0, \w, \h, \bgcolor)
If \center = #True
DrawText((\w / 2)-(TextWidth(\value) / 2), (\h / 2)-(TextHeight(\value) / 2), \value, \fgcolor, \bgcolor)
Else
DrawText(2, (\h / 2)-(TextHeight(\value) / 2), \value, \fgcolor, \bgcolor)
EndIf
DrawingMode(#PB_2DDrawing_XOr)
If \cursor\length < 0
If \center = #True
Box((\w / 2)-(TextWidth(\value) / 2) + GetCursorPosition(*pTimeGadget) + GetCursorLength(*pTimeGadget), (\h / 2)-(TextHeight(\value) / 2), -GetCursorLength(*pTimeGadget), TextHeight(" "))
Else
Box(2 + GetCursorPosition(*pTimeGadget) + GetCursorLength(*pTimeGadget), (\h / 2)-(TextHeight(\value) / 2), -GetCursorLength(*pTimeGadget), TextHeight(" "))
EndIf
ElseIf \cursor\length > 0
If \center = #True
Box((\w / 2)-(TextWidth(\value) / 2) + GetCursorPosition(*pTimeGadget) + 1, (\h / 2)-(TextHeight(\value) / 2), GetCursorLength(*pTimeGadget) - 1, TextHeight(" "))
Else
Box(2 + GetCursorPosition(*pTimeGadget) + 1, (\h / 2)-(TextHeight(\value) / 2), GetCursorLength(*pTimeGadget) - 1, TextHeight(" "))
EndIf
EndIf
DrawingMode(#PB_2DDrawing_Default)
If show_cursor = #True And \isfocus = #True
If \center = #True
Line((\w / 2)-(TextWidth(\value) / 2) + GetCursorPosition(*pTimeGadget), (\h / 2)-(TextHeight(\value) / 2), 1, TextHeight(" "), RGB(0,0,0))
Else
Line(2 + GetCursorPosition(*pTimeGadget), (\h / 2)-(TextHeight(\value) / 2), 1, TextHeight(" "), RGB(0,0,0))
EndIf
EndIf
StopDrawing()
EndWith
EndIf
EndProcedure
Procedure TimeGadget_Resize(*pTimeGadget.TTimeInput, x, y, w, h)
If IsGadget(*pTimeGadget\gid)
With *pTimeGadget
If x <> #PB_Ignore And x > 0
\x = x
EndIf
If y <> #PB_Ignore And y > 0
\y = y
EndIf
If w <> #PB_Ignore And w > 0
\w = w
EndIf
If h <> #PB_Ignore And h > 0
\h = h
EndIf
ResizeGadget(*pTimeGadget\gid, \x, \y, \w, \h)
TimeGadget_Update(*pTimeGadget)
EndWith
EndIf
EndProcedure
;Time-Gadget-Constructor
Procedure.i TimeGadget(gid.i, xpos.i, ypos.i, width.i, height.i, timeStr.s, flag.i = 0)
Protected *pTimeGadget.TTimeInput = AllocateMemory(SizeOf(TTimeInput))
Protected pid.i, k.i
pid = CanvasGadget(gid, xpos, ypos, width, height, #PB_Canvas_Border|#PB_Canvas_Keyboard)
If pid <> 0
If gid = -1
SetGadgetAttribute(pid, #PB_Canvas_Cursor, #PB_Cursor_IBeam)
Else
SetGadgetAttribute(gid, #PB_Canvas_Cursor, #PB_Cursor_IBeam)
EndIf
With *pTimeGadget
If gid = -1
\gid = pid
Else
\gid = gid
EndIf
\x = xpos
\y = ypos
\h = height
\w = width
If flag = 0
;auto-center
\center = #True
Else
;no-center
\center = #False
EndIf
\font = -1
\bgcolor = RGB(255,255,255)
\fgcolor = RGB(0,0,0)
EndWith
TimeGadget_SetTimeString(*pTimeGadget, timeStr)
ProcedureReturn *pTimeGadget
EndIf
ProcedureReturn -1
EndProcedure
;Time-Gadget-Destructor
Procedure TimeGadget_Destroy(*pTimeGadget.TTimeInput)
If IsGadget(*pTimeGadget\gid)
FreeGadget(*pTimeGadget\gid)
FreeMemory(*pTimeGadget)
EndIf
EndProcedure
EndModule
Enumeration
#Win
#ControlTimer
#SecondTimer
EndEnumeration
UseModule TimeGadget
Global *vTimeGadget.TTimeInput, atimeStr.s
Global *vTimeGadget2.TTimeInput
If OpenWindow(#Win, 0, 0, 200, 100, "Time-Control", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
atimeStr = RSet(Str(Hour(Date())), 2, "0") + ":" + RSet(Str(Minute(Date())), 2, "0") + ":" + RSet(Str(Second(Date())), 2, "0")
*vTimeGadget = TimeGadget(0, 10, 10, 80, 20, "00:00:00", #True)
;Debug *vTimeGadget
*vTimeGadget2 = TimeGadget(1, 10, 50, 80, 20, "00:00:00")
;Debug *vTimeGadget2
TimeGadget_SetTimeString(*vTimeGadget, atimeStr)
TimeGadget_ChangeColor(*vTimeGadget, RGB(0,0,0), RGB(255, 255, 0))
TimeGadget_ChangeColor(*vTimeGadget2, RGB(255,255,0))
LoadFont(0, "ComicSansMS", 14)
TimeGadget_ChangeFont(*vTimeGadget2, 0)
TimeGadget_Resize(*vTimeGadget2, 10, 40, 180, 50)
;TimeGadget_SetLocalTime(*vTimeGadget2)
TimeGadget_SetUTCTime(*vTimeGadget2)
;Beim Shortcut-Problem ...
AddKeyboardShortcut(#Win, #PB_Shortcut_Right, 1)
AddKeyboardShortcut(#Win, #PB_Shortcut_Left, 2)
AddKeyboardShortcut(#Win, #PB_Shortcut_Up, 3)
AddKeyboardShortcut(#Win, #PB_Shortcut_Down, 4)
;.. muss/sollte/kann eine Ausnahmeliste erstellt werden!
NewMap ExMenuItem.i()
ExMenuItem("1") = #PB_Shortcut_Right
ExMenuItem("2") = #PB_Shortcut_Left
ExMenuItem("3") = #PB_Shortcut_Up
ExMenuItem("4") = #PB_Shortcut_Down
TimeGadget_SetEvent_MenuExceptions(ExMenuItem())
AddWindowTimer(#Win, #ControlTimer, 200)
AddWindowTimer(#Win, #SecondTimer, 1000) ;Durch Deaktivieren\Kommentieren läuft die Zeit nicht weiter !
Repeat
event = WaitWindowEvent()
If TimeGadget_Event(*vTimeGadget, #Win, event)
TimeGadget_Update(*vTimeGadget, #False)
EndIf
If TimeGadget_Event(*vTimeGadget2, #Win, event)
TimeGadget_Update(*vTimeGadget2, #False)
EndIf
Select event
Case #PB_Event_Menu
;Test!
If EventMenu() = 1 Or EventMenu() = 2 Or EventMenu() = 3 Or EventMenu() = 4
Debug "Key-Exception!"
EndIf
Case #PB_Event_CloseWindow
End
Case #PB_Event_Timer
Select EventTimer()
Case #ControlTimer
TimeGadget_Update(*vTimeGadget, #True)
TimeGadget_Update(*vTimeGadget2, #True)
Case #SecondTimer
atimeStr = RSet(Str(Hour(Date())), 2, "0") + ":" + RSet(Str(Minute(Date())), 2, "0") + ":" + RSet(Str(Second(Date())), 2, "0")
TimeGadget_SetTimeString(*vTimeGadget, atimeStr)
EndSelect
EndSelect
ForEver
TimeGadget_Destroy(*vTimeGadget)
TimeGadget_Destroy(*vTimeGadget2)
EndIf
UnuseModule TimeGadget
Was könnte man so alles an meiner "Wer hat an der Uhr gedreht"(TimeGadget) -Version noch alles verbessern ?
Zuletzt geändert von ccode_new am 22.12.2018 16:39, insgesamt 1-mal geändert.
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
no Keyboard, press any key
no mouse, you need a cat