Improved SpinGadget dealing with decimal values
Posted: Sat Jun 18, 2011 8:29 am
For a 3D-Editor I needed a more flexible way to treat SpinGadgets than the usual one can provide.
So I came up with this fake SpinGadget version which works with regular expression and deals with different inputs
like: double values with 2-10 decimals | restricted to 0-9,.- | update on lostfocus | ...
Please let me know if you´d change or improve something! Thx
So I came up with this fake SpinGadget version which works with regular expression and deals with different inputs
like: double values with 2-10 decimals | restricted to 0-9,.- | update on lostfocus | ...
Please let me know if you´d change or improve something! Thx

Code: Select all
; English forum: http://www.purebasic.fr/english/viewtopic.php?f=12&t=46669
; Author: chi
; Date: 18. June 2011
; OS: Windows
; Demo: No
;////////////////////////////////////////////////////////
;// Improved SpinGadget dealing with decimal values //
;//////////////////////////////////////////////////////
EnableExplicit
;{ Enum
Enumeration
#Win
#Return
#Txt_1
#Str_1
#Spn_1
#Txt_2
#Str_2
#Spn_2
#Txt_3
#Str_3
#Spn_3
#RegExp
#PB_EventType_SpinUp = 1
#PB_EventType_SpinDown = -1
EndEnumeration
;}
;{ Inits
Define event.i
Define eventgadget.i
Global decimalplaces.i = 4 ; min = 2 / max = 10
Declare GetStringCursorPos( gadget )
Declare String_Event( gadget )
Declare Enter_Event( gadget )
Declare Spin_Event( gadget )
Declare Debug_Gadget( gadget.i, text.s )
;}
;{ Window
OpenWindow( #Win, 0, 0, 165, 96, "Demo", #PB_Window_SystemMenu|#PB_Window_ScreenCentered )
AddKeyboardShortcut( #Win, #PB_Shortcut_Return, #Return )
TextGadget( #Txt_1, 10, 18, 35, 19, "Pos X :" )
StringGadget( #Str_1, 46, 15, 100, 19, StrD( -1, decimalplaces ), #ES_RIGHT )
SpinGadget( #Spn_1, 147, 14, 9, 21, -1, 1, #PB_Spin_Numeric )
TextGadget( #Txt_2, 10, 43, 35, 19, "Pos Y :" )
StringGadget( #Str_2, 46, 40, 100, 19, StrD( 0, decimalplaces ), #ES_RIGHT )
SpinGadget( #Spn_2, 147, 39, 9, 21, -1, 1, #PB_Spin_Numeric )
TextGadget( #Txt_3, 10, 68, 35, 19, "Pos Z :" )
StringGadget( #Str_3, 46, 65, 100, 19, StrD( 1, decimalplaces ), #ES_RIGHT )
SpinGadget( #Spn_3, 147, 64, 9, 21, -1, 1, #PB_Spin_Numeric )
;}
;{ RegExp
CreateRegularExpression( #RegExp, "^[-]?\d*[.,]?\d*$" )
;}
;{ EventLoop
Repeat
event = WaitWindowEvent()
Select event
Case #PB_Event_Menu
Select EventMenu()
Case #Return
Enter_Event( eventgadget )
EndSelect
Case #PB_Event_Gadget
Select EventGadget()
Case #Str_1
String_Event( #Str_1 )
Case #Str_2
String_Event( #Str_2 )
Case #Str_3
String_Event( #Str_3 )
Case #Spn_1
Spin_Event( #Spn_1 )
Case #Spn_2
Spin_Event( #Spn_2 )
Case #Spn_3
Spin_Event( #Spn_3 )
EndSelect
EndSelect
Until event = #PB_Event_CloseWindow
End
;}
Procedure GetStringCursorPos( gadget )
Protected min.i, max.i
SendMessage_( GadgetID( gadget ), #EM_GETSEL, @min, @max )
ProcedureReturn max - SendMessage_( GadgetID( gadget ), #EM_LINEINDEX, SendMessage_( GadgetID( gadget ), #EM_LINEFROMCHAR, min, 0 ), 0 )
EndProcedure
Procedure String_Event( gadget )
Protected last.s, text.s, deci.i, cpos.i
Shared eventgadget.i
Static lasttext.s
Select EventType()
Case #PB_EventType_Focus
eventgadget = gadget
lasttext = StrD( ValD( GetGadgetText( gadget ) ), decimalplaces )
Case #PB_EventType_Change
cpos = GetStringCursorPos( gadget )
text = GetGadgetText( gadget )
If MatchRegularExpression( #RegExp, text ) = 0
last = Mid( text, cpos, 1 )
text = RemoveString( text, last, 0, cpos, 1 )
SetGadgetText( gadget, text )
SendMessage_( GadgetID( gadget ), #EM_SETSEL, cpos-1, cpos-1 )
Else
If FindString( text, ",", 1 ) > 0
text = ReplaceString( text, ",", "." )
SetGadgetText( gadget, text )
SendMessage_( GadgetID( gadget ), #EM_SETSEL, cpos, cpos )
EndIf
last = StringField( text, 2, "." )
If Len( last ) > decimalplaces
deci = Len( StringField( text, 1, "." ) ) + 1
deci = cpos - deci
text = StringField( text, 1, "." ) + "." + Left ( Left( last, deci ) + Right( last, decimalplaces-deci ), decimalplaces )
SetGadgetText( gadget, text )
If deci >= decimalplaces
cpos - 1
EndIf
SendMessage_( GadgetID( gadget ), #EM_SETSEL, cpos, cpos )
EndIf
EndIf
Case #PB_EventType_LostFocus
text = StrD( ValD( GetGadgetText( gadget ) ), decimalplaces )
SetGadgetText( gadget, text )
If lasttext <> text
Debug_Gadget( gadget, text)
EndIf
EndSelect
EndProcedure
Procedure Enter_Event( gadget )
Protected text.s
text = StrD( ValD( ReplaceString( GetGadgetText( gadget ), ",", "." ) ), decimalplaces )
SetGadgetText( gadget, text )
SetGadgetState( gadget+1, 0 )
SetActiveGadget( gadget+1 )
EndProcedure
Procedure Spin_Event( gadget )
Protected value.d
Select EventType()
Case #PB_EventType_SpinUp
value = ValD( ReplaceString( GetGadgetText( gadget-1 ), ",", "." ) )
If value + 0.1 > 0 And value + 0.1 < 0.1
value = Abs( value )
Else
value + 0.1
EndIf
SetGadgetText( gadget-1, StrD( value , decimalplaces ) )
SetGadgetState( gadget, 0 )
SetActiveGadget( gadget )
Debug_Gadget( gadget-1, GetGadgetText( gadget-1 ) )
Case #PB_EventType_SpinDown
value = ValD( ReplaceString( GetGadgetText( gadget-1 ), ",", "." ) )
If value - 0.1 < 0 And value - 0.1 > -0.1
value = -value
Else
value - 0.1
EndIf
SetGadgetText( gadget-1, StrD( value, decimalplaces ) )
SetGadgetState( gadget, 0 )
SetActiveGadget( gadget )
Debug_Gadget( gadget-1, GetGadgetText( gadget-1 ) )
EndSelect
EndProcedure
Procedure Debug_Gadget( gadget.i, text.s )
Debug GetGadgetText( gadget-1 ) + " " + GetGadgetText( gadget )
EndProcedure