diff --git a/app/src/gambas3/.project b/app/src/gambas3/.project index 53194b599..a9f3b068a 100644 --- a/app/src/gambas3/.project +++ b/app/src/gambas3/.project @@ -1,7 +1,6 @@ # Gambas Project File 3.0 Title=Gambas 3 Startup=Project -Profiling=1 Icon=img/logo/logo-ide.png Version=3.14.90 VersionFile=1 diff --git a/app/src/gambas3/.src/Editor/Form/FToolBox.class b/app/src/gambas3/.src/Editor/Form/FToolBox.class index deef7c4b8..660839c85 100644 --- a/app/src/gambas3/.src/Editor/Form/FToolBox.class +++ b/app/src/gambas3/.src/Editor/Form/FToolBox.class @@ -23,7 +23,7 @@ End Public Sub Form_Open() - $aOrder = ["Form", "View", "Report", "WebForm", "TermForm", "Dialog", "Chooser", "Container", "Data", "Network", "Special"] + $aOrder = ["Form", "WebForm", "TermForm", "View", "Report", "Dialog", "Chooser", "Container", "Data", "Network", "Special"] ReadConfig SetTool diff --git a/comp/src/gb.web.gui/.src/Table/WebTableSelection.class b/comp/src/gb.web.gui/.src/CSelection.class similarity index 63% rename from comp/src/gb.web.gui/.src/Table/WebTableSelection.class rename to comp/src/gb.web.gui/.src/CSelection.class index 8a92939f1..555ecb0f7 100644 --- a/comp/src/gb.web.gui/.src/Table/WebTableSelection.class +++ b/comp/src/gb.web.gui/.src/CSelection.class @@ -7,48 +7,18 @@ Private $bInvert As Boolean Event _Fake -' Private Sub Dump() -' -' Dim I As Integer -' ' -' ' Print System.Backtrace.Join(" ") -' ' -' Print "Selection = "; -' For I = 0 To $aSel.Max Step 2 -' Print "["; $aSel[I]; ","; $aSel[I + 1]; "] "; -' Next -' Print -' -' End -' - -Private Sub GetTable() As WebTable - - Return Object.Parent(Me) +Public Sub GetItemCount() As Integer + Return Object.Parent(Me).Count + End Public Sub Refresh() - GetTable().Refresh + Object.Parent(Me).Refresh End -Public Sub SetSelection(aSel As Integer[], bInvert As Boolean) - - $aSel = aSel - $bInvert = bInvert - -End - -Public Sub Copy() As WebTableSelection - - Dim hSel As WebTableSelection = New WebTableSelection - - hSel.SetSelection($aSel.Copy(), $bInvert) - Return hSel - -End Private Sub Add(iStart As Integer, Optional iLength As Integer = 1) @@ -177,7 +147,7 @@ Public Function GetSelectedRows() As Integer[] If $bInvert Then - For I = 0 To GetTable().Max + For I = 0 To GetItemCount() - 1 If IsSelected(I) Then aRet.Add(I) Next @@ -198,8 +168,8 @@ Public Function GetSelectedRows() As Integer[] End -Private Sub Count_Read() As Integer - +Private Function Count_Read() As Integer + Dim I, N As Integer For I = 0 To $aSel.Max Step 2 @@ -208,79 +178,22 @@ Private Sub Count_Read() As Integer If $bInvert Then - Return GetTable().Count - N + Return GetItemCount() - N Else Return N Endif - + End - - Public Sub IsEverythingSelected() As Boolean If $bInvert And $aSel.Count = 0 Then Return True End -' Public Sub InsertRows(iStart As Integer, iLength As Integer) -' -' Dim I, S, L As Integer -' -' For I = 0 To $aSel.Max Step 2 -' -' S = $aSel[i] -' L = $aSel[I + 1] -' -' If iStart <= S Then -' $aSel[I] += iLength -' Else If iStart <= (S + L) Then -' $aSel[I + 1] = iStart - S -' $aSel.Add(iStart + iLength) -' $aSel.Add(L - (iStart - S)) -' Endif -' -' Next -' -' 'Dump -' -' End -' -' Public Sub RemoveRows(iStart As Integer, iLength As Integer) -' -' Dim I, S, L As Integer -' -' I = 0 -' While I < $aSel.Count -' -' S = $aSel[I] -' L = $aSel[I + 1] -' -' If (iStart + iLength) <= S Then -' $aSel[I] -= iLength -' Else If iStart >= (S + L) Then -' Else -' If iStart < S Then -' iLength -= (S - iStart) -' $aSel[I] = iStart -' Endif -' $aSel[I + 1] -= iLength - (iStart - S) -' Endif -' -' If $aSel[I + 1] <= 0 Then -' $aSel.Remove(I, 2) -' Else -' I += 2 -' Endif -' -' Wend -' -' 'Dump -' -' End Public Sub GetCurrent() As Integer @@ -288,8 +201,56 @@ Public Sub GetCurrent() As Integer If $aSel.Count = 2 Then iCurrent = $aSel[0] - If iCurrent < GetTable().Count Then Return iCurrent + If iCurrent < GetItemCount() Then Return iCurrent Endif Return -1 End + +Public Sub InsertRow(iRow As Integer) + + Dim I As Integer + Dim S As Integer + Dim L As Integer + + For I = 0 To $aSel.Max Step 2 + + S = $aSel[I] + L = $aSel[I + 1] + + If iRow <= S Then + Inc $aSel[I] + Else If iRow < (S + L) Then + Inc $aSel[I + 1] + Endif + + Next + +End + +Public Sub RemoveRow(iRow As Integer) + + Dim I As Integer + Dim S As Integer + Dim L As Integer + + I = 0 + While I < $aSel.Count + + S = $aSel[I] + L = $aSel[I + 1] + + If iRow <= S Then + Dec $aSel[I] + Else If iRow < (S + L) Then + Dec $aSel[I + 1] + If $aSel[I + 1] = 0 Then + $aSel.Remove(I, 2) + Continue + Endif + Endif + + I += 2 + Wend + +End diff --git a/comp/src/gb.web.gui/.src/Table/WebTable.class b/comp/src/gb.web.gui/.src/Table/WebTable.class index ef615786b..40fd9fb0c 100644 --- a/comp/src/gb.web.gui/.src/Table/WebTable.class +++ b/comp/src/gb.web.gui/.src/Table/WebTable.class @@ -4,6 +4,7 @@ Export Inherits WebControl Public Const _Properties As String = "*,Border=True,Mode{Select.*}=None,ShowCheck=True,ShowHeader=True,Sortable" +Public Const _Group As String = "View" Public Const _DrawWith As String = "GridView" Public Const _DefaultSize As String = "24,24" Public Const _DefaultEvent As String = "Data" @@ -34,7 +35,7 @@ Property SortOrder As Integer Private $hColumns As _WebTableColumns Private $iCount As Integer Private $iMode As Integer -Private $hSelection As WebTableSelection +Private $hSelection As CSelection Private $iStep As Integer = 100 Private $iDisplay As Integer = 100 @@ -138,7 +139,7 @@ Private Sub PrintBody(iStart As Integer, iEnd As Integer) If $bNoCheck Then Print " id=\""; Me.Name & ":" & CStr(iRow); "\"" - If IsSelected(iRow) Then Print " class=\"gw-table-row-selected\";" + If IsSelected(iRow) Then Print " class=\"gw-selected\";" 'Print Me._GetUpdateJS("onclick", "$" & CStr(iRow)); Print " onmousedown=\"gw.table.select("; JS(Me.Name); ","; iRow; Else @@ -244,12 +245,11 @@ Private Sub SetSelection() If $iMode = Select.None Then $hSelection = Null Else - If Not $hSelection Then $hSelection = New WebTableSelection As "TableSelection" + If Not $hSelection Then $hSelection = New CSelection As "Selection" Endif End - Public Sub SelectAll() If $hSelection Then diff --git a/comp/src/gb.web.gui/.src/Test/Webform1.class b/comp/src/gb.web.gui/.src/Test/Webform1.class index ede0ae753..bab316bb5 100644 --- a/comp/src/gb.web.gui/.src/Test/Webform1.class +++ b/comp/src/gb.web.gui/.src/Test/Webform1.class @@ -190,3 +190,17 @@ Public Sub WebButton7_Click() WebFileButton1.Abort() End + +Public Sub WebListBox1_Activate() + + Message(WebListBox1.Text) + +End + +Public Sub WebListBox1_Select() + + Dim aSel As String[] = WebListBox1.Selection + + WebTextArea1.Text = aSel.Join() + +End diff --git a/comp/src/gb.web.gui/.src/Test/Webform1.webform b/comp/src/gb.web.gui/.src/Test/Webform1.webform index 3e2b5d371..9d3c2a275 100644 --- a/comp/src/gb.web.gui/.src/Test/Webform1.webform +++ b/comp/src/gb.web.gui/.src/Test/Webform1.webform @@ -132,8 +132,36 @@ } Index = 1 Text = ("Tab 2") + { WebVBox1 WebVBox + #MoveScaled(1,1,133.75,12) + { WebRadioButton1 WebRadioButton + #MoveScaled(1,1,131.75,3) + Text = ("Alpha") + } + { WebRadioButton2 WebRadioButton + #MoveScaled(1,4,131.75,3) + Text = ("Beta") + } + { WebRadioButton3 WebRadioButton + #MoveScaled(1,7,131.75,3) + Text = ("Gamma") + } + } + { WebListBox1 WebListBox + #MoveScaled(1,14,133.75,31) + Height = "14em" + List = [("Élément 1"), ("Élément 2"), ("Élément 3"), ("Élément 4"), ("Élément 5"), ("Élément 6"), ("Élément 7"), ("Élément 8"), ("Élément 9"), ("Élément 10"), ("Élément 11"), ("Élément 12")] + Mode = Select.Multiple + UseHTML = True + } + { WebTextArea1 WebTextArea + #MoveScaled(1,46,133.75,16) + Height = "8em" + } + Index = 2 + Text = ("Tab 3") { WebHBox2 WebHBox - #MoveScaled(1,1,85.75,6) + #MoveScaled(1,1,133.75,6) Spacing = True { WebCheckBox1 WebCheckBox #MoveScaled(1,1,18,4) @@ -153,30 +181,13 @@ } } { WebImage1 WebImage - #MoveScaled(1,8,85.75,6) + #MoveScaled(1,8,133.75,6) Image = "favicon.png" } { lblTime WebLabel - #MoveScaled(1,15,85.75,4) + #MoveScaled(1,15,133.75,4) Font = "4em" } - Index = 2 - Text = ("Tab 3") - { WebVBox1 WebVBox - #MoveScaled(1,1,85.75,14) - { WebRadioButton1 WebRadioButton - #MoveScaled(1,1,83.75,4) - Text = ("Alpha") - } - { WebRadioButton2 WebRadioButton - #MoveScaled(1,5,83.75,4) - Text = ("Beta") - } - { WebRadioButton3 WebRadioButton - #MoveScaled(1,9,83.75,4) - Text = ("Gamma") - } - } Index = 0 } { WebTimer1 WebTimer diff --git a/comp/src/gb.web.gui/.src/Test/Webform3.class b/comp/src/gb.web.gui/.src/Test/Webform3.class new file mode 100644 index 000000000..59634eba9 --- /dev/null +++ b/comp/src/gb.web.gui/.src/Test/Webform3.class @@ -0,0 +1,4 @@ +' Gambas class file + +Export + diff --git a/comp/src/gb.web.gui/.src/Test/Webform3.webform b/comp/src/gb.web.gui/.src/Test/Webform3.webform new file mode 100644 index 000000000..ecbc4dee9 --- /dev/null +++ b/comp/src/gb.web.gui/.src/Test/Webform3.webform @@ -0,0 +1,9 @@ +# Gambas Form File 3.0 + +{ WebForm WebForm + #MoveScaled(0,0,64,91) + { WebListBox1 WebListBox + #MoveScaled(6,5,24,39) + List = [("Élément 1"), ("Élément 2"), ("Élément 3"), ("Élément 4"), ("Élément 5"), ("Élément 6"), ("Élément 7"), ("Élément 8"), ("Élément 9"), ("Élément 10"), ("Élément 11"), ("Élément 12")] + } +} diff --git a/comp/src/gb.web.gui/.src/WebControl.class b/comp/src/gb.web.gui/.src/WebControl.class index c615352a0..01b555c0b 100644 --- a/comp/src/gb.web.gui/.src/WebControl.class +++ b/comp/src/gb.web.gui/.src/WebControl.class @@ -120,7 +120,7 @@ Public Sub _new(Optional Parent As WebContainer) _NoRefresh = 1 Inc $iCount - WebForm.PrintLog("==== " & $iCount & " controls") + 'WebForm.PrintLog("==== " & $iCount & " controls") Inc $iLastId $iId = $iLastId @@ -864,7 +864,7 @@ Public Sub Delete() $cFromId[$iId] = Null _Invalid = True Dec $iCount - WebForm.PrintLog("==== " & $iCount & " controls") + 'WebForm.PrintLog("==== " & $iCount & " controls") 'Debug $sName;; $iId;; System.Backtrace.Join(" ") End diff --git a/comp/src/gb.web.gui/.src/WebForm.class b/comp/src/gb.web.gui/.src/WebForm.class index 516e8ae25..cdf8e222a 100644 --- a/comp/src/gb.web.gui/.src/WebForm.class +++ b/comp/src/gb.web.gui/.src/WebForm.class @@ -145,7 +145,6 @@ End Static Private Sub Upload(sKey As String) As Boolean - Dim sErr As String Dim sPath As String Dim sTarget As String @@ -192,8 +191,6 @@ Static Public Sub Main() Dim sRead As String Dim sWrite As String Dim sTemp As String - Dim sKey As String - Dim cEnv As Collection Dim sPath As String Dim aLib As String[] Dim sFile As String diff --git a/comp/src/gb.web.gui/.src/WebListBox.class b/comp/src/gb.web.gui/.src/WebListBox.class new file mode 100644 index 000000000..132ebee59 --- /dev/null +++ b/comp/src/gb.web.gui/.src/WebListBox.class @@ -0,0 +1,297 @@ +' Gambas class file + +Export +Inherits WebControl + +Public Const _Properties As String = "*,Border=True,List,Text,Mode{Select.*}=Single,UseHTML" +Public Const _Group As String = "View" +Public Const _DrawWith As String = "ListBox" +Public Const _DefaultSize As String = "24,4" +Public Const _Similar As String = "WebTextBox" +Public Const _DefaultEvent As String = "Click" + +'' This event is raised when an item is clicked in the list box. +Event Click +'' This event is raised when an item is clicked twice. +Event Activate +'' This event is raised when the selection changes. +Event Select + + +'' Return the listbox selection mode. +Property Mode As Integer +'' Return or set the text of the current selected item. +Property Text As String +'' Return the number of items in the combo-box popup. +Property Read Count As Integer +'' Return or set the index of the current selected item. +Property Index, Current As Integer +'' Return or set the contents of the combo-box popup as a string array. +Property List As String[] +'' Return the list of selected items. +Property Read Selection As Integer[] +'' Return or set if the items are HTML or plain text. +Property UseHTML As Boolean + +Private $aList As New String[] +Private $iMode As Integer +Private $hSelection As CSelection +Private $bHTml As Boolean + +Public Sub _new() + + Mode_Write(Select.Single) + +End + + +Public Sub _RenderStyleSheet() + + Me._StartStyleSheet + + Super._RenderStyleSheet() + + If $iMode = Select.None Then Me._AddStyleSheet("pointer-events: none;") + + Me._EndStyleSheet + +End + +Public Sub _Render() + + Dim I As Integer + + For I = 0 To $aList.Max + Print ""; + If $bHtml Then + Print $aList[I]; + Else + Print Html($aList[I]); + Endif + Print ""; + Next + + If $iMode = Select.Single Then WebForm._AddJavascript("$(" & JS(Me.Name) & ").gw_current = " & Index_Read()) + +End + +Public Sub _UpdateProperty(sProp As String, vValue As Variant) + + Select Case sProp + + Case "+" + + Inc Me._NoRefresh + Try Select(vValue[0], vValue[1]) + Dec Me._NoRefresh + + Case "-" + + Inc Me._NoRefresh + Try Unselect(vValue[0], vValue[1]) + Dec Me._NoRefresh + + Case "$" + + Inc Me._NoRefresh + Try Select(vValue) + Dec Me._NoRefresh + + End Select + +End + +Private Function Text_Read() As String + + Try Return $aList[Index_Read()] + +End + +Private Sub Text_Write(Value As String) + + Me.Index = $aList.Find(Value) + +End + +Private Function Count_Read() As Integer + + Return $aList.Count + +End + +Private Function Index_Read() As Integer + + If $iMode <> Select.None Then + Return $hSelection.GetCurrent() + Else + Return -1 + Endif + +End + +Private Sub Index_Write(Value As Integer) + + If $iMode = Select.None Then Return + UnselectAll + Select(Value) + +End + +Private Function List_Read() As String[] + + Return $aList.Copy() + +End + +Private Sub List_Write(Value As String[]) + + UnselectAll + If Not Value Then + $aList.Clear + Else + $aList = Value.Copy() + Endif + Me.Refresh + +End + +Private Function Mode_Read() As Integer + + Return $iMode + +End + +Private Sub SetSelection() + + If $iMode = Select.None Then + $hSelection = Null + Else + If Not $hSelection Then $hSelection = New CSelection As "Selection" + Endif + +End + +Private Sub Mode_Write(Value As Integer) + + If $iMode = Value Then Return + $iMode = Value + SetSelection + Me.Refresh + +End + +Public Sub Clear() + + UnselectAll + $aList.Clear + Me.Refresh + +End + +Public Sub SelectAll() + + If $hSelection Then + $hSelection.SelectAll + Raise Select + Endif + +End + +Public Sub UnselectAll() + + If $hSelection Then + $hSelection.UnselectAll + Raise Select + Endif + +End + +Public Sub Select(Row As Integer, Optional Length As Integer = 1) + + If $hSelection Then + + If $iMode = Select.Single Then + + $hSelection.UnselectAll + $hSelection.Select(Row) + + Else + + $hSelection.Select(Row, Length) + + Endif + + Raise Select + + Endif + +End + +Public Sub Unselect(Row As Integer, Optional Length As Integer = 1) + + If $hSelection Then + $hSelection.Unselect(Row, Length) + Raise Select + Endif + +End + +Public Sub IsSelected(Row As Integer) As Boolean + + If $hSelection Then Return $hSelection.IsSelected(Row) + +End + +Private Function Selection_Read() As Integer[] + + If $hSelection Then Return $hSelection.GetSelectedRows() + +End + +'' Add an item to the list. +'' +'' - ~Item~ is the text of the item to add. +'' - ~Index~ is the position the item will be inserted from. If not specified, the item is added at the end of the popup list. + +Public Sub Add(Item As String, Optional Index As Integer = -1) + + $aList.Add(Item, Index) + If $hSelection Then $hSelection.InsertRow(Index) + Me.Refresh + +End + +'' Remove an item from the list. +'' +'' - ~Index~ is the index of the item to remove, between 0 and [../count] - 1. + +Public Sub Remove(Index As Integer) + + $aList.Remove(Index) + If $hSelection Then $hSelection.RemoveRow(Index) + Me.Refresh + +End + +Private Function UseHtml_Read() As Boolean + + Return $bHtml + +End + +Private Sub UseHtml_Write(Value As Boolean) + + If $bHtml = Value Then Return + $bHtml = Value + Me.Refresh + +End diff --git a/comp/src/gb.web.gui/lib.js b/comp/src/gb.web.gui/lib.js index 1c47a9115..366c5d404 100644 --- a/comp/src/gb.web.gui/lib.js +++ b/comp/src/gb.web.gui/lib.js @@ -1093,9 +1093,9 @@ gw = { { tr = $(id + ':' + i); if (checked) - tr.addClass('gw-table-row-selected'); + tr.addClass('gw-selected'); else - tr.removeClass('gw-table-row-selected'); + tr.removeClass('gw-selected'); } gw.update(id, '!' + start + ':' + (end - start + 1), checked); @@ -1105,7 +1105,7 @@ gw = { { var elt = $(id + ':' + row); var last = $(id).gw_current; - var selected = !elt.hasClass('gw-table-row-selected'); + var selected = !elt.hasClass('gw-selected'); if (event) { @@ -1117,8 +1117,8 @@ gw = { else { if (last != undefined) - $(id + ':' + last) && $(id + ':' + last).removeClass('gw-table-row-selected'); - elt.addClass('gw-table-row-selected'); + $(id + ':' + last) && $(id + ':' + last).removeClass('gw-selected'); + elt.addClass('gw-selected'); gw.update(id, '$' + row, null); } @@ -1282,7 +1282,7 @@ gw = { child = $(child); gw.table.scroll(id, child.offsetLeft - (sw.clientWidth - child.offsetWidth) / 2, child.offsetTop - (sw.clientHeight - child.offsetHeight) / 2); } -}, + }, file: { @@ -1474,7 +1474,62 @@ gw = { { $(id).lastElementChild.innerHTML = text; } - } + }, + listbox: + { + selectRange: function(id, start, end, checked) + { + var items = $(id).children; + var i; + var elt; + + if (end < start) + { + i = start; + start = end; + end = i; + } + + for (i = start; i <= end; i++) + { + elt = items[i]; + if (checked) + elt.addClass('gw-selected'); + else + elt.removeClass('gw-selected'); + } + + gw.update(id, checked ? '+' : '-', [start, end - start + 1]); + }, + + select: function(id, row, event) + { + var items = $(id).children; + var elt = items[row]; + var last = $(id).gw_current; + var selected = !elt.hasClass('gw-selected'); + + if (event) + { + if (event.shiftKey && last) + gw.listbox.selectRange(id, last, row, selected); + else + gw.listbox.selectRange(id, row, row, selected); + } + else + { + if (last != undefined) + items[last] && items[last].removeClass('gw-selected'); + elt.addClass('gw-selected'); + gw.update(id, '$', row); + } + + $(id).gw_current = row; + + /*$(id).addClass('gw-unselectable'); + setTimeout(function() { $(id).removeClass('gw-unselectable'); }, 0);*/ + } + } } diff --git a/comp/src/gb.web.gui/style.css b/comp/src/gb.web.gui/style.css index 4286da8ef..c6a30469c 100644 --- a/comp/src/gb.web.gui/style.css +++ b/comp/src/gb.web.gui/style.css @@ -813,7 +813,6 @@ TABLE.gw-calendar > TBODY > TR > TD.gw-date-current { position: relative; border: solid 1px #C0C0C0; min-height: 0.5em; - border-radius: 0.25em; } .gw-progressbar.gw-noborder { @@ -825,7 +824,6 @@ TABLE.gw-calendar > TBODY > TR > TD.gw-date-current { height: 100%; background: #C0C0C0; border: solid 1px white; - border-radius: 0.25em; z-index: -1; } @@ -853,7 +851,7 @@ TABLE.gw-calendar > TBODY > TR > TD.gw-date-current { border: none; } -.gw-table-row-selected { +.gw-selected { background-color: #2980B9 !important; color: white !important; } @@ -924,3 +922,19 @@ TABLE.gw-calendar > TBODY > TR > TD.gw-date-current { left: -2000px; } +.gw-listbox { + display: flex; + flex-direction: column; + border: solid 1px #C0C0C0; + user-select: none; + cursor: pointer; + overflow: auto; +} + +.gw-listbox.gw-noborder { + border: none; +} + +.gw-listbox > DIV { + padding: 0.25em 0.5em; +}