[GB.FORM]

* NEW: Redesign the syntax of the MaskBox.Mask property. It is now a LIKE
  regular expression (or almost).
* BUG: DateBox.Value works correctly again.

[GB.GTK]
* BUG: Popup windows work again.


git-svn-id: svn://localhost/gambas/trunk@3447 867c0c6c-44f3-4631-809d-bfa615b0a4ec
This commit is contained in:
Benoît Minisini 2011-01-05 19:36:59 +00:00
parent 51de809d76
commit 1cdef3b24f
5 changed files with 233 additions and 95 deletions

View file

@ -35,6 +35,7 @@ Public Sub _new()
$hButtonBox = New ButtonBox(Me) As "ButtonBox" $hButtonBox = New ButtonBox(Me) As "ButtonBox"
$hButtonBox.Picture = Picture["icon:/small/calendar"] $hButtonBox.Picture = Picture["icon:/small/calendar"]
$hButtonBox.Editor.Mask = Replace(Format(Date(1111, 11, 11), gb.ShortDate), "1", "0")
$hPopup = New Window As "PopupWindow" $hPopup = New Window As "PopupWindow"
$hPopup.Persistent = True $hPopup.Persistent = True
@ -55,7 +56,7 @@ Private Function Value_Read() As Date
Dim vVal As Variant = Val($hButtonBox.Text) Dim vVal As Variant = Val($hButtonBox.Text)
If vVal And If IsDate(vVal) Then Return vVal If vVal And If TypeOf(vVal) = gb.Date Then Return vVal
End End
@ -68,6 +69,7 @@ End
Public Sub ButtonBox_Click() Public Sub ButtonBox_Click()
Dim X, Y, iPad As Integer Dim X, Y, iPad As Integer
Dim dDate As Date
iPad = If($hButtonBox.Border, 3, 0) iPad = If($hButtonBox.Border, 3, 0)
X = $hButtonBox.ScreenX + $hButtonBox.W - $hPopup.W - iPad X = $hButtonBox.ScreenX + $hButtonBox.W - $hPopup.W - iPad
@ -77,6 +79,8 @@ Public Sub ButtonBox_Click()
Y = $hButtonBox.ScreenY - $hPopup.H Y = $hButtonBox.ScreenY - $hPopup.H
Endif Endif
dDate = Me.Value
If dDate Then $hChooser.Value = dDate
$hPopup.ShowPopup(X, Y) $hPopup.ShowPopup(X, Y)
'$hPopup.ShowModal '$hPopup.ShowModal

View file

@ -0,0 +1,101 @@
' Gambas class file
'Export
Inherits ButtonBox
Public Const _Properties As String = "*,-Picture,-Text,ShowSecond,ShowMillisecond"
Property Value As Date
Property ShowSecond As Boolean
Property ShowMillisecond As Boolean
Private $bAMPM As Boolean
Private $bPM As Boolean
Private $bSecond As Boolean
Private $bMillisecond As Boolean
Private $hObserver As Observer
Public Sub _new()
$hObserver = New Observer(Me) As "TimeBox"
Me.Picture = Picture["icon:/16/clock"]
UpdateMask
End
Private Sub UpdateMask()
Dim sMask As String
If $bSecond Then
sMask = Format(Time(11, 11, 11), gb.LongTime)
Else
sMask = Format(Time(11, 11, 11), gb.ShortTime)
Endif
If $bMillisecond Then sMask &= ".000"
$bAMPM = Format(Now, "AM/PM")
Me.Editor.Mask = Replace(sMask, "1", "0")
End
Private Function Value_Read() As Date
Return Val(Me.Text)
End
Private Sub Value_Write(Value As Date)
Dim sFormat As String
If $bSecond Then
sFormat = Format(Time(11, 22, 33), gb.LongTime)
Else
sFormat = Format(Time(11, 22, 33), gb.ShortTime)
Endif
sFormat = Replace(sFormat, "11", "hh")
sFormat = Replace(sFormat, "22", "nn")
sFormat = Replace(sFormat, "33", "ss")
If $bMillisecond Then sFormat &= ".uu"
Me.Text = Format(Value, sFormat)
End
Private Function ShowSecond_Read() As Boolean
Return $bSecond
End
Private Sub ShowSecond_Write(Value As Boolean)
$bSecond = Value
UpdateMask
End
Private Function ShowMillisecond_Read() As Boolean
Return $bMillisecond
End
Private Sub ShowMillisecond_Write(Value As Boolean)
$bMillisecond = Value
UpdateMask
End
Public Sub TimeBox_Click()
Stop Event
End

View file

@ -8,7 +8,11 @@
} }
{ MaskBox1 MaskBox { MaskBox1 MaskBox
MoveScaled(6,18,24,4) MoveScaled(6,18,24,4)
Mask = "IP: 999.999.999.999" Alignment = Align.Right
Mask = "[0-9][0-9][0-9],00 €"
MaskChar = " " MaskChar = " "
} }
{ DateBox1 DateBox
MoveScaled(8,5,19,4)
}
} }

View file

@ -29,9 +29,17 @@ Private $hObserver As Observer
Private Const MASK_CHARACTER As String = "90A6?" Private Const MASK_CHARACTER As String = "90A6?"
Private Const MASK_DEFAULT As String = "_0___" Private Const MASK_DEFAULT As String = "_0___"
Private $sMaskOrg As String Private $sMaskOrg As String
Private $sMask As String
Private $aMask As String[]
Private $sDefault As String
Private $sSeparator As String Private $sSeparator As String
Private $sAlign As String
Private $bUpperCase As Boolean
Private $bLowerCase As Boolean
Private $sMaskChar As String Private $sMaskChar As String
Public Sub _new() Public Sub _new()
@ -42,26 +50,15 @@ End
Private Function Mask_Read() As String Private Function Mask_Read() As String
Return $sMask Return $sMaskOrg
End End
Private Sub GetDefaultCharacter(iPos As Integer) As String Private Sub GetDefaultCharacter(iPos As Integer) As String
Dim sCar As String Dim sCar As String = String.Mid$($sDefault, iPos + 1, 1)
If sCar = " " Then sCar = String.Mid$($sSeparator, iPos + 1, 1)
Inc iPos
sCar = String.Mid$($sMask, iPos, 1)
If sCar <> " " Then
iPos = InStr(MASK_CHARACTER, sCar)
If iPos Then
sCar = String.Mid$(MASK_DEFAULT, iPos, 1)
If sCar = "_" And If $sMaskChar Then sCar = $sMaskChar
Endif
Return sCar Return sCar
Else
Return String.Mid$($sSeparator, iPos, 1)
Endif
End End
@ -72,63 +69,97 @@ Private Sub MakeDefault() As String
Dim sCar As String Dim sCar As String
Dim iInd As Integer Dim iInd As Integer
For iInd = 1 To String.Len($sMask) For iInd = 0 To $aMask.Max
sDefault &= GetDefaultCharacter(iInd - 1) sDefault &= GetDefaultCharacter(iInd)
Next Next
Return sDefault Return RTrim(sDefault)
End End
Private Sub GetFirstCharacterPos() As Integer Private Sub GetFirstCharacterPos() As Integer
Return Len($sMask) - Len(LTrim($sMask)) Dim iPos As Integer
For iPos = 0 To $aMask.Max
If $aMask[iPos] Then Return iPos
Next
End End
Private Sub GetLastCharacterPos() As Integer Private Sub GetLastCharacterPos() As Integer
Return Len(RTrim($sMask)) Dim iPos As Integer
For iPos = $aMask.Max DownTo 0
If $aMask[iPos] Then Return iPos + 1
Next
End End
Private Sub UpdateMaskAndSeparator() Private Sub UpdateMaskAndSeparator(sMask As String)
Dim iPos As Integer Dim iPos, iPos2 As Integer
Dim sCar As String Dim sCar As String
Dim iLen As Integer Dim iLen As Integer
Dim aMask As New String[]
Dim sSeparator As String
Dim sAlign As String
Dim sDefault As String
iLen = String.Len($sMaskOrg) iLen = String.Len(sMask)
$sMask = ""
$sSeparator = ""
For iPos = 1 To iLen For iPos = 1 To iLen
sCar = String.Mid$($sMaskOrg, iPos, 1) sCar = String.Mid$(sMask, iPos, 1)
If IsMaskCharacter(sCar) Then If sCar = "[" Then
$sMask &= sCar iPos2 = String.InStr(sMask, "]", iPos)
$sSeparator &= " " If iPos2 = 0 Then Error.Raise("Bad mask")
aMask.Add(String.Mid$(sMask, iPos, iPos2 - iPos + 1))
iPos = iPos2
sSeparator &= " "
sDefault &= "_"
Continue Continue
Else If sCar = "?" Then
aMask.Add(sCar)
sSeparator &= " "
sDefault &= "_"
Else If sCar = "0" Then
aMask.Add("[0-9]")
sSeparator &= " "
sDefault &= "0"
Else If sCar = "9" Then
aMask.Add("[0-9]")
sSeparator &= " "
sDefault &= "_"
Else If sCar = "A" Then
aMask.Add("[A-Za-z]")
sSeparator &= " "
sDefault &= "_"
Else If sCar = "\\" And If iPos < iLen Then Else If sCar = "\\" And If iPos < iLen Then
$sMask &= " " aMask.Add("")
Inc iPos Inc iPos
$sSeparator &= String.Mid$($sMaskOrg, iPos, 1) sSeparator &= String.Mid$(sMask, iPos, 1)
sDefault &= " "
Else Else
$sMask &= " " aMask.Add("")
$sSeparator &= sCar sSeparator &= sCar
sDefault &= " "
Endif Endif
Next Next
Debug Quote($sMask);; Quote($sSeparator) $sMaskOrg = sMask
$aMask = aMask
$sSeparator = sSeparator
$sAlign = sAlign
$sDefault = sDefault
If $sMaskChar Then $sDefault = Replace($sDefault, "_", $sMaskChar)
End End
Private Sub Mask_Write(Value As String) Private Sub Mask_Write(Value As String)
$sMaskOrg = Value UpdateMaskAndSeparator(Value)
UpdateMaskAndSeparator
If Not $sMaskOrg Then Return If Not $sMaskOrg Then Return
@ -137,20 +168,25 @@ Private Sub Mask_Write(Value As String)
End End
Private Sub IsMaskCharacter(sCar As String) As Boolean ' Private Sub IsMaskCharacter(sCar As String) As Boolean
'
' Return InStr(MASK_CHARACTER, sCar)
'
' End
Return InStr(MASK_CHARACTER, sCar) Private Sub GetNextSeparator(sText As String, iPos As Integer, Optional sSep As String) As Integer
End
Private Sub GetNextSeparator(sText As String, iPos As Integer) As Integer
Dim iLen As Integer = String.Len(sText) Dim iLen As Integer = String.Len(sText)
Dim sCar As String
If iPos < 0 Then Return 0 If iPos < 0 Then Return 0
While iPos < iLen While iPos < iLen
If Not IsMaskCharacter(String.Mid$($sMask, iPos + 1, 1)) Then Break sCar = $aMask[iPos]
If Not sCar Then
If Not sSep Then Break
If sSep = String.Mid$(sText, iPos + 1, 1) Then Break
Endif
Inc iPos Inc iPos
Wend Wend
@ -165,7 +201,7 @@ Private Sub GetNextCharacter(sText As String, iPos As Integer) As Integer
If iPos < 0 Then Return 0 If iPos < 0 Then Return 0
While iPos < iLen While iPos < iLen
If IsMaskCharacter(String.Mid$($sMask, iPos + 1, 1)) Then Break If $aMask[iPos] Then Break
Inc iPos Inc iPos
Wend Wend
@ -186,7 +222,7 @@ Public Sub TextBox_KeyPress()
Dim sDefault As String Dim sDefault As String
Dim bChange As Boolean Dim bChange As Boolean
If Not $sMask Then Return If Not $sMaskOrg Then Return
sText = Me.Text sText = Me.Text
If Me.Selected Then If Me.Selected Then
@ -232,39 +268,20 @@ Public Sub TextBox_KeyPress()
Return Return
Endif Endif
If Key.Text Then If Key.Text And iPos < $aMask.Count Then
sCar = String.Mid$($sMask, iPos + 1, 1) sCar = $aMask[iPos]
If sCar Then If sCar And If Key.Text Like sCar Then sInsert = Key.Text
Select Case sCar
Case "9", "0"
If IsDigit(Key.Text) Then sInsert = Key.Text
Case "A"
If IsLetter(Key.Text) Then sInsert = Key.Text
Case "6"
If IsHexa(Key.Text) Then sInsert = Key.Text
Case "?"
sInsert = Key.Text
End Select
If Not sInsert Then If Not sInsert Then
iPosNext = GetNextSeparator(sText, iPos - 1) iPosNext = GetNextSeparator(sText, iPos - 1, Key.Text)
sCar = String.Mid$($sSeparator, iPosNext + 1, 1) If iPosNext >= Me.Length Then Goto DO_NOTHING
If Key.Text <> sCar Then Goto DO_NOTHING
iPos = iPosNext iPos = iPosNext
Endif Endif
iMove = 1 iMove = 1
Endif Endif
Endif
End Select End Select
If sInsert Or If bDelete Then If sInsert Or If bDelete Then
@ -293,7 +310,7 @@ Public Sub TextBox_KeyPress()
iPos = GetLastCharacterPos() iPos = GetLastCharacterPos()
Break Break
Endif Endif
If IsMaskCharacter(String.Mid$($sMask, iPos + 1, 1)) Then Break If $aMask[iPos] Then Break
Loop Loop
Endif Endif
@ -301,7 +318,7 @@ Public Sub TextBox_KeyPress()
If bDelete Then If bDelete Then
iPosNext = GetNextSeparator(sText, iPos) iPosNext = GetNextSeparator(sText, iPos)
If iPosNext > iPos Then If iPosNext > iPos Then
sText = String.Left(sText, iPos) & String.Mid$(sText, iPos + 2, iPosNext - iPos - 1) & GetDefaultCharacter(iPosNext - 1) & String.Mid$(sText, iPosNext + 1) sText = RTrim(String.Left(sText, iPos) & String.Mid$(sText, iPos + 2, iPosNext - iPos - 1) & GetDefaultCharacter(iPosNext - 1) & String.Mid$(sText, iPosNext + 1))
Endif Endif
Endif Endif
@ -331,19 +348,20 @@ Private Sub MaskChar_Write(Value As String)
Value = String.Left(Value) Value = String.Left(Value)
sText = Me.Text sText = Me.Text
For iPos = 1 To String.Len($sMask) For iPos = 0 To $aMask.Max
sCar = String.Mid$($sMask, iPos, 1) sCar = $aMask[iPos]
If sCar = " " Or If Mid$(MASK_DEFAULT, InStr(MASK_CHARACTER, sCar), 1) <> "_" Then Continue If Not sCar Or If String.Mid$($sDefault, iPos + 1, 1) <> "_" Then Continue
If String.Mid$(sText, iPos, 1) = GetDefaultCharacter(iPos - 1) Then aPos.Add(iPos) If String.Mid$(sText, iPos + 1, 1) = GetDefaultCharacter(iPos) Then aPos.Add(iPos)
Next Next
$sMaskChar = Value $sMaskChar = Value
UpdateMaskAndSeparator($sMaskOrg)
For Each iPos In aPos For Each iPos In aPos
sText = String.Left(sText, iPos - 1) & GetDefaultCharacter(iPos - 1) & String.Mid$(sText, iPos + 1) sText = String.Left(sText, iPos) & GetDefaultCharacter(iPos) & String.Mid$(sText, iPos + 2)
Next Next
Me.Text = sText Me.Text = RTrim(sText)
Me.Pos = GetFirstCharacterPos() Me.Pos = GetFirstCharacterPos()
End End

View file

@ -468,13 +468,6 @@ static void gambas_handle_event(GdkEvent *event)
{ {
case GDK_BUTTON_PRESS: case GDK_BUTTON_PRESS:
control->onMouseEvent(control, gEvent_MousePress); control->onMouseEvent(control, gEvent_MousePress);
if (control->isTopLevel())
{
gMainWindow *win = ((gMainWindow *)control);
if (win->isPopup() && (x < 0 || y < 0 || x >= win->width() || y >= win->height()))
win->close();
}
break; break;
case GDK_2BUTTON_PRESS: case GDK_2BUTTON_PRESS:
@ -483,8 +476,6 @@ static void gambas_handle_event(GdkEvent *event)
case GDK_BUTTON_RELEASE: case GDK_BUTTON_RELEASE:
control->onMouseEvent(control, gEvent_MouseRelease); control->onMouseEvent(control, gEvent_MouseRelease);
if (control->_grab)
gApplication::exitLoop(control);
break; break;
} }
@ -494,6 +485,26 @@ static void gambas_handle_event(GdkEvent *event)
control->onMouseEvent(control, gEvent_MouseMenu); control->onMouseEvent(control, gEvent_MouseMenu);
} }
if (type == gEvent_MousePress && control->isTopLevel())
{
gMainWindow *win = ((gMainWindow *)control);
if (win->isPopup())
{
control->getScreenPos(&xc, &yc);
x = (int)event->button.x_root - xc;
y = (int)event->button.y_root - yc;
if (x < 0 || y < 0 || x >= win->width() || y >= win->height())
win->close();
}
}
else if (type == gEvent_MouseRelease && control->_grab)
{
gApplication::exitLoop(control);
}
if (control->_proxy_for) if (control->_proxy_for)
{ {
control = control->_proxy_for; control = control->_proxy_for;