Commits (2)
  • Benoît Minisini's avatar
    Key.Shortcut is a new property that returns a string describing the key of a... · a89f827a
    Benoît Minisini authored
    Key.Shortcut is a new property that returns a string describing the key of a keyboard event with all its modifiers.
    
    [GB.GTK]
    * NEW: Key.Shortcut is a new property that returns a string describing the key of a keyboard event with all its modifiers.
    
    [GB.GTK3]
    * NEW: Key.Shortcut is a new property that returns a string describing the key of a keyboard event with all its modifiers.
    
    [GB.QT4]
    * NEW: Key.Shortcut is a new property that returns a string describing the key of a keyboard event with all its modifiers.
    
    [GB.QT5]
    * NEW: Key.Shortcut is a new property that returns a string describing the key of a keyboard event with all its modifiers.
    a89f827a
  • Benoît Minisini's avatar
    Finish implementing keyboard event and menu shortcuts management. · 5b8ef31f
    Benoît Minisini authored
    [GB.WEB.GUI]
    * NEW: Key.Code returns the name of the pressed key, while Key.Text now returns the text associated with the key if there is.
    * NEW: Key.Shortcut returns the shortcut string associated with a keyboard event.
    * BUG: Fix Key.Control property.
    * NEW: Handle WebMenu.Shortcut property.
    * BUG: Use 'keydown' DOM event instead of 'keypress', as 'keypress' is deprecated.
    * NEW: Setting WebTextArea.Text now automatically moves the cursor and the scrollbar to the end of the text.
    5b8ef31f
# Gambas Project File 3.0
Title=Web application development using processes as session
Startup=Webform3
Startup=Webform1
UseHttpServer=1
Icon=.hidden/webform.png
Version=3.16.90
......
......@@ -8,8 +8,11 @@ Static Property Read Alt As Boolean
Static Property Read Meta As Boolean
Static Property Read Normal As Boolean
Static Property Read Code As String
Static Property Read Text As String
Static Property Read Shortcut As String
Static Public _Event As Collection
Static Private $cTrans As Collection
Static Private Function Shift_Read() As Boolean
......@@ -21,7 +24,7 @@ End
Static Private Function Control_Read() As Boolean
If Not _Event Then Error.Raise("No keyboard data")
Return _Event["controlKey"]
Return _Event["ctrlKey"]
End
......@@ -47,10 +50,67 @@ Static Private Function Normal_Read() As Boolean
End
Static Private Sub TranslateCode(sCode As String) As String
Dim sTrans As String
If Not $cTrans Then
$cTrans = [
"Alt": "AltKey",
"AltGraph": "AltGrKey",
"Control": "ControlKey",
"Meta": "MetaKey",
"Shift": "ShiftKey",
"ArrowDown": "Down",
"ArrowUp": "Up",
"ArrowLeft": "Left",
"ArrowRight": "Right",
" ": "Space"
]
Endif
sTrans = $cTrans[sCode]
If Not sTrans Then sTrans = sCode
Return sTrans
End
Static Private Function Code_Read() As String
Dim sCode As String
If Not _Event Then Error.Raise("No keyboard data")
sCode = TranslateCode(_Event["key"])
If String.Len(sCode) = 1 Then sCode = String.UCase(sCode)
Return sCode
End
Static Private Function Shortcut_Read() As String
Dim sShortcut As String
Dim sCode As String
If Not _Event Then Error.Raise("No keyboard data")
Return _Event["key"]
sCode = Code_Read()
If Key.Control And If sCode <> "ControlKey" Then sShortcut &= "Ctrl+"
If Key.Shift And If sCode <> "ShiftKey" Then sShortcut &= "Shift+"
If Key.Alt And If sCode <> "AltKey" Then sShortcut &= "Alt+"
If Key.Meta And If sCode <> "MetaKey" Then sShortcut &= "Meta+"
Return sShortcut & sCode
End
Static Private Function Text_Read() As String
Dim sCode As Variant
If Not _Event Then Error.Raise("No keyboard data")
sCode = _Event["key"]
If String.Len(sCode) = 1 Then Return sCode
End
......@@ -40,6 +40,8 @@ Public Sub panMenu_Render()
If hMenu.HasChildren() Then
Print "<div class=\"gw-menuitem-arrow\" id=\""; Html(hMenu.Name); "\""; Me._GetUpdateJS("onmouseover", "#popup", JS(hMenu.Name)); "></div>";
Else If hMenu.Shortcut Then
Print "<div class=\"gw-menuitem-shortcut\">"; Html(hMenu.Shortcut); "</div>";
Endif
Print "</div>";
......
......@@ -4,7 +4,7 @@ Export
Inherits WebContainer
Public Const _Group As String = "Container"
Public Const _Properties As String = "*,-Arrangement,-Margin,-Spacing,-Border,Text,Image{WebImage}"
Public Const _Properties As String = "*,-Arrangement,-Margin,-Spacing,-Border,Text,Image{WebImage},Shortcut"
Public Const _DefaultArrangement As String = "V"
Public Const _DefaultEvent As String = "Click"
......@@ -55,6 +55,7 @@ End
Private Sub Shortcut_Write(Value As String)
If $sShortcut = Value Then Return
$sShortcut = Value
Me.Refresh
......@@ -68,6 +69,7 @@ End
Private Sub Text_Write(Value As String)
If $sText = Value Then Return
$sText = Value
Me.Refresh
......
......@@ -9,6 +9,7 @@
{ WebMenu3 WebMenu
Text = ("Open")
Image = "icon:/small/open"
Shortcut = "Ctrl+Alt+O"
}
{ WebMenu11 WebMenu
Text = ("Open recent")
......@@ -29,6 +30,7 @@
{ WebMenu17 WebMenu
Text = ("WebMenu17")
Image = "icon:/small/play"
Shortcut = "Ctrl+Alt+B"
}
}
{ WebMenu14 WebMenu
......@@ -40,6 +42,7 @@
{ WebMenu8 WebMenu
Text = ("Save")
Image = "icon:/small/save"
Shortcut = "Ctrl+Alt+S"
}
{ WebMenu9 WebMenu
Text = ("Save as") & "..."
......@@ -50,6 +53,7 @@
{ WebMenu4 WebMenu
Text = ("Close")
Image = "icon:/small/quit"
Shortcut = "Ctrl+Alt+Q"
}
}
{ WebMenu2 WebMenu
......
......@@ -2,11 +2,11 @@
Export
' Static Public Sub _init()
'
' WebForm.Debug = True
'
' End
Static Public Sub _init()
WebForm.Debug = True
End
'
'
Public Sub WebComboBox1_Click()
......@@ -23,13 +23,13 @@ End
Public Sub WebForm_KeyPress()
WebForm.Print(Last.Name & ": " & JSON.ToString(Key._Event))
WebTextArea1.Text &= Last.Name & ": " & JSON.ToString(Key._Event) & " " & Key.Shortcut & " '" & Key.Text & "'\n"
End
Public Sub WebTextBox1_KeyPress()
WebForm.Print(Last.Name & ": " & JSON.ToString(Key._Event))
End
'
'
' Public Sub WebTextBox1_KeyPress()
'
' WebTextArea1.Text &= Last.Name & ": " & JSON.ToString(Key._Event) & " " & Key.Shortcut & "\n"
'
' End
......@@ -2,6 +2,7 @@
{ WebForm WebForm
#MoveScaled(0,0,64,91)
Height = "100%"
Arrangement = Arrange.Vertical
Margin = True
Spacing = True
......@@ -21,4 +22,9 @@
{ WebTextBox1 WebTextBox
#MoveScaled(1,40,62,4)
}
{ WebTextArea1 WebTextArea
#MoveScaled(1,45,62,16)
Expand = True
ReadOnly = True
}
}
......@@ -69,7 +69,7 @@ Public Sub _Render()
If Not $bReadOnly Then
Print "<input id=\""; Me.Name; ":entry\" class=\"gw-combobox-text\" type=\"text\" value=\""; Html(Text_Read()); "\""; Me._GetUpdateJS("onchange", "text", "this.value"); Me._GetUpdateJS("onblur", "text", "this.value");
If Object.CanRaise(Me, "Activate") Then
Print " onkeypress=\"gw.textbox.onactivate("; JS(Me.Name); ",event);\""; 'WebForm._AddJavascript("gw.textbox.onactivate(" & JS(Me.Name) & ");")
Print " onkeydown=\"gw.textbox.onactivate("; JS(Me.Name); ",event);\""; 'WebForm._AddJavascript("gw.textbox.onactivate(" & JS(Me.Name) & ");")
Endif
If Not Me.Enabled Then Print " disabled";
If $sPlaceHolder Then Print " placeholder=\""; Html($sPlaceHolder); "\"";
......
......@@ -285,7 +285,7 @@ End
Public Sub _GetKeyPressHandler() As String
If Object.CanRaise(Me, "KeyPress") Then Return " onkeydown=\"gw.onkeypress(" & JS($sName) & ", event)\""
If Object.CanRaise(Me, "KeyPress") Then Return " onkeydown=\"gw.onkeydown(" & JS($sName) & ", event)\""
End
......
......@@ -1382,3 +1382,38 @@ Public Sub _GetHeaders() As String[]
Return $aHeaders
End
Private Sub TriggerShortcut(hParent As WebContainer, sShortcut As String) As Boolean
Dim hChild As WebControl
Dim hMenu As WebMenu
For Each hChild In hParent.Children
hMenu = hChild
If String.UCase(hMenu.Shortcut) = sShortcut Then
Object.Raise(hChild, "Click")
Return True
Else If TriggerShortcut(hChild, sShortcut) Then
Return True
Endif
Next
End
Public Sub _RaiseKeyPress(cEvent As Variant)
Dim cSave As Collection
Dim sShortcut As String
Super._RaiseKeyPress(cEvent)
If Not $hMenuBar.HasChildren() Then Return
cSave = Key._Event
Key._Event = cEvent
sShortcut = Key.Shortcut
Key._Event = cSave
TriggerShortcut($hMenuBar, String.UCase(sShortcut))
End
......@@ -78,6 +78,7 @@ End
Public Sub _AfterRender()
Print "</textarea>"
WebForm._AddJavascript("gw.textarea.moveEnd(" & JS(Me.Name) & ")")
End
......
......@@ -86,7 +86,7 @@ Public Sub _Render()
If $bShowClear Then Print " style=\"padding-right:2.25em;\"";
Print " type=\""; If($bPassword, "password", "text"); "\""; Me._GetUpdateJS("onblur", "text", "this.value"); 'Me._GetUpdateJS("oninput", "text", "this.value"); '
If Object.CanRaise(Me, "Change") Then Print " oninput=\"gw.textbox.onchange("; JS(Me.Name); ");\"";
If Object.CanRaise(Me, "Activate") Then Print " onkeypress=\"gw.textbox.onactivate("; JS(Me.Name); ",event);\"";
If Object.CanRaise(Me, "Activate") Then Print " onkeydown=\"gw.textbox.onactivate("; JS(Me.Name); ",event);\"";
'WebForm._AddJavascript("gw.textbox.onactivate(" & JS(Me.Name) & ")")
Print Me._GetKeyPressHandler();
......
......@@ -1429,11 +1429,16 @@ gw = {
return $(id + ':entry').value;
},
moveEnd: function(id)
{
gw.setSelection($(id + ':entry'), [-1, -1]);
},
setText: function(id, text)
{
gw.command(function() {
$(id + ':entry').value = text;
gw.setSelection($(id + ':entry'), [text.length, text.length]);
gw.textbox.moveEnd(id);
gw.update(id, 'text', text);
});
},
......@@ -1462,7 +1467,22 @@ gw = {
copy: function(id)
{
gw.copy($(id));
}
},
moveEnd: function(id)
{
gw.setSelection($(id), [-1, -1]);
$(id).scrollTop = $(id).scrollHeight;
},
setText: function(id, text)
{
gw.command(function() {
$(id).value = text;
gw.textarea.moveEnd(id);
gw.update(id, 'text', text);
});
},
},
button:
......@@ -1572,9 +1592,9 @@ gw = {
}
},
onkeypress: function(event)
onkeydown: function(event)
{
console.log('onkeypress: ' + event);
console.log('onkeydown: ' + event);
if (!event.bubbles)
return;
......@@ -1603,5 +1623,5 @@ gw = {
}
}
document.onkeydown = gw.onkeypress;
document.onkeydown = gw.onkeydown;
......@@ -516,7 +516,8 @@ P:first-child,UL:first-child,OL:first-child {
.gw-menuitem-shortcut {
text-align: right;
padding: 0.25em 1em;
padding: 0.25em 0.25em 0.25em 1em;
min-width: 8em;
}
.gw-menuitem-arrow {
......
......@@ -104,6 +104,23 @@ BEGIN_PROPERTY(Key_Normal)
END_PROPERTY
BEGIN_PROPERTY(Key_Shortcut)
static GB_FUNCTION func;
static bool init = FALSE;
if (!init)
{
init = TRUE;
GB.GetFunction(&func, (void *)GB.FindClass("Shortcut"), "FromKey", NULL, "s");
}
if (GB_FUNCTION_IS_VALID(&func))
GB.Call(&func, 0, FALSE);
else
GB.ReturnNull();
END_PROPERTY
GB_DESC CKeyDesc[] =
{
......@@ -180,6 +197,8 @@ GB_DESC CKeyDesc[] =
GB_STATIC_PROPERTY_READ("Meta", "b", Key_Meta),
GB_STATIC_PROPERTY_READ("Normal", "b", Key_Normal),
GB_STATIC_PROPERTY_READ("Shortcut", "s", Key_Shortcut),
GB_END_DECLARE
};
......
......@@ -140,6 +140,23 @@ BEGIN_PROPERTY(Key_Normal)
END_PROPERTY
BEGIN_PROPERTY(Key_Shortcut)
static GB_FUNCTION func;
static bool init = FALSE;
if (!init)
{
init = TRUE;
GB.GetFunction(&func, (void *)GB.FindClass("Shortcut"), "FromKey", NULL, "s");
}
if (GB_FUNCTION_IS_VALID(&func))
GB.Call(&func, 0, FALSE);
else
GB.ReturnNull();
END_PROPERTY
GB_DESC CKeyDesc[] =
{
......@@ -216,7 +233,9 @@ GB_DESC CKeyDesc[] =
GB_STATIC_PROPERTY_READ("Alt", "b", Key_Alt),
GB_STATIC_PROPERTY_READ("Meta", "b", Key_Meta),
GB_STATIC_PROPERTY_READ("Normal", "b", Key_Normal),
GB_STATIC_PROPERTY_READ("Shortcut", "s", Key_Shortcut),
GB_END_DECLARE
};