"Gadget(s)" für Zeiteingabe gesucht

Für allgemeine Fragen zur Programmierung mit PureBasic.
Omi
Beiträge: 143
Registriert: 25.03.2013 09:59

Re: "Gadget(s)" für Zeiteingabe gesucht

Beitrag von Omi »

Sodele, das 'TimeGadget' liegt in einer PB-Gadget-ähnlichen, Multi-OS Form vor für Linux Gtk2/Gtk3, MacOS und Windows und heißt jetzt
  • TimePickerGadget
Bedienung, Möglichkeiten und Flags sind etwas OS-abhängig - dies ist aber beim PB-DateGadget nicht anders!

Shardik hat sich (trotz ausgefallenem Weihnachtsurlaub) mächtig reingehängt und den MacOS-Teil angepasst sowie das Ganze auch noch in Module-Form gebracht.

Vom Umfang geht es z.Zt. etwas in Richtung amerikanischer SUV (= Deutscher Gigaliner) ;-) - aber wir hamm's ja.

- Das 'TimePickerGadget' (hält namentlich PureBasic den Weg für ein 'TimeGadget' frei) wird ähnlich zu PB-Gadgets angelegt.
Details sind im Header des Sourcecodes zu ersehen!
- Die zusätzliche Angabe des Parameters #Window ist jedoch zwingend (und wie ich beim Tippen dieser Zeilen grad merke wird hier auch (noch) kein #PB_Any akzeptiert!).
- Der Parameter #Gadget kann eine PBNo/Konstante (> -1) oder #PB_Any sein. (#Gadget kann als Dummy zur Erstellung verwendet werden, wird aber später nicht mehr benötigt!)
- Für lesende oder schreibende Zugriffe auf das Gadget (s.u.) wird nicht die PB-GadgetNo (ala #Gadget) sondern der Zeiger/OS-Handle auf das OS-Objekt benötigt! (ala GadgetID), da im MacOS keinerlei Dummy-PB-Gadget dafür existiert!
- Lesen und Schreiben einer Uhrzeit (Tageszeit als String oder Sekunden seit der vergangenen Mitternacht) geschieht mit ...
  • GetTimePickerGadgetState(GadgetId)
    GetTimePickerGadgetText(GadgetId)
    SetTimePickerGadgetState(GadgetId, TimeVal)
    SetTimePickerGadgetText(GadgetId, sTimeString.s) als formatierter String im Format #TPG_TimeMask24h (= "%hh:%ii:%ss")
- Änderungen am TimePickerGadget lösen ein Event vom EventType: #PB_EventType_Change aus
- Ich hab noch einige OS-abhängigen Flags und Konstanten dafür integriert, siehe im Code-Header.
- Der Zugriff auf die Funktionen erfolgt (bei Verwendung von UseModule TimePickerGadget mit den Funktionsnamen,
ohne Verwendung von UseModule TimePickerGadget mit, den Funktionsaufrufen vorangestelltem TimePickerGadget::). Siehe auch in der folgenden Demo.

TimePickerGadget-Modul, All OS, eingebettet in einen Democode mit 2 Gadgets auf 2 Fenster verteilt: V0.21, 2018-01-20

Code: Alles auswählen

; Module/File:     TimePickerGadget_AllOS_V0_21.pb
; Function:        Gadget to edit, set and get time as module
; Author:          Teamwork: Omi + Shardik + others (netmaestro, PB, ..)
; Date:            Jan. 19, 2019
; Version:         0.21
; Target OS:       Windows, Linux Gtk2/Gtk3, MacOS
; Target Compiler: PureBasic 5.46/5.62/5.70
;                  Compilation on MacOS 10.6.8 (Snow Leopard) with PB 5.46/5.62 only possible with x86 compiler
;                  Last version supporting x64 compilation on Snow Leopard was PB 5.43
;                  Minimum MacOS version for 5.70 x86 + x64: 10.8 (Mountain Lion)
; Links to topic:  https://www.purebasic.fr/german/viewtopic.php?f=3&t=31214
;                  https://www.purebasic.fr/english/viewtopic.php?f=12&t=23797
;                  https://www.purebasic.fr/english/viewtopic.php?t=33184
;                  https://www.purebasic.fr/english/viewtopic.php?f=3&t=30025
;--------------------------------------------------------------

;V0.10 : Access with Gadget constant & GadgetNo (no Id)
;V0.11 : Access with var for GadgetId & GadgetId (no No/#Gadget)
;V0.12 : Trial to adapt and complete the Mac part
;V0.13 : 2 different module accesses in EventLoop with and without UseModule TimePickerGadget
;V0.14 : #PB_Any now works as #Gadget for TimePickerGadget
;V0.15 : Mac part bugs fixed:
;        - GetTimePickerGadgetState(): Time had to be extracted from sCurrentDate and
;          ProcedureReturn Mid(sCurrentDate, 11, 9)
;          had to be changed to
;          ProcedureReturn TimeVal
;        - TimePickerGadget(): Date and time offset had to be added to sTime
;        - SetTimePickerGadgetText(): Date and time offset had to be added to sTimeString
;        - SetTimePickerGadgetState(): Date and time offset had to be added to sTime and sTime
;        General Mac problems still to be solved:
;        - Cocoa class NSDate needs time offset to UTC: currently staticly set to
;          +01:00 for German timezone (Berlin)
;        - Callback integration still necessary to update the TextGadgets "Time set:" and "Time value set (=seconds):"
;V0.16 : MacOS callback implemented
;V0.17 : Added missing debug warnings on not available flags. Flag names corrected in warnings.
;V0.18 : MacOS Sierra bug fix: in GetTimePickerGadgetState(GadgetId) und GetTimePickerGadgetText(GadgetId) one hour
;        UTC correction had to be added (currently correct only in German timezone!), but now Snow Leopard display wrong time!
;V0.19 : For MacOS automatic detection of UTC offset implemented
;        Detection of MacOS version added to add UTC offset only in Get-Procedures for versions newer than Snow Leopard
;V0.20 : Now #PB_Any instead of GadgetNo for second window for demo part
;        Shardik: Fixed Windows issue on Ascii-executable
;                 Added Flag #TPG_Time_BorderLess for MacOS
;V0.21 : Fixed Flag names and some (now wrong) hints in this description and the code + tidy up a bit
;        Changed for Win: Callback_Window_Main() to Callback_Window() cause now it applies to all windows


;T e r m s:
;GadgetNo: PB-No for the Gadget, like #Gadget (here i.e. #TimeGadget1) or the Return from Gadget creation with #PB_Any
;GadgetId: Pointer to the API control/widget/object like GadgetID(GadgetNo), *widget, ...

;C r e a t e Gadget for Module-Version (without 'UseModule TimePickerGadget' use prefixed 'TimePickerGadget::'):
; *GadgetId= TimePickerGadget(GadgetNo, x, y, w, h, sTime.s, WindowNo, Flags)
; P a r a m e t e r s:
; GadgetNo: Can be a valid constant number (but nor necessary) AND #PB_Any
; x,y,w,h : Coordinates as usual
; sTime   : Time as valid string. From 00:00:00 to 23:59:59, for Windows #TPG_Time_12h format too !!! (it's auto converted)
; WindowNo: The PB #Window number (not WindowId or Result)
; Flags   : see below
; -> USE ONLY THE RETURNED POINTER (*GadgetId) FOR ACCESS !!! (here *gTimeGadget1 or *gTimeGadget2)

;A c c e s s for Module-Version (without 'UseModule TimePickerGadget' use prefixed 'TimePickerGadget::'):
; Use the pointer (here *gTimeGadget1 or *gTimeGadget2) as GadgetID for access ....
; - GetTimePickerGadgetState(GadgetID);                                        Equivalent to GetGadgetState(#Gadget)
;   : Provides the time as TimeValue
; - SetTimePickerGadgetState(GadgetID, TimeVal);                               Equivalent to SetGadgetState(#Gadget, State)
;   : Set Gadgets time from TimeValue
; - GetTimePickerGadgetText(GadgetID)                                          Equivalent to GetGadgetText(#Gadget)
;   : Provides the time as formated TimeString, #TPG_TimeMask24h: %hh:%ii:%ss, #TPG_Time_12h too
; - SetTimePickerGadgetText(GadgetID, TimeString.s)                            Equivalent to SetGadgetText(#Gadget, Text$)
;   : Set the Gadgets time as formated TimeString, #TPG_TimeMask24h: %hh:%ii:%ss, #TPG_Time_12h too

;F l a g s for creating (without 'UseModule TimePickerGadget' use prefixed 'TimePickerGadget::'):
; Linux Gtk:
; - #TPG_Time_ReadOnly                                                         Same effect as #PB_String_ReadOnly on StringGadget
; - #TPG_Time_BorderLess                                                       Same effect as #PB_String_BorderLess on StringGadget
; - (#TPG_Time_NoUpDown)                                                       Always ON
; - (#TPG_Time_12h)                                                            Not yet possible
; Mac:
; - (#TPG_Time_ReadOnly?)                                                      Possible ?
; - #TPG_Time_BorderLess?                                                      Gadget w/o border
; - #TPG_Time_NoUpDown                                                         w/o up/down arrows
; - (#TPG_Time_12h)                                                            Seems not possible ?
; Windows:
; - (#TPG_Time_ReadOnly?)                                                      Seems not possible ?
; - #TPG_Time_BorderLess                                                       Gadget w/o border
; - (#TPG_Time_NoUpDown?)                                                      Seems not possible ?
; - #TPG_Time_12h                                                              12h setting w. attached AM/PM segment.
;    -> Time range in Windows AM/PM ...
;       24h: 00:00:00   = 12h: 12:00:00 AM
;       24h: 00:59:59   = 12h: 12:59:59 AM
;       24h: 01:00:00   = 12h: 01:00:00 AM
;       24h: 12:00:00   = 12h: 12:00:00 PM
;       24h: 12:59:59   = 12h: 12:59:59 PM
;       24h: 13:00:00   = 12h: 01:00:00 PM
;       24h: 23:59:59   = 12h: 11:59:59 PM
;   see https://www.timeanddate.com/time/am-And-pm.html

;A d a p t i o n:
; Win: automated
; Lin: automated
; Mac: automated

;E v e n t s:
; Watch (EventType() on) pointer to TimePickerGadget within PB-WindowNo section. Here *gTimeGadget1 or *gTimeGadget2

;C O N T R O L L I N G:
; Flag or feature                                  Linux      Mac      Windows
; ----------------------------------------------------------------------------
; #TPG_Time_ReadOnly                                 +         -          -
; #TPG_Time_BorderLess                               +         +          +
; #TPG_Time_NoUpDown                               always      +          -
; #TPG_Time_12h                                      -         -          +
; Value scrolling with mousewheel over segment       +         -          -
; Value scrolling with mousewheel over arrows        -         -          +
; Value scrolling with key <up>/<down>               +         +          +
; Value scrolling with num pads <+>/<->              +         -          +
; Wrapping on segments value overrun/undershoot      -         ?          +
; Value jumps to segments max. value               <End>       -        <End>
;                                                                       <Home>
; Value jumps to segments min. value (0)           <Home>      -          -
; Value reset (recover format)                     <Esc>       -          -
; Segment selection with mouse click                 +         +          +
; Segment selection with key <left>/<right>          +         +          +
; Wrapping on segment change                         +         -       <Right>
; Segment forwarding                                 -        <->         -
;                                                             </>
;                                                             <,>

;-Init Demo ...
EnableExplicit

; Object constants
Enumeration Windows
	#Win_Main   = 1;                                                             Set to 1 for tests (because 0 is a empty value too)
; 	#Win_Sec;                                                                    2. Window now with #PB_Any for Demo
EndEnumeration

Enumeration Gadgets
	#TimeGadget1= 1;                                                             1. TimePickerGadget with GadgetNo (not needed any longer!)
	#StGMain1
	#TxGMain1
	#TxMainG2
	#BtGMainSet
	
	;#TimeGadget2;                                                                2. TimePickerGadget now with #PB_Any
	#StGSec1
	#TxGSec1
	#TxGSec2
	#BtGSecSet
EndEnumeration

Global.i gEvent, gEventGadget, gEventWin, gQuit;                               For EventLoop
Global   *gTimeGadget1, *gTimeGadget2;                                         GadgetId (see above, pointer is neccessary)
Global.i gWin_Sec;                                                             Instead of #Win_Sec for #PB_Any on Window 2


;- Time Picker module ...
DeclareModule TimePickerGadget
	
	;-{ DeclareModul: TimePickerGadget ...
	
	;Flags for Gadget creation ...
	#Event_TimePickerChanged = #PB_Event_FirstCustomValue
	#TPG_Time_ReadOnly   = 1 << 8;                                               Time not editable. Only Linux
	#TPG_Time_BorderLess = 1 << 9;                                               Display without border (Mac without funktion)
	#TPG_Time_NoUpDown   = 1 << 10;                                              Display without up/down arrow buttons (Linux always on, Windows not available)
	#TPG_Time_12h        = 1 << 11;                                              Display + edit in 12h format 08:00:00 AM | 08:00:00 PM, only Windows
	
	#TPG_TimeMask24h     = "%hh:%ii:%ss"
	#TPG_DebugOn         = #True;                                                Output in Debug window. Set to #False if it's annoying
	
	CompilerSelect #PB_Compiler_OS
			
		CompilerCase #PB_OS_Linux
			
			ImportC ""
				gtk_widget_has_focus             (*widget.GtkWidget)
				gtk_editable_get_selection_bounds(*entry.GtkEntry, *start_pos, *end_pos)
				gtk_entry_set_text               (*entry.GtkEntry, text.p-utf8)
				gtk_entry_get_text               (*entry.GtkEntry)
				gtk_entry_get_text_length        (*entry.GtkEntry)
				gtk_entry_set_alignment          (*entry.GtkEntry, xalign.f)
				g_signal_connect                 (*instance, detailed_signal.p-utf8, *c_handler, *data, destroy= 0, flags= 0) As "g_signal_connect_data"
			EndImport
			
			;from #define __GDK_KEYSYMS_H__
			#GDK_KEY_Up          = $FF52
			#GDK_KEY_Down        = $FF54
			#GDK_KEY_Left        = $FF51
			#GDK_KEY_Right       = $FF53
			#GDK_KEY_Tab         = $FF09
			#GDK_KEY_Escape      = $FF1B
			#GDK_KEY_KP_Add      = $FFAB
			#GDK_KEY_KP_Subtract = $FFAD
			#GDK_KEY_End         = $FF57
			#GDK_KEY_Home        = $FF50
			#GDK_KEY_KP_0        = $FFB0
			#GDK_KEY_KP_9        = $FFB9
			#GDK_KEY_0           = $0030
			#GDK_KEY_9           = $0039
			
			Structure CALLBACKUSERDATA
				GadgetId.i
				WindowNo.i
			EndStructure
			NewList GadgetData.CALLBACKUSERDATA()
			
		CompilerCase #PB_OS_MacOS
			#NSDatePickerStyleTextFieldAndStepper    = 0
			#NSDatePickerStyleTextField              = 2
			#NSHourMinuteSecondDatePickerElementFlag = 14
			
			Structure TimePickerCellEntry
				ID.I
				WindowNo.I
			EndStructure
			NewList TimePickerCell.TimePickerCellEntry()
			
	CompilerEndSelect
	
	Declare.i GetTimePickerGadgetState(GadgetId)
	Declare   SetTimePickerGadgetState(GadgetId, TimeVal)
	Declare.s GetTimePickerGadgetText (GadgetId)
	Declare   SetTimePickerGadgetText (GadgetId, sTimeString.s)
	Declare   TimePickerGadget        (GadgetNo, x, y, w, h, sTime.s, WindowNo, Flags= #Null)
	
	;-} EndDeclareModul: TimePickerGadget ...
	
EndDeclareModule

Module TimePickerGadget
	
	;-{ Modul: TimePickerGadget ...
	
	CompilerSelect #PB_Compiler_OS
			
		CompilerCase #PB_OS_Linux
			
			;-{  _Linux TimePickerGadget API ...
			
			Procedure.i GetTimePickerGadgetState(GadgetId)
				Protected.i TimeVal
				
				TimeVal= ParseDate(#TPG_TimeMask24h, PeekS(gtk_entry_get_text(GadgetId), -1, #PB_UTF8))
				
				ProcedureReturn TimeVal
			EndProcedure
			
			Procedure SetTimePickerGadgetState(GadgetId, TimeVal)
				If TimeVal > -1 And TimeVal < 86400
					gtk_entry_set_text(GadgetId, FormatDate(#TPG_TimeMask24h, TimeVal))
				EndIf
			EndProcedure
			
			Procedure.s GetTimePickerGadgetText(GadgetId)
				Protected.i TimeVal
				Protected.s sTimeString= PeekS(gtk_entry_get_text(GadgetId), -1, #PB_UTF8)
				
				TimeVal= ParseDate(#TPG_TimeMask24h, sTimeString)
				sTimeString= FormatDate(#TPG_TimeMask24h, TimeVal)
				
				ProcedureReturn sTimeString
			EndProcedure
			
			Procedure SetTimePickerGadgetText(GadgetId, sTimeString.s)
				Protected.i TimeVal
				
				If ParseDate(#TPG_TimeMask24h, sTimeString) > -1
					gtk_entry_set_text(GadgetId, sTimeString)
				EndIf
			EndProcedure
			
			Procedure _TimePickerGadget_SelectPart(*widget, Range, Colon1, Colon2);  internal
				Select Range
					Case 1 : gtk_editable_select_region_(*widget, 0,      Colon1 - 1)
					Case 2 : gtk_editable_select_region_(*widget, Colon1, Colon2 - 1)
					Case 3 : gtk_editable_select_region_(*widget, Colon2, -1)
				EndSelect
			EndProcedure
			
			Procedure _TimePickerGadget_CheckInput(*widget.GtkWidget, EditAction, *user_data.CALLBACKUSERDATA);  internal
;				EditAction: 0 = nothing, -1 = scroll-, 1 = scroll+, -2 = lower limit, 2 = upper limit, 3 = number input
				Protected.i cPos, I
				Protected.i cBlock;                                                    0= out, 1 = h, 2 = m, 3 = s
				Protected.s sPart
				Protected.s sTime=   PeekS(gtk_entry_get_text_(*widget), -1, #PB_UTF8), sTime_
				Protected.i Colon1=  FindString(sTime, ":");                           Find separators on existing string
				Protected.i Colon2=  FindString(sTime, ":", Colon1 + 1)
				Static.s    TimeMax= "23:59:59"
				Protected.i hMax=    Val(StringField(TimeMax, 1, ":"))
				Protected.i mMax=    Val(StringField(TimeMax, 2, ":"))
				Protected.i sMax=    Val(StringField(TimeMax, 3, ":"))
				
				If gtk_widget_has_focus(*widget) And gtk_editable_get_editable_(*widget)
					
					cPos= gtk_editable_get_position_(*widget);                           Get cursor offset
					Select cPos;                                                         Specify segment index on existing time string
						Case 0 To Colon1 - 1      : cBlock= 1
						Case Colon1 To Colon2 - 1 : cBlock= 2
						Case Colon2 To Len(sTime) : cBlock= 3
					EndSelect
					
					If EditAction < 3;                                                   All scroll inputs in segment (up/down, +/-, home/end or mouse scrolling) ...
						
						For I= 1 To 3;                                                     Reformat segments
							sTime_+ RSet(Str(Val(StringField(sTime, I, ":"))), 2, "0") + ":"
						Next I
						sTime = RTrim(sTime_, ":")
						Colon1= FindString(sTime, ":");                                    Correct separators on existing string
						Colon2= FindString(sTime, ":", Colon1 + 1)
						gtk_entry_set_text  (*widget, sTime);                              Reformat string
						_TimePickerGadget_SelectPart(*widget, cBlock, Colon1, Colon2);     Set selected segment
						
						sPart= StringField(sTime, cBlock, ":");                            Read segments value under cursor
						Select EditAction;                                                 Calculate new values from scroll inputs
							Case  1 : sPart= Str(Val(sPart) + 1)
							Case -1 : sPart= Str(Val(sPart) - (Bool(Val(sPart) > 0)))
							Case  2 : sPart= StringField(TimeMax, 2, ":");                   will be clipped per segment further down ...
							Case -2 : sPart= "0"
						EndSelect
						
						If cBlock And (Abs(EditAction) = 1 Or Abs(EditAction) = 2);        Monitor and restrict the new values in the segments....
							
							Select cBlock
									
								Case 1
									If Val(sPart) > hMax : sPart = StringField(TimeMax, cBlock, ":") : EndIf
									sTime= RSet(sPart, 2, "0") + ":" + StringField(sTime, 2, ":") + ":" + StringField(sTime, 3, ":")
									gtk_editable_select_region_(*widget, 0,      Colon1 - 1)
									
								Case 2
									If Val(sPart) > mMax : sPart = StringField(TimeMax, cBlock, ":") : EndIf
									sTime= StringField(sTime, 1, ":") + ":" + RSet(sPart, 2, "0") + ":" + StringField(sTime, 3, ":")
									gtk_editable_select_region_(*widget, Colon1, Colon2 - 1)
									
								Case 3
									If Val(sPart) > sMax : sPart = StringField(TimeMax, cBlock, ":") : EndIf
									sTime= StringField(sTime, 1, ":") + ":" + StringField(sTime, 2, ":") + ":" + RSet(sPart, 2, "0")
									gtk_editable_select_region_(*widget, Colon2, -1)
									
							EndSelect
							gtk_entry_set_text  (*widget, sTime)
							_TimePickerGadget_SelectPart(*widget, cBlock, Colon1, Colon2)
							PostEvent(#PB_Event_Gadget, *user_data\WindowNo, *user_data\GadgetId, #PB_EventType_Change)
							
						EndIf
						
					Else;                                                                Value input in segment ...
						
						If cBlock
							
							sPart= StringField(sTime, cBlock, ":");                          Read segments value under cursor
							
							Select cBlock;                                                   Monitor and restrict the newly entered value in the segments....
									Case 1 : If Val(sPart) > hMax : sPart = StringField(TimeMax, cBlock, ":") : sTime= sPart + ":" + StringField(sTime, 2, ":") + ":" + StringField(sTime, 3, ":") : EndIf
									Case 2 : If Val(sPart) > mMax : sPart = StringField(TimeMax, cBlock, ":") : sTime= StringField(sTime, 1, ":") + ":" + sPart + ":" + StringField(sTime, 3, ":") : EndIf
									Case 3 : If Val(sPart) > sMax : sPart = StringField(TimeMax, cBlock, ":") : sTime= StringField(sTime, 1, ":") + ":" + StringField(sTime, 2, ":") + ":" + sPart : EndIf
							EndSelect
							gtk_entry_set_text(*widget, sTime);                              Reformat string
							gtk_editable_set_position_(*widget, cPos);                       Reset cursor position
							PostEvent(#PB_Event_Gadget, *user_data\WindowNo, *user_data\GadgetId, #PB_EventType_Change)
							
						EndIf
						
					EndIf
					
				EndIf
			EndProcedure; TimePickerGadgetCheckInput
			
			ProcedureC Callback_TimePickerGadget_LostFocus(*widget.GtkWidget, *event.GdkEventFocus, *user_data.CALLBACKUSERDATA)
				gtk_editable_select_region_(*widget, 0, 0)
			EndProcedure
			
			ProcedureC Callback_TimePickerGadget_ClickAction(*widget.GtkWidget, *event.GdkEventButton, *user_data.CALLBACKUSERDATA)
				;Protected.i ModKey= *event\state & $F;                                 reserved for bigger jumps with Shift modifier
				
				If *event\type = #GDK_BUTTON_RELEASE
					_TimePickerGadget_CheckInput(*widget, 0, *user_data)
				EndIf
			EndProcedure
			
			ProcedureC Callback_TimePickerGadget_KeyAction(*widget.GtkWidget, *event.GdkEventKey, *user_data.CALLBACKUSERDATA)
				Protected.i ModKey= *event\state & $F;                                 (Required 'modifier keys' masked with low nibble)
				Protected.i KeyVal= *event\keyval
				Protected.i KeyRelease= *event\type
				Protected.i Stop= #False
				Protected.i EditAction= 0
				Protected.i SelStart, SelEnd
				
				gtk_editable_get_selection_bounds(*widget, @SelStart, @SelEnd);        neu 0.12 ...
				If SelEnd - SelStart > 2;                                              destroy wrong selection
					gtk_editable_set_position_(*widget, 1);                              'SelEnd' instead of '1' sets cursor to selection end - if so wanted
					Stop= #True
				EndIf
				
				If KeyRelease = #GDK_KEY_PRESS;                                        push key or button
					
					If ModKey = #Null;                                                   no modifier key
						
						Select KeyVal
								
							Case #GDK_KEY_KP_0 To #GDK_KEY_KP_9, #GDK_KEY_0 To #GDK_KEY_9, #GDK_KEY_Tab; Digits from main- and numeric pad
								
							Case #GDK_KEY_Up, #GDK_KEY_KP_Add;                               Cursor up, NumPad +
								_TimePickerGadget_CheckInput(*widget,  1, *user_data)
								Stop= #True
								
							Case #GDK_KEY_Down, #GDK_KEY_KP_Subtract;                        Cursor down, NumPad -
								_TimePickerGadget_CheckInput(*widget, -1, *user_data)
								Stop= #True
								
							Case #GDK_KEY_End;                                               Upper limit, End
								_TimePickerGadget_CheckInput(*widget,  2, *user_data)
								Stop= #True
								
							Case #GDK_KEY_Home;                                              Lower limit, Home/Pos1
								_TimePickerGadget_CheckInput(*widget, -2, *user_data)
								Stop= #True
								
							Default;                                                         Stop handler for other keys
								Stop= #True
								
						EndSelect
						
					EndIf
					
				EndIf
				
				If KeyRelease = #GDK_KEY_RELEASE;                                      release key or button
					
					If ModKey = #Null;                                                   w/o modifier key
						
						Select KeyVal
								
							Case #GDK_KEY_Escape;                                            <Esc> for emergency reset. Comment out if unwanted
								gtk_entry_set_text(*widget, "12:00:00")
								
							Case #GDK_KEY_Left;                                              Cursor left
								gtk_editable_set_position_(*widget, SelStart - 1)
								
							Case #GDK_KEY_Right;                                             Cursor right
								SelEnd * Bool(Not(SelEnd = gtk_entry_get_text_length(*widget)));  Cursor position on 0 if behind string end
								gtk_editable_set_position_(*widget, SelEnd + 1)
								
							Case #GDK_KEY_KP_0 To #GDK_KEY_KP_9, #GDK_KEY_0 To #GDK_KEY_9;   Digits from main- and numeric pad
								EditAction= 3
								
							Default;                                                         Stop handler for other keys
								Stop= #True
								
						EndSelect
						
					EndIf
					
					If Not Stop
						_TimePickerGadget_CheckInput(*widget, EditAction, *user_data)
					EndIf
					
				EndIf
				
				ProcedureReturn Stop
			EndProcedure
			
			ProcedureC Callback_TimePickerGadget_ScrollBlock(*widget.GtkWidget, *event.GdkEventScroll, *user_data.CALLBACKUSERDATA)
				Protected.GdkEventKey *eventKey= gdk_event_new_(#GDK_KEY_RELEASE)
				
				*eventKey\window= gtk_widget_get_root_window_(*widget)
				*eventKey\type= #GDK_KEY_PRESS
				If gtk_widget_has_focus(*widget)
					
					If *event\direction = #GDK_SCROLL_UP
						*eventKey\keyval = #GDK_KEY_Up
						Callback_TimePickerGadget_KeyAction(*widget, *eventKey, *user_data)
						
					ElseIf *event\direction = #GDK_SCROLL_DOWN
						*eventKey\keyval = #GDK_KEY_Down
						Callback_TimePickerGadget_KeyAction(*widget, *eventKey, *user_data)
						
					EndIf
					
				EndIf
			EndProcedure
			
			Procedure TimePickerGadget(GadgetNo, x, y, w, h, sTime.s, WindowNo, Flags= #Null);   Linux
				Protected.i TimePattern= CreateRegularExpression(#PB_Any, "^[0-2]?[0-9]:[0-5]?[0-9]:[0-5]?[0-9]$")
				Protected.i GadgetId, PBId
				Protected.i _Flags= #Null
				Shared      GadgetData()
				
				If Not MatchRegularExpression(TimePattern, sTime)
					If #TPG_DebugOn
						Debug "TimePickerGadget [" + Str(GadgetNo) + "]: Preset string is not in time format: '[h]h:[m]m:[s]s', or time is invalid!"
						Debug " -> Time is set to '00:00:00'!"
					EndIf
					sTime= "00:00:00"
				EndIf
				If TimePattern : FreeRegularExpression(TimePattern) : EndIf
				
				If Flags & #TPG_Time_ReadOnly
					_Flags | #PB_String_ReadOnly
				EndIf
				If Flags & #TPG_Time_BorderLess
					_Flags | #PB_String_BorderLess
				EndIf
				If #TPG_DebugOn And Flags & #TPG_Time_NoUpDown
					Debug "TimePickerGadget Flag: '#TPG_Time_NoUpDown' isn't implemented on Linux."
				EndIf
				If #TPG_DebugOn And Flags & #TPG_Time_12h
					Debug "TimePickerGadget Flag: '#TPG_Time_12h' isn't implemented on Linux."
				EndIf
				
				PBId= StringGadget(GadgetNo, x,  y,  w,  h, sTime, _Flags)
				If GadgetNo = #PB_Any
					GadgetId= GadgetID(PBId)
				ElseIf GadgetNo > #PB_Any
					GadgetId= GadgetID(GadgetNo)
				Else
					Debug "TimePickerGadget [" + Str(GadgetNo) + "]: GadgetNo < #PB_Any not defined! Programm stopped!" : End
				EndIf
				
				AddElement(GadgetData())
				GadgetData()\GadgetId= GadgetId
				GadgetData()\WindowNo= WindowNo
				
				gtk_entry_set_max_length_(GadgetId, 8)
				gtk_entry_set_alignment  (GadgetId, 0.5)
				gtk_widget_add_events_   (GadgetId, #GDK_FOCUS_CHANGE | #GDK_SCROLL_MASK | #GDK_KEY_PRESS_MASK)
				
				g_signal_connect(GadgetId, "scroll-event",         @Callback_TimePickerGadget_ScrollBlock(), @GadgetData())
				g_signal_connect(GadgetId, "button-press-event",   @Callback_TimePickerGadget_ClickAction(), @GadgetData())
				g_signal_connect(GadgetId, "button-release-event", @Callback_TimePickerGadget_ClickAction(), @GadgetData())
				g_signal_connect(GadgetId, "key-press-event",      @Callback_TimePickerGadget_KeyAction(),   @GadgetData())
				g_signal_connect(GadgetId, "key-release-event",    @Callback_TimePickerGadget_KeyAction(),   @GadgetData())
				g_signal_connect(GadgetId, "focus-out-event",      @Callback_TimePickerGadget_LostFocus(),   @GadgetData())
				
				ProcedureReturn GadgetId
			EndProcedure;   Linux
			
			;-}  _Linux TimePickerGadget API END
			
		CompilerCase #PB_OS_MacOS
			
			;-{  _MacOS TimePickerGadget API ...
			
			Procedure GetUTCOffset()
				Shared.i iUTCOffsetSeconds
				Shared.s sUTCOffset
				
				iUTCOffsetSeconds = CocoaMessage(0, CocoaMessage(0, 0, "NSTimeZone systemTimeZone"), "secondsFromGMT")
				
				If iUTCOffsetSeconds < 0
					sUTCOffset = "-" + FormatDate("%hh%ii", 24 * 60 * 60 - iUTCOffsetSeconds)
				Else
					sUTCOffset = "+" + FormatDate("%hh%ii", iUTCOffsetSeconds)
				EndIf
			EndProcedure
			
			Procedure.i GetTimePickerGadgetState(GadgetId)
				Shared.i iUTCOffsetSeconds
				
				Protected   *CurrentDate
				Protected.s sCurrentDate
				Protected.i TimeVal
				
				*CurrentDate= CocoaMessage(0, GadgetId, "dateValue")
				sCurrentDate= PeekS(CocoaMessage(0, CocoaMessage(0, *CurrentDate, "description"), "UTF8String"), -1, #PB_UTF8)
				
				If OSVersion() <= #PB_OS_MacOSX_10_6
					TimeVal= ParseDate(#TPG_TimeMask24h, Mid(sCurrentDate, 12, 8))
				Else
					TimeVal= AddDate(ParseDate(#TPG_TimeMask24h, Mid(sCurrentDate, 12, 8)), #PB_Date_Second, iUTCOffsetSeconds)
				EndIf
				
				ProcedureReturn TimeVal
			EndProcedure
			
			Procedure SetTimePickerGadgetState(GadgetId, TimeVal)
				Shared.s sUTCOffset
				
				Protected.s sTime
				
				If TimeVal > -1 And TimeVal < 86400
					sTime = FormatDate("%yyyy-%mm-%dd", Date()) + " " + FormatDate(#TPG_TimeMask24h, TimeVal) + " " + sUTCOffset
					*StartDate = CocoaMessage(0, 0, "NSDate dateWithString:$", @sTime)
					CocoaMessage(0, GadgetId, "setDateValue:@", @*StartDate)
				EndIf
			EndProcedure
			
			Procedure.s GetTimePickerGadgetText(GadgetId)
				Shared.i iUTCOffsetSeconds
				
				Protected   *CurrentDate
				Protected.s sCurrentDate
				Protected.s sCurrentTime
				
				*CurrentDate= CocoaMessage(0, GadgetId, "dateValue")
				sCurrentDate= PeekS(CocoaMessage(0, CocoaMessage(0, *CurrentDate, "description"), "UTF8String"), -1, #PB_UTF8)
				
				If OSVersion() <= #PB_OS_MacOSX_10_6
					sCurrentTime= FormatDate(#TPG_TimeMask24h, ParseDate(#TPG_TimeMask24h, Mid(sCurrentDate, 12, 8)))
				Else
					sCurrentTime= FormatDate(#TPG_TimeMask24h, AddDate(ParseDate(#TPG_TimeMask24h, Mid(sCurrentDate, 12, 8)), #PB_Date_Second, iUTCOffsetSeconds))
				EndIf
				
				ProcedureReturn sCurrentTime
			EndProcedure
			
			Procedure SetTimePickerGadgetText(GadgetId, sTimeString.s)
				Shared.s sUTCOffset
				
				Protected *StartDate
				
				If ParseDate(#TPG_TimeMask24h, sTimeString) > -1
					sTimeString = FormatDate("%yyyy-%mm-%dd", Date()) + " " + sTimeString + " " + sUTCOffset
					*StartDate = CocoaMessage(0, 0, "NSDate dateWithString:$", @sTimeString)
					CocoaMessage(0, GadgetId, "setDateValue:@", @*StartDate)
				EndIf
			EndProcedure
			
			ProcedureC Callback_TimePickerGadget_Changed(Object.I, Selector.I, Cell.I, ProposedValue.I, ProposedTimeInterval.I)
				Shared TimePickerCell()
				
				ForEach TimePickerCell()
					If TimePickerCell()\ID = Cell
						PostEvent(#PB_Event_Gadget, TimePickerCell()\WindowNo, Cell, #PB_EventType_Change)
						Break
					EndIf
				Next
			EndProcedure
			
			Procedure InitCallback(TimePicker.I)
				Protected AppDelegate.I  = CocoaMessage(0, CocoaMessage(0, 0, "NSApplication sharedApplication"), "delegate")
				Protected DelegateClass.I= CocoaMessage(0, AppDelegate, "class")
				Protected Selector.I     = sel_registerName_("datePickerCell:validateProposedDateValue:timeInterval:")
				
				class_addMethod_(DelegateClass, Selector, @Callback_TimePickerGadget_Changed(), "v@:@@@")
				CocoaMessage(0, TimePicker, "setDelegate:", AppDelegate)
			EndProcedure
			
			Procedure TimePickerGadget(GadgetNo, x, y, w, h, sTime.s, WindowNo, Flags= #Null);   MacOS
				Shared.s sUTCOffset
				Shared.i TimePickerCell()
				
				Protected   Frame.NSRect
				Protected   *StartDate
				Protected.i TimePicker
				Protected.i TimePattern= CreateRegularExpression(#PB_Any, "^[0-2]?[0-9]:[0-5]?[0-9]:[0-5]?[0-9]$")
				
				If sUTCOffset = ""
					GetUTCOffset()
				EndIf
				
				If Not MatchRegularExpression(TimePattern, sTime)
					If #TPG_DebugOn
						Debug "TimePickerGadget [" + Str(GadgetNo) + "]: Preset string is not in time format: '[h]h:[m]m:[s]s', or time is invalid!"
						Debug " -> Time is set to '00:00:00'!"
					EndIf
					sTime= "00:00:00"
				EndIf
				If TimePattern : FreeRegularExpression(TimePattern) : EndIf
				
				Frame\origin\x = x
				Frame\origin\y = y
				Frame\size\width = w
				Frame\size\height = h
				TimePicker = CocoaMessage(0, CocoaMessage(0, 0, "NSDatePicker alloc"), "initWithFrame:@", @Frame)
				
				If #TPG_DebugOn And Flags & #TPG_Time_ReadOnly
					Debug "TimePickerGadget Flag: '#TPG_Time_ReadOnly' isn't implemented on Mac."
				EndIf
				If Flags & #TPG_Time_BorderLess
				 	CocoaMessage(0, TimePicker, "setBordered:", #False)
				Else
					CocoaMessage(0, TimePicker, "setBezeled:", #True)
				EndIf
				If Flags & #TPG_Time_NoUpDown
					CocoaMessage(0, TimePicker, "setDatePickerStyle:", #NSDatePickerStyleTextField)
				Else
					CocoaMessage(0, TimePicker, "setDatePickerStyle:", #NSDatePickerStyleTextFieldAndStepper)
				EndIf
				If #TPG_DebugOn And Flags & #TPG_Time_12h
					Debug "TimePickerGadget Flag: '#TPG_Time_12h' isn't implemented on Mac."
				EndIf
				
				CocoaMessage(0, TimePicker, "setDatePickerElements:", #NSHourMinuteSecondDatePickerElementFlag)
				CocoaMessage(0, CocoaMessage(0, WindowID(WindowNo), "contentView"), "addSubview:", TimePicker)
				sTime = FormatDate("%yyyy-%mm-%dd", Date()) + " " + sTime + " " + sUTCOffset
				*StartDate = CocoaMessage(0, 0, "NSDate dateWithString:$", @sTime)
				CocoaMessage(0, TimePicker, "setDateValue:@", @*StartDate)
				InitCallback(TimePicker)
				AddElement(TimePickerCell())
				TimePickerCell()\ID = CocoaMessage(0, TimePicker, "cell")
				TimePickerCell()\WindowNo = WindowNo
				
				ProcedureReturn TimePickerCell()\ID
			EndProcedure;   MacOS
			
			;-}  _MacOS TimePickerGadget API END
			
		CompilerCase #PB_OS_Windows
			
			;-{  _Windows TimePickerGadget API ...
			
			Procedure GetTimePickerGadgetState(GadgetId)
				Protected.i TimeVal
				Protected   tTime.systemtime
				
				SendMessage_(GadgetId, #MCM_GETCURSEL, 0, @tTime)
				TimeVal = Val(Str(ParseDate(#TPG_TimeMask24h, RSet(Str(tTime\wHour), 2, "0") + ":" + RSet(Str(tTime\wMinute), 2, "0") + ":" + RSet(Str(tTime\wSecond), 2, "0"))))
				
				ProcedureReturn TimeVal
			EndProcedure
			
			Procedure SetTimePickerGadgetState(GadgetId, TimeVal)
				Protected tTime.systemtime
				
				If TimeVal > -1 And TimeVal < 86400
					SendMessage_(GadgetId, #MCM_GETCURSEL, 0, @tTime)
					tTime\wYear  = 1970
					tTime\wMonth = 1
					tTime\wDay   = 1
					tTime\wHour  = Hour(TimeVal)
					tTime\wMinute= Minute(TimeVal)
					tTime\wSecond= Second(TimeVal)
					SendMessage_(GadgetId, #MCM_SETCURSEL, 0, @tTime)
				EndIf
			EndProcedure
			
			Procedure.s GetTimePickerGadgetText(GadgetId)
				Protected.s sTimeString
				Protected   tTime.systemtime
				
				SendMessage_(GadgetId, #MCM_GETCURSEL, 0, @tTime)
				sTimeString= RSet(Str(tTime\wHour), 2, "0") + ":" + RSet(Str(tTime\wMinute), 2, "0") + ":" + RSet(Str(tTime\wSecond), 2, "0")
				
				ProcedureReturn sTimeString
			EndProcedure
			
			Procedure SetTimePickerGadgetText(GadgetId, sTimeString.s)
				Protected.i TimeVal
				Protected   tTime.systemtime
				
				TimeVal= ParseDate(#TPG_TimeMask24h, sTimeString)
				If TimeVal > -1 And TimeVal < 86400
					SendMessage_(GadgetId, #MCM_GETCURSEL, 0, @tTime)
					tTime\wYear  = 1970
					tTime\wMonth = 1
					tTime\wDay   = 1
					tTime\wHour  = Hour(TimeVal)
					tTime\wMinute= Minute(TimeVal)
					tTime\wSecond= Second(TimeVal)
					SendMessage_(GadgetId, #MCM_SETCURSEL, 0, @tTime)
				EndIf
			EndProcedure
			
			Procedure Callback_Window(WindowHandle, Msg, wParam, lParam)
				Protected *pnmh.NMHDR
				Protected WindowNo= GetProp_(WindowHandle, "PB_WINDOWID") - 1
				
				Select Msg
						
					Case #WM_NOTIFY
						
						*pnmh = lParam
						
						Select *pnmh\code
								
							Case #DTN_DATETIMECHANGE
								PostEvent(#PB_Event_Gadget, WindowNo, *pnmh\hwndFrom, #PB_EventType_Change)
								
						EndSelect
						
				EndSelect
				
				ProcedureReturn #PB_ProcessPureBasicEvents
			EndProcedure
			
			Procedure TimePickerGadget(GadgetNo, x, y, w, h, sTime.s, WindowNo, Flags= #Null);   Windows
				Protected.i TimePattern= CreateRegularExpression(#PB_Any, "^[0-2]?[0-9]:[0-5]?[0-9]:[0-5]?[0-9]$")
				Protected.i GadgetId, PBId
				
				If Not MatchRegularExpression(TimePattern, sTime)
					If #TPG_DebugOn
						Debug "TimePickerGadget [" + Str(GadgetNo) + "]: Preset string is not in time format: '[h]h:[m]m:[s]s', or time is invalid!"
						Debug " -> Time is set to '00:00:00'!"
					EndIf
					sTime= "00:00:00"
				EndIf
				If TimePattern : FreeRegularExpression(TimePattern) : EndIf
				
				InitCommonControls_();                                                 ?
				PBId= DateGadget(GadgetNo, x, y, w, h, "", 0, #DTS_TIMEFORMAT);        no other flags accepted
				If GadgetNo = #PB_Any
					GadgetId= GadgetID(PBId)
				ElseIf GadgetNo > #PB_Any
					GadgetId= GadgetID(GadgetNo)
				Else
					Debug "TimePickerGadget [" + Str(GadgetNo) + "]: GadgetNo < #PB_Any not defined! Programm stopped!" : End
				EndIf
				SetWindowCallback(@Callback_Window(), WindowNo)
				
				If #TPG_DebugOn And Flags & #TPG_Time_ReadOnly
					Debug "TimePickerGadget Flag: '#TPG_Time_ReadOnly' isn't available on Windows."
				EndIf
				If Flags & #TPG_Time_BorderLess
					SetWindowLongPtr_(GadgetId, #GWL_EXSTYLE, 0)
					SetWindowPos_(GadgetId, 0, 0, 0, 0, 0, #SWP_NOMOVE | #SWP_NOSIZE | #SWP_FRAMECHANGED); w/o frame
				EndIf
				If #TPG_DebugOn And Flags & #TPG_Time_NoUpDown
					Debug "TimePickerGadget Flag: '#TPG_Time_NoUpDown' isn't available on Windows."
				EndIf
				If Flags & #TPG_Time_12h
					CompilerIf #PB_Compiler_Unicode
						SendMessage_(GadgetId, #DTM_SETFORMATW, 0, @"hh:mm:ss tt");            set time format 12h + am/pm in unicode
					CompilerElse
						SendMessage_(GadgetId, #DTM_SETFORMATA, 0, @"hh:mm:ss tt");            set time format 12h + am/pm in ascii
					CompilerEndIf
				EndIf
				SetTimePickerGadgetText(GadgetId, sTime)
				
				ProcedureReturn GadgetId
			EndProcedure;   Windows
			
			;-}  _Windows TimePickerGadget API END
			
	CompilerEndSelect
	
	;-} EndModul: TimePickerGadget
	;-
EndModule


; Demo for TimePickerGadget() ...
CompilerIf #PB_Compiler_IsMainFile
	
	UseModule TimePickerGadget;                                                  access with UseModule ...
	
	Procedure Create_WinMain()
		OpenWindow(#Win_Main,      100, 100, 800, 170, "TimePickerGadget, All OS - Demo Win 1 ", #PB_Window_SystemMenu)
		TextGadget(#PB_Any,          5,   5, 790,  20, "Set a time in 24h format as 'hh:mm:ss':")
		TextGadget(#PB_Any,         10,  25, 785,  20, "- choose segment (marked block) with <left>/<right> keys or mouseclick.")
		TextGadget(#PB_Any,         10,  45, 785,  20, "- choose segments value w. number keys, <up>/<down> | num-pads <+>/<-> (not Mac) or mouse scrolling not Mac).")
		TextGadget(#PB_Any,         10,  65, 785,  20, "- jump to segments min.-/max.- values with <home>/<end>. (not Mac, Win only max.)")
		
		StringGadget(#StGMain1,    600,  90, 195,  26, "Only for focus tests!")
		
		TextGadget(#PB_Any,          5,  94,  98,  22, "Set time :")
		*gTimeGadget1= TimePickerGadget(#TimeGadget1, 200,  90,  90,  26, "05:33:20", #Win_Main, #TPG_Time_12h)
		
		TextGadget(#PB_Any,          5, 118, 190,  22, "Time set:")
		TextGadget(#PB_Any,          5, 138, 190,  22, "Time value set (=seconds):")
		TextGadget(#TxGMain1,      200, 118,  98,  22, "")
		TextGadget(#TxMainG2,      200, 138,  98,  22, "")
		
		ButtonGadget(#BtGMainSet,  520, 135, 275,  26, "Set time to 8:00:00 from TimeVal")
	EndProcedure
	
	UnuseModule TimePickerGadget;                                                access without UseModule. ...
	
	Procedure Create_WinSec()
		gWin_Sec= OpenWindow(#PB_Any,       100, 300, 800, 100, "TimePickerGadget, All OS - Demo Win 2 ", #PB_Window_SystemMenu)
		StringGadget(#StGSec1,     600,  10, 195,  26, "Only for focus tests!")
		
		TextGadget(#PB_Any,          5,  14,  98,  22, "Set time :")
		*gTimeGadget2= TimePickerGadget::TimePickerGadget(#PB_Any, 200,  10,  90,  26, "11:06:40", gWin_Sec, TimePickerGadget::#TPG_Time_BorderLess)
		
		TextGadget(#PB_Any,          5,  38, 190,  22, "Time set:")
		TextGadget(#PB_Any,          5,  58, 190,  22, "Time value set (=seconds):")
		TextGadget(#TxGSec1,       200,  38,  98,  22, "")
		TextGadget(#TxGSec2,       200,  58,  98,  22, "")
		
		ButtonGadget(#BtGSecSet,   520,  55, 275,  26, "Set time to 16:00:00 from TimeString")
	EndProcedure
	
	Create_WinMain()
	Create_WinSec()
	
	UseModule TimePickerGadget
	
	Repeat
		gEvent=    WaitWindowEvent()
		gEventWin= EventWindow()
		Select gEventWin
				
			Case #Win_Main;                                                          access with UseModule ...
				
				Select gEvent
						
					Case #PB_Event_CloseWindow
						gQuit= #True
						
					Case #PB_Event_Gadget
						gEventGadget= EventGadget()
						
						Select gEventGadget
								
							Case *gTimeGadget1;                                              watch the pointer and read time
								If EventType() = #PB_EventType_Change
									SetGadgetText(#TxGMain1, GetTimePickerGadgetText(*gTimeGadget1))
									SetGadgetText(#TxMainG2, Str(GetTimePickerGadgetState(*gTimeGadget1)))
								EndIf
								
							Case #BtGMainSet;                                                set TimePickerGadget to 08:00:00 by time value
								SetTimePickerGadgetState(*gTimeGadget1, 28800)
								PostEvent(#PB_Event_Gadget, #Win_Main, *gTimeGadget1, #PB_EventType_Change); trigger event for reading
								
						EndSelect
						
				EndSelect
				
	UnuseModule TimePickerGadget
				
			Case gWin_Sec;                                                           access without UseModule ...
				
				Select gEvent
						
					Case #PB_Event_CloseWindow
						gQuit= #True
						
					Case #PB_Event_Gadget
						gEventGadget= EventGadget()
						
						Select gEventGadget
								
							Case *gTimeGadget2;                                              watch the pointer and read time
								If EventType() = #PB_EventType_Change
									SetGadgetText(#TxGSec1, TimePickerGadget::GetTimePickerGadgetText(*gTimeGadget2))
									SetGadgetText(#TxGSec2, Str(TimePickerGadget::GetTimePickerGadgetState(*gTimeGadget2)))
								EndIf
								
							Case #BtGSecSet;                                                 set TimePickerGadget to 16:00:00 by string
								TimePickerGadget::SetTimePickerGadgetText(*gTimeGadget2, "16:00:00")
								PostEvent(#PB_Event_Gadget, gWin_Sec, *gTimeGadget2, #PB_EventType_Change); trigger event for reading
								
						EndSelect
						
				EndSelect
				
		EndSelect
		
	Until gQuit
	
CompilerEndIf
Schönen Sonntag, Charly

PS: Der Sache mit #PB_Any für den WindowNo-Parameter muss ich mich (wie schon bei der GadgetNo) noch mal widmen!
Nachtrag: #PB_Any für den WindowNo-Parameter scheint keine Probleme zu machen. In diesem Fall den global-/shared-Rückgabewert aus OpenWindow() verwenden.
Update: 2018-10-20: V0.21
Zuletzt geändert von Omi am 20.01.2019 08:37, insgesamt 3-mal geändert.
PureBasic Linux-API-Library: http://www.chabba.de
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: "Gadget(s)" für Zeiteingabe gesucht

Beitrag von ccode_new »

Super!
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: "Gadget(s)" für Zeiteingabe gesucht

Beitrag von Nino »

An Charly und alle anderen beteiligten Coder:
War offensichtlich ein Haufen Arbeit, aber es hat sich gelohnt. :-)
Vielen Dank fürs Teilen!

PS: Wenn der Fokus auf den Sekunden ist und ich diese durch Mausklicks auf die Pfeiltasten hoch oder runter zähle, dann verändern sich beim Überschreiten von 59 bzw. beim Unterschreiten von 0 die Minuten nicht. Ist das Absicht? Ich finde es intuitiver und bin es z.B. von den Uhren unter Android so gewöhnt, dass dann ein entspr. Übertrag stattfindet.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: "Gadget(s)" für Zeiteingabe gesucht

Beitrag von ccode_new »

Hi Nino!
Nino hat geschrieben:PS: Wenn der Fokus auf den Sekunden ist und ich diese durch Mausklicks auf die Pfeiltasten hoch oder runter zähle, dann verändern sich beim Überschreiten von 59 bzw. beim Unterschreiten von 0 die Minuten nicht. Ist das Absicht? Ich finde es intuitiver und bin es z.B. von den Uhren unter Android so gewöhnt, dass dann ein entspr. Übertrag stattfindet.
Ja, das ist das normale Verhalten.

Man könnte aber noch extra Flags für zukünftigte Sonderfunktionen einführen.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
Shardik
Beiträge: 746
Registriert: 25.01.2005 12:19

Re: "Gadget(s)" für Zeiteingabe gesucht

Beitrag von Shardik »

Nino hat geschrieben:PS: Wenn der Fokus auf den Sekunden ist und ich diese durch Mausklicks auf die Pfeiltasten hoch oder runter zähle, dann verändern sich beim Überschreiten von 59 bzw. beim Unterschreiten von 0 die Minuten nicht.
Das ist das Standardverhalten für die verwendeten API-TimePicker in Desktop-Anwendungen von Windows und MacOS. Eine Änderung würde Windows- und MacOS-Anwender, die bereits mit diesem Gadget in anderen Anwendungen gearbeitet haben, wahrscheinlich verwirren. Ich persönlich würde allerdings auch das Umspringen der davorliegenden Segmente bevorzugen...:wink:
Nino
Beiträge: 1300
Registriert: 13.05.2010 09:26
Wohnort: Berlin

Re: "Gadget(s)" für Zeiteingabe gesucht

Beitrag von Nino »

Danke für die Erklärung!
Omi
Beiträge: 143
Registriert: 25.03.2013 09:59

Re: "Gadget(s)" für Zeiteingabe gesucht

Beitrag von Omi »

Danke! Auch noch mal an Shardik, da ich es in obigem Posting versäumt habe. Ohne ihn wär's wohl eine 2 OS-Version geblieben!

Ich hoffe mal, als ursprünglich Bedürftiger bin ich nicht der einzige Nutznießer und der Eine oder Andere kann es dann auch mal gebrauchen und ist vom Umfang nicht zu sehr abgeschreckt.
Es ist halt wie immer. Der Feinschliff macht die meiste Arbeit und Codelänge.
(Und an Ideen und Möglichkeiten scheint es weiterhin nicht zu mangeln um das Modul noch zu erweitern :wink: )

Ich hab's beim Code-Posting noch ergänzt: Das #PB_Any bei den Fenstern dürfte kein Problem darstellen - evtl. tausche ich den Demo-Code diesbezgl. noch aus.

Gruß, Charly

Nachtrag: Shardik hat mich gerade noch kontaktiert bezgl. noch entdeckter Unkorrektheiten im Beschreibungstext des Code-Headers und funktionellen Problemen unter gewissen Bedingungen. Weitere Update(s) sind also wahrscheinlich.
PureBasic Linux-API-Library: http://www.chabba.de
Omi
Beiträge: 143
Registriert: 25.03.2013 09:59

Re: "Gadget(s)" für Zeiteingabe gesucht

Beitrag von Omi »

Der zuletzt gepostete All-OS-Code erhielt ein kleines Update auf V0.21:
- Shardik hat eine Fehler unter Windows beim kompilieren als Ascii-Executable entdeckt und beseitigt,
- des weiteren wurde von ihm für MacOS das Flag #TPG_Time_BorderLess nachgereicht. Vielen Danke dafür!
- Allgemein wurden noch Kleinigkeiten im Code, Kommentaren und der Beschreibung im Header überarbeitet. U.a. wurde im Demo-Teil des Codes das 2. Fenster jetzt als #PB_Any angelegt, um Funktion und Handling zu zeigen.

Schönen Sonntag, Charly
PureBasic Linux-API-Library: http://www.chabba.de
Antworten