diff --git a/comp/src/gb.spreadsheet/.project b/comp/src/gb.spreadsheet/.project index fb9dd88d0..09a0bab3a 100644 --- a/comp/src/gb.spreadsheet/.project +++ b/comp/src/gb.spreadsheet/.project @@ -1,10 +1,15 @@ # Gambas Project File 3.0 -Title= +Title=Gambas SpreadSheet Component Startup=FMain Version=0.0.1 Component=gb.image Component=gb.gui Component=gb.form +Component=gb.eval +Description="This component aim to provide a very basic spreadsheet." +Authors="Fabien Bodard" +TabSize=2 Translate=1 Language=en_US +Vendor=FabienBodard Packager=1 diff --git a/comp/src/gb.spreadsheet/.src/CResolver.class b/comp/src/gb.spreadsheet/.src/CResolver.class new file mode 100644 index 000000000..9831fcf97 --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/CResolver.class @@ -0,0 +1,104 @@ +' Gambas class file + +Inherits Expression +Public Data As Variant +Event Data(Name As String) +Static Private $aFunctions As String[] +Private $hSP As SpreadSheet +'Static Private $aAllowedIdentifiers As String[] = ["page", "pages", "index"] + +Static Private Sub LoadFunctions() + + $aFunctions = Split(File.Load("FunctionsList.txt"), "\n") + +End + +Static Public Sub IsIdentifier(Name As String) As Boolean + + Print "Identifier : " & Name + Print IsAvailableCellName(Name) + Return IsAvailableCellName(Name) + + 'Return $aAllowedIdentifiers.Exist(LCase(Name)) +End + +Static Public Sub IsSubr(Name As String) As Boolean + + If Not $aFunctions Then LoadFunctions + ' Return if a the 'Name' Gambas subroutine is allowed. + Return $aFunctions.Exist(LCase(Name)) + 'Print Name + +End + +Public Sub GetValue(Name As String) As Variant + + 'Return the value Of the 'Name' identifier. + Data = 0 + 'Print object.parent(Me) + Raise Data(Name) + Return Data + 'Print "Get Value : " & Name + 'Return "2" + +End + +' Public Sub Coucou(Value As String) As String +' +' Return "Coucou " & Value +' +' End + +Static Private Function IsAvailableCellName(sName As String) As Boolean + + Dim i As Integer + Dim s As String + + For i = 1 To Len(sName) + s = Mid(sName, i, 1) + If Not IsLetter(s) Then Break + Next + + Return IsDigit(Mid(sName, i)) + +End + +Private Sub GetParent() As SpreadSheet + + Return Object.Parent(Me) + +End + +Private Function ConvertToCells(sName As String) As Integer + + Dim i As Integer + Dim s, ss As String + + For i = 1 To Len(sName) + s = Mid(sName, i, 1) + If Not IsLetter(s) Then Break + ss &= s + Next + +End + +Private Sub ColLetterToInt(sValue As String) As Integer + + Dim iLetter As Integer + Dim iResult As Integer + + If sValue = "" Then Return + sValue = UCase(sValue) + Select Case Len(sValue) + Case 1 + Return Asc(sValue) - 65 + + Case 2 + Return Asc(Left(sValue) - 65) * 26 + (Asc(Right(sValue)) - 65) + + Case 3 + Return (Asc(Left(sValue) - 65) * (26 * 26)) + (Asc(Mid(sValue, 2, 1) - 65) * 26) + (Asc(Right(sValue)) - 65) + + End Select + +End diff --git a/comp/src/gb.spreadsheet/.src/FMain.class b/comp/src/gb.spreadsheet/.src/FMain.class deleted file mode 100644 index 0a5fa73ac..000000000 --- a/comp/src/gb.spreadsheet/.src/FMain.class +++ /dev/null @@ -1,2 +0,0 @@ -' Gambas class file - diff --git a/comp/src/gb.spreadsheet/.src/FMain.form b/comp/src/gb.spreadsheet/.src/FMain.form deleted file mode 100644 index 3ee8ed652..000000000 --- a/comp/src/gb.spreadsheet/.src/FMain.form +++ /dev/null @@ -1,5 +0,0 @@ -# Gambas Form File 3.0 - -{ FMain Form - MoveScaled(0,0,64,64) -} diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet.class b/comp/src/gb.spreadsheet/.src/SpreadSheet.class new file mode 100644 index 000000000..032ad1912 --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet.class @@ -0,0 +1,740 @@ +' Gambas class file + +'Fast +Export +Inherits UserControl +Public _NumbersWidth As Integer = 30 +Public _NumbersHeight As Integer = 20 + +Property Read Columns As _SpreadSheetColumns +Property Read Rows As _SpreadSheetRows +Property Read Current As _SpreadSheetCell +Property ShowGrid As Boolean + +Property Row As Integer +Property Column As Integer + +Private $hRows As _SpreadSheetRows +Private $hColumns As _SpreadSheetColumns +Private $hView As New ScrollArea(Me) As "View" + +Private $iFirstVisibleRow As Integer +Private $iFirstVisibleCol As Integer +Private $iLastVisibleCol As Integer +Private $iLastVisibleRow As Integer + +Private $iCurrCellRow As Integer = 3 +Private $iCurrCellCol As Integer = 3 +Private $bShowGrid As Boolean = True + +Private $hCursorCol As Cursor +Private $hCursorRow As Cursor +Private $hCursorCross As Cursor +Private iChangeColWidth As Integer = -1 +Private iChangeRowHeight As Integer = -1 + +Private $hCurSelection As _SpreadSheetSelection +Private $aSelections As New _SpreadSheetSelection[] +Private $bSelMode As Boolean +Private $fScale As Float = 1 +Private $hTimerScroll As Timer +Private $SX As Integer +Private $SY As Integer +Private $hObs As Observer +Private $hEditor As TextBox +Private $hResolver As CResolver + +Private $htmrEnsureVisible As Timer +Private $iRowEV As Integer +Private $iColEv As Integer + +Static Public _Cells As New Collection + +'Private $hColumns As _SpreadSheetColumns + +Public Sub _new() + + $hView.ScrollBar = Scroll.Both + $hView.Background = Color.White + $hView.Tracking = True + $hView.Focus = True + '_NumbersWidth = $hView.Font.TextWidth(5000) + 5 + $hRows = New _SpreadSheetRows(150) As "Rows" + $hColumns = New _SpreadSheetColumns(150) As "Columns" + + $hCursorCol = New Cursor(Picture["cursorcol.png"]) + $hCursorrow = New Cursor(Picture["cursorrow.png"]) + $hCursorCross = New Cursor(Picture["cross.png"]) + $hObs = New Observer($hView.View) As "OBS" + + $hEditor = New TextBox(Me) As "Editor" + $hEditor.Ignore = True + $hEditor.Border = False + + $hResolver = New CResolver As "Resolver" + +End + +Private Function Columns_Read() As _SpreadSheetColumns + + Return $hColumns + +End + +Private Function Rows_Read() As _SpreadSheetRows + + Return $hRows + +End + +Public Sub View_Draw() + + Dim Column As _SpreadSheetColumn + Dim Row As _SpreadSheetRow + Dim X, Y, H, W As Integer + Dim i, j As Integer + Dim hSelection As _SpreadSheetSelection + Dim iSR, iER, iSC, iEC As Integer + Dim iRow, iCol As Integer + Dim hCell As Variant + + Paint.Scale($fScale, $fScale) + '_NumbersWidth = draw.TextWidth($hRows.Count) + 5 + + $hView.ResizeContents($hColumns._FullWidth * $fScale, $hRows._FullHeight * $fScale) + + 'Calcul de la zone visible + $iFirstVisibleCol = Max(0, $hColumns.FindColumnByPos($hView.ScrollX + _NumbersWidth)) + $iLastVisibleCol = $hColumns.FindColumnByPos($hView.ScrollX + $hView.ClientWidth / $fScale) + 'Print $iFirstVisibleCol, $iLastVisibleCol + If $iLastVisibleCol = -1 Then $iLastVisibleCol = $hColumns.Max + + $iFirstVisibleRow = $hRows.FindRowByPos($hView.ScrollY + _NumbersHeight * 2) + 'Print "FirstVisible " & $hRows.FindRowByPos($hView.ScrollY) + $iLastVisibleRow = $hRows.FindRowByPos($hView.ScrollY + $hView.ClientHeight / $fScale + _NumbersHeight) + + If $iLastVisibleRow = -1 Then $iLastVisibleRow = $hRows.Max + + Paint.AntiAlias = False + + 'Dessin du fond des barre d'entetes + Paint.Brush = Paint.Color(Color.Lighter(Color.Lighter(Color.LightGray))) + Paint.Rectangle(0, 0, Paint.Width / $fScale, _NumbersHeight) + Paint.Rectangle(0, 0, _NumbersWidth, Paint.Height / $fScale) + Paint.Fill + + Paint.Brush = Paint.Color(Color.Lighter(Color.LightGray)) + Paint.Rectangle(_NumbersWidth / 2, _NumbersHeight / 2, Paint.Width / $fScale, _NumbersHeight / 2) + Paint.Rectangle(_NumbersWidth / 2, _NumbersHeight / 2, _NumbersWidth / 2, Draw.Height / $fScale) + Paint.Fill + + Paint.Brush = Paint.Color(Color.Gray) + Paint.Rectangle(0, 0, _NumbersWidth, _NumbersHeight) + Paint.Stroke + + DrawColsHeader($iFirstVisibleCol, $iLastVisibleCol, $iCurrCellCol) + DrawRowsHeader(Max(0, $iFirstVisibleRow - 1), $iLastVisibleRow, $iCurrCellRow) + + 'Dessiner les cellules connues + Paint.ClipRect = Rect(_NumbersWidth, _NumbersHeight, (Paint.Width / $fScale) - _NumbersWidth, (Paint.Height / $fScale) - _NumbersHeight) + 'Paint.Rectangle(_NumbersWidth + 6, _NumbersHeight, Paint.Width - _NumbersWidth, Paint.Height - _NumbersHeight) + + For iCol = $iFirstVisibleCol To $iLastVisibleCol + For iRow = Max(0, $iFirstVisibleRow - 1) To $iLastVisibleRow + hCell = _Cells[GetCellKey(iRow, iCol)] + If hCell Then DrawCell(hCell, irow, iCol) + Next + Next + + Paint.Background = Color.SetAlpha(Color.Violet, 180) + + 'Dessiner les selections + For Each hSelection In $aSelections + iSR = Min(hSelection.StartRow, hSelection.EndRow) + iER = Max(hSelection.StartRow, hSelection.EndRow) + iSC = Min(hSelection.StartColumn, hSelection.EndColumn) + iEC = Max(hSelection.StartColumn, hSelection.EndColumn) + + X = $hColumns[Max($iFirstVisibleCol, iSC)]._X - $hView.ScrollX + Y = $hRows[Max($iFirstVisibleRow - 1, iSR)]._Y - $hView.ScrollY + W = ($hColumns[Min($iLastVisibleCol, iEC)]._X + $hColumns[iEC].Width) - (X + $hView.ScrollX) + H = ($hRows[Min($iLastVisibleRow, iER)]._Y + $hRows[iER].Height) - (Y + $hView.ScrollY) + paint.Rectangle(X, Y, W, H) + Paint.Fill + + Next + + 'Dessinner la grille + Paint.Brush = Paint.Color(Color.LightGray) + If $bShowGrid Then + For i = $iFirstVisibleRow To $iLastVisibleRow + Paint.MoveTo(_NumbersWidth, $hRows[i]._Y - $hView.ScrollY) + Paint.LineTo(Paint.Width / $fScale, $hRows[i]._Y - $hView.ScrollY) + Next + + For j = $iFirstVisibleCol To $iLastVisibleCol + Paint.MoveTo($hColumns[j]._X - $hView.ScrollX, _NumbersHeight) + Paint.LineTo($hColumns[j]._X - $hView.ScrollX, Paint.Height / $fScale) + Next + Paint.Stroke + Endif + + 'Dessiner la cellule courante + column = $hColumns[$iCurrCellCol] + row = $hRows[$iCurrCellRow] + X = column._X - $hView.ScrollX + Y = Row._Y - $hView.ScrollY + Paint.Rectangle(x, y, column.Width + 1, row.Height + 1) + Paint.LineWidth = 3 + Paint.Brush = Paint.Color(Color.Black) + Paint.Stroke + Paint.Rectangle(x + column.Width - 3, Y + row.Height - 3, 6, 6) + Paint.LineWidth = 1 + Paint.Background = Color.Red + Paint.Fill(True) + Paint.Background = Color.Black + Paint.Stroke + + Paint.ClipRect = Null + +End + +Private Sub DrawRowsHeader(iFirstRow As Integer, iLastRow As Integer, iCurRow As Integer) + + Dim i As Integer + ' Dim iHeight As Integer = _NumbersHeight + ' Dim iWidth As Integer = _NumbersWidth + + Dim hRect As New Rect(0, _NumbersHeight, _NumbersWidth + 1, (Paint.Height / $fScale) - _NumbersHeight) + 'Dim j As Integer + + Paint.ClipRect = hRect + + For i = iFirstRow To iLastRow + + If i = iCurRow Then + Paint.Font.Bold = True + Paint.Rectangle(0, $hRows[i]._Y - $hView.ScrollY, _NumbersWidth, $hRows[i].Height) + + Paint.Brush = Paint.Color(Color.Lighter(Color.Blue)) + Paint.Fill(True) + Paint.Brush = Paint.Color(Color.Gray) + Paint.Stroke + Paint.Brush = Paint.Color(Color.White) + + Else + + Paint.Font.Bold = False + Paint.Brush = Paint.Color(Color.Gray) + Paint.Rectangle(0, $hRows[i]._Y - $hView.ScrollY, _NumbersWidth, $hRows[i].Height) + Paint.Stroke + Endif + Paint.DrawText(i + 1, 0, $hRows[i]._Y - $hView.ScrollY, _NumbersWidth, $hRows[i].Height, Align.Center) + Next + Paint.ClipRect = Null + ' For i = $iFirstVisibleRow To $iLastVisibleRow + ' For j = $iFirstVisibleCol To $iLastVisibleCol + ' If i = $iCurrCellRown anf If j = $iCurrCellCol Then + ' Endif + ' Next + ' Next + +End + +Private Sub DrawColsHeader(iFirstCol As Integer, iLastCol As Integer, iCurCol As Integer) + + Dim i As Integer + Dim iHeight As Integer = _NumbersHeight + 'Dim iWidth As Integer = _NumbersWidth + Dim hRect As New Rect(_NumbersWidth, 0, (Paint.Width / $fScale) - _NumbersWidth, _NumbersHeight) + + Paint.ClipRect = hRect + For i = iFirstCol To iLastCol + Paint.Rectangle($hColumns[i]._X - $hView.ScrollX, 0, $hColumns[i].Width, iHeight) + If i = iCurCol Then + + Paint.Font.Bold = True + Paint.Brush = Paint.Color(Color.Lighter(Color.Blue)) + Paint.Fill(True) + Paint.Brush = Paint.Color(Color.Gray) + Paint.Stroke + Paint.Brush = Paint.Color(Color.White) + Else + Paint.Brush = Paint.Color(Color.Gray) + Paint.Stroke + Paint.Font.Bold = False + Endif + Paint.DrawText(ConvIntToText(i), $hColumns[i]._X - $hView.ScrollX, 0, $hColumns[i].Width, iHeight, Align.Center) + Paint.Fill + Next + + Paint.ClipRect = Null + +End + +Private Function ConvIntToText(iValue As Integer) As String + + Dim Nombre As String + + While (iValue >= 26) + + nombre = Chr((iValue Mod 26) + 65) & nombre ' on fait une s érie de division successives + iValue = iValue Div 26 'pour calculer chaque chiffre du nombre + + Wend + + If iValue >= 0 Then + If nombre Then + nombre = Chr(iValue Mod 26 + 64) & nombre + Else + nombre = Chr(iValue Mod 26 + 65) & nombre + Endif + Endif + + Return nombre + +End + +Public Sub View_MouseMove() + + Dim i, j, iMouse As Integer + Dim iMarge As Integer = 5 * $fScale + Dim X, Y As Integer + Dim hRect As Rect + + $SX = Mouse.X + $SY = Mouse.Y + + If iChangeColWidth > -1 Then + $hColumns[iChangeColWidth].Width = Max(10, (Mouse.x / $fScale + $hView.ScrollX) - $hColumns[iChangeColWidth]._X) + $hView.Refresh + Endif + If iChangeRowHeight > -1 Then + $hRows[iChangeRowHeight].Height = Max(10, (Mouse.Y / $fScale + $hView.ScrollY) - $hRows[iChangeRowHeight]._Y) + $hView.Refresh + Endif + 'Are we in the column header ? + If Mouse.y < _NumbersHeight * $fScale Then + i = $hColumns.FindColumnByPos(Mouse.x / $fScale + $hView.ScrollX) + If i > 0 Then + If Mouse.x + $hView.ScrollX < ($hColumns[i]._X + 5) * $fScale Or If Mouse.x + $hView.ScrollX > ($hColumns[i]._X + $hColumns[i].Width - 5) * $fScale Then + iMouse = Mouse.SizeH + Else + iMouse = Mouse.Custom + $hView.Cursor = $hCursorCol + Endif + Endif + Else + 'are we in the row header ? + If Mouse.X < _NumbersWidth * $fScale Then + i = $hRows.FindRowByPos(Mouse.y / $fScale + $hView.ScrollY) + If i > 0 Then + If Mouse.y + $hView.ScrollY < ($hRows[i]._y + 5) * $fScale Or If Mouse.y + $hView.ScrollY > ($hRows[i]._y + $hRows[i].Height - 5) * $fScale Then + iMouse = Mouse.SizeV + Else + iMouse = Mouse.Custom + $hView.Cursor = $hCursorRow + Endif + + Endif + Else + If $bSelMode Then + i = $hRows.FindRowByPos(Mouse.y / $fScale + $hView.ScrollY) + j = $hColumns.FindColumnByPos(Mouse.X / $fScale + $hView.ScrollX) + If $hCurSelection = Null Then + If (i <> $iCurrCellRow Or j <> $iCurrCellCol) Then + $hCurSelection = _SpreadSheetSelection($iCurrCellRow, $iCurrCellCol, $iCurrCellRow, $iCurrCellCol) + $aSelections.Add($hCurSelection) + Endif + Else + If i > -1 Then $hCurSelection.EndRow = i + If j > -1 Then $hCurSelection.EndColumn = j + Endif + $hView.Refresh + Endif + If Mouse.Left And If Not $hTimerScroll Then + $hTimerScroll = New Timer As "TimerScroll" + $hTimerScroll.Delay = 50 + $hTimerScroll.Start + Endif + Endif + + X = $hColumns[$iCurrCellCol]._X + $hColumns[$iCurrCellCol].Width + Y = $hRows[$iCurrCellRow]._Y + $hRows[$iCurrCellRow].Height + hRect = Rect(X, Y, 6, 6) + If hRect.Contains(Mouse.x, Mouse.y) Then + iMouse = Mouse.Custom + $hView.Cursor = $hCursorCross + Endif + Endif + + If $hView.Mouse <> iMouse Then $hView.Mouse = iMouse + +End + +Public Sub View_MouseDown() + + Dim i As Integer + + If $hEditor.Visible Then + HideEditor + Endif + + If Not Mouse.Left Then Return + 'selection de l'ensemble (coin gauche) + If Mouse.y < _NumbersHeight Then + If Mouse.x < _NumbersWidth Then + $aSelections.Clear + $aSelections.Add(_SpreadSheetSelection(0, 0, $hRows.Max, $hColumns.Max)) + $hView.Refresh + Return + Endif + + i = $hColumns.FindColumnByPos(Mouse.x / $fScale + $hView.ScrollX) + + If i > 0 Then + If Mouse.x + $hView.ScrollX < ($hColumns[i]._X + 5) * $fScale Then iChangeColWidth = i - 1 + If Mouse.x + $hView.ScrollX > ($hColumns[i]._X + $hColumns[i].Width - 5) * $fScale Then iChangeColWidth = i + Endif + + If iChangeColWidth > -1 Then + $hView.Mouse = Mouse.SizeH + Else + 'selection d'une colonne + $aSelections.Clear + $aSelections.Add(_SpreadSheetSelection(0, i, $hRows.Max, i)) + $hView.Refresh + Endif + Else + If Mouse.X < _NumbersWidth Then + i = $hRows.FindRowByPos(Mouse.y / $fScale + $hView.ScrollY) + If i > 0 Then + If Mouse.Y + $hView.ScrollY < ($hRows[i]._y + 5) * $fScale Then iChangeRowHeight = i - 1 + If Mouse.Y + $hView.ScrollY > ($hRows[i]._y + $hRows[i].Height - 5) * $fScale Then iChangeRowHeight = i + + Endif + If iChangeRowHeight > -1 Then + $hView.Mouse = Mouse.SizeV + Else + 'selection d'une ligne + $aSelections.Clear + $aSelections.Add(_SpreadSheetSelection(i, 0, i, $hColumns.Max)) + $hView.Refresh + + Endif + Else + $iCurrCellCol = $hColumns.FindColumnByPos(Mouse.X / $fScale + $hView.ScrollX) + $iCurrCellRow = $hRows.FindRowByPos(Mouse.Y / $fScale + $hView.ScrollY) + $bSelMode = True + + If Not Mouse.Control Then + $aSelections.Clear + $hCurSelection = Null + Else + $hCurSelection = _SpreadSheetSelection($iCurrCellRow, $iCurrCellCol, $iCurrCellRow, $iCurrCellCol) + $aSelections.Add($hCurSelection) + Endif + + $hView.Refresh + Endif + Endif + +End + +Public Sub View_MouseUp() + + If Mouse.Left Then + If iChangeColWidth > -1 Then + iChangeColWidth = -1 + $hView.Mouse = Mouse.Default + Endif + If iChangeRowHeight > -1 Then + iChangeRowHeight = -1 + $hView.Mouse = Mouse.Default + Endif + If $bSelMode Then + 'hSelBlocs.Add(hCurSelection) + $bSelMode = False + Endif + If $hTimerScroll Then + $hTimerScroll.Stop + $hTimerScroll = Null + Endif + 'Raise MouseUp() + 'Raise Click + Else + 'Raise MouseUp() + Endif + +End + +Public Sub View_MouseWheel() + + If Mouse.Control Then + $fScale = Min(1.0, Max($fScale + (Mouse.Delta * 0.1), 0.1)) + $hView.Refresh + Return + Endif + 'If Mouse.Control Then Stop Event + +End + +Public Sub View_DblClick() + + ShowEditor + +End + +Public Sub TimerScroll_Timer() + + Dim X As Integer = $SX + _NumbersWidth + $hView.ScrollX + Dim Y As Integer = $SY + _NumbersHeight + $hView.ScrollY + Dim iCol As Integer + Dim iRow As Integer + 'Print X, Y + iCol = Min($hColumns.Max, Max(0, $hColumns.FindColumnByPos(X / $fScale))) + iRow = Min($hRows.Max, Max(0, $hRows.FindRowByPos(Y / $fScale))) + 'Print icol, iRow + 'TODO: ajouter la fin du code + + SetVisible(irow, iCol) + +End + +Private Sub SetVisible(iRow As Integer, iCol As Integer) + + If iRow > $iLastVisibleRow Then + $hView.ScrollY = Min($hView.ScrollHeight, Max(0, ($hRows[iRow]._Y + $hRows[iRow].Height) - $hView.ClientHeight)) + Else If iRow < $iFirstVisibleRow Then + 'Print "inferieur" + $hView.ScrollY = Min($hView.ScrollHeight, Max(0, ($hRows[iRow]._Y - $hView.ClientHeight))) + 'Print $hRows[iRow]._Y - $hView.ScrollH + Endif + If iCol > $iLastVisibleCol Or If iRow < $iFirstVisibleCol Then + $hView.ScrollX = Min($hView.ScrollWidth, Max(0, ($hColumns[iCol]._X + $hColumns[iCol].Width) - $hView.ClientWidth)) + Endif + +End + +Public Sub OBS_MouseWheel() + + If Mouse.Control Then + $hView.UseMouse = False + 'Stop Event + Else + 'Stop Event + $hView.UseMouse = True + Endif + +End + +Public Sub _Get(Row As Integer, Column As Integer) As _SpreadSheetCell + + Dim sKey As String = GetCellKey(Row, Column) + Dim hCell As _SpreadSheetCell + + hCell = _Cells[sKey] + + If Not hCell Then + hCell = New _SpreadSheetCell As "Cells" + hCell._Key = sKey + Endif + Return hCell + +End + +Private Function Current_Read() As _SpreadSheetCell + + Return _get($iCurrCellRow, $iCurrCellCol) + +End + +Private Sub GetCellKey(iRow As Integer, iCol As Integer) As String + + 'If iRow >= iCol Then + ' Return CLong(iRow) * iRow + iCol * 2 + 'Else + ' Return CLong(iCol) * iCol + iRow * 2 + 1 + 'Endif + Return ConvIntToText(irow) & CStr(iCol) + +End + +Private Sub DrawCell(hCell As _SpreadSheetCell, iRow As Integer, iCol As Integer) + + Dim hRow As _SpreadSheetRow = $hRows[iRow] + Dim hCol As _SpreadSheetColumn = $hColumns[iCol] + Dim hRect As New Rectf(hCol._X - $hView.ScrollX, hRow._Y - $hView.ScrollY, hCol.Width, hRow.Height) + 'Paint.ClipRect = hRect + + If hCell.BackGround > -1 Then + Paint.Rectangle(hRect.x, hRect.y, hRect.Width, hRect.Height) + Paint.Background = hCell.BackGround + Paint.Fill + Else + 'Paint.Background = Color.White + Endif + + If hCell.Text Then + Paint.Background = Color.TextForeground + Paint.DrawText(hCell.Text, hRect.x + 3, hRect.Y + 3, hRect.W - 6, hRect.H - 6, hCell.Alignment) + Endif + ' hCell.Border = Border("6px") + If hCell.Border Then hCell.Border.Paint(hRect) + + 'Paint.ClipRect = Null + +End + +Public Sub Cells_Change() + + If Not _Cells.Exist(Last._Key) Then + _Cells[Last._Key] = Last + Endif + +End + +Public Sub View_KeyPress() + + Select Case Key.Code + Case Key.Enter, Key.Return + + Case Key.Down + Inc Me.Row + _EnsureVisible + Case Key.Up + Dec Me.Row + _EnsureVisible + Case Key.Left + Dec Me.Column + _EnsureVisible + Case Key.Right + Inc Me.Column + _EnsureVisible + Case Key.Home + Me.Row = 0 + Me.Column = 0 + _EnsureVisible + Case Key.Tab + + Case Key.End + Me.Row = $hRows.Max + If Key.Control Then + Me.Column = $hColumns.Max + Endif + _EnsureVisible + + Case Else + '$hEditor.Background = Color.Green + If IsAscii(Key.Text) Then ShowEditor + End Select + +End + +Public Sub Editor_LostFocus() + + If Last.Visible Then HideEditor + +End + +Public Sub Editor_KeyPress() + + Select Case Key.Code + Case Key.Enter, Key.Return + HideEditor + $hView.SetFocus + Inc $iCurrCellRow + $hView.Refresh + End Select + +End + +Private Sub ShowEditor() + + Dim s As String + + $hEditor.Move($hColumns[$iCurrCellCol]._X + 1, $hRows[$iCurrCellRow]._Y + 1, $hColumns[$iCurrCellCol].Width - 2, $hRows[$iCurrCellRow].Height - 2) + Try s = Key.Text + If Error Then + $hEditor.Text = Me[$iCurrCellRow, $iCurrCellCol].Text + $hEditor.Select + Else + $hEditor.Text = s + + Endif + + $hEditor.Show + $hEditor.SetFocus + +End + +Private Sub HideEditor() + + Me[$iCurrCellRow, $iCurrCellCol].Text = $hEditor.Text + $hEditor.Text = "" + $hEditor.Hide + $hView.SetFocus + +End + +Public Sub MoveTo(Row As Integer, Column As Integer) + + $iCurrCellRow = Min(Max(Row, 0), $hRows.Max) + $iCurrCellCol = Min(Max(Column, 0), $hColumns.Max) + $hView.Refresh + +End + +Private Function ShowGrid_Read() As Boolean + + Return $bShowGrid + +End + +Private Sub ShowGrid_Write(Value As Boolean) + + $bShowGrid = Value + $hView.Refresh + +End + +Private Function Row_Read() As Integer + + Return $iCurrCellRow + +End + +Private Sub Row_Write(Value As Integer) + + $iCurrCellRow = Max(0, Min($hRows.Max, Value)) + $hView.Refresh + +End + +Private Function Column_Read() As Integer + + Return $iCurrCellCol + +End + +Private Sub Column_Write(Value As Integer) + + $iCurrCellCol = Max(0, Min($hColumns.Count, Value)) + $hView.Refresh + +End + +Public Sub _EnsureVisible() + + If Not $htmrEnsureVisible Then $htmrEnsureVisible = New Timer As "TimerEnsureVisible" + $iRowEV = $iCurrCellRow + $iColEv = $iCurrCellCol + $htmrEnsureVisible.Trigger + +End + +Public Sub TimerEnsureVisible_Timer() + + $hView.EnsureVisible($hColumns[$iColEv]._X - _NumbersWidth, $hRows[$iRowEV]._Y - _NumbersHeight, $hColumns[$iColEv].Width, $hRows[$iRowEV].Height) + +End diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/FMain.class b/comp/src/gb.spreadsheet/.src/SpreadSheet/FMain.class new file mode 100644 index 000000000..716ef829f --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/FMain.class @@ -0,0 +1,50 @@ +' Gambas class file + + +Public Sub Form_Open() + + + +'SpreadSheet1.ShowGrid = False +SpreadSheet1[1, 1].Text = "toto" +'SpreadSheet1[1, 1].BackGround = Color.Green +'SpreadSheet1[1, 1].Border = SpreadSheetCellBorder("right-style:solid;width:0;right-Width:3;toprightradius:5") +SpreadSheet1.MoveTo(3, 3) +End + +Public Sub SpreadSheet1_Click() + + + +End + +Public Sub Button1_Click() + + + +End + +Public Sub ColorButton1_Change() + + 'For Each hCell In SpreadSheet + +End + +Public Sub DrawingArea1_Draw() + + Paint.Rectangle(10, 10, paint.Width - 20, Paint.Height - 20) + Paint.Stroke + + Paint.MoveTo(10, Paint.Height / 2) + Paint.RelLineTo(Paint.Width - 20, 0) + Paint.MoveTo(Paint.Width / 2, 10) + Paint.RelLineTo(0, Paint.Height - 20) + Paint.Stroke + +End + +Public Sub SpreadSheet1_MouseDown() + + + +End diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/FMain.form b/comp/src/gb.spreadsheet/.src/SpreadSheet/FMain.form new file mode 100644 index 000000000..99c312ef6 --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/FMain.form @@ -0,0 +1,21 @@ +# Gambas Form File 3.0 + +{ Form Form + MoveScaled(0,0,154,81) + Arrangement = Arrange.Horizontal + { SpreadSheet1 SpreadSheet + MoveScaled(0,0,55,60) + Expand = True + } + { Panel2 SidePanel + MoveScaled(92,1,49,66) + Orientation = Align.Right + { Panel1 Panel + MoveScaled(0,0,48,65) + Border = Border.Plain + { DrawingArea1 DrawingArea + MoveScaled(7,2,34,31) + } + } + } +} diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/SpreadSheetCellBorder.class b/comp/src/gb.spreadsheet/.src/SpreadSheet/SpreadSheetCellBorder.class new file mode 100644 index 000000000..4d5435ceb --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/SpreadSheetCellBorder.class @@ -0,0 +1,863 @@ +' Gambas class file + +Export Optional + +'From Benoit Minisini Border Class + +Public Enum Solid = 1, Dotted = 2, Dashed = 3, Double = 16 + +Property Width As Single +Property Radius As Single +Property Style As Integer +Property Color As Integer +Property Padding As Single +Property Margin As Single + +Public LeftStyle As Byte = Solid +Public RightStyle As Byte = Solid +Public TopStyle As Byte = Solid +Public BottomStyle As Byte = Solid + +Public LeftWidth As Single = 1 +Public RightWidth As Single = 1 +Public TopWidth As Single = 1 +Public BottomWidth As Single = 1 + +Public LeftColor As Integer +Public RightColor As Integer +Public TopColor As Integer +Public BottomColor As Integer + +Public TopLeftRadius As Single +Public TopRightRadius As Single +Public BottomLeftRadius As Single +Public BottomRightRadius As Single + +Public LeftPadding As Single +Public RightPadding As Single +Public TopPadding As Single +Public BottomPadding As Single + +Public LeftMargin As Single +Public RightMargin As Single +Public TopMargin As Single +Public BottomMargin As Single + +Public SlashStyle As Byte +Public BackslashStyle As Byte +Public SlashColor As Integer +Public BackslashColor As Integer +Public SlashWidth As Single +Public BackslashWidth As Single + +Static Private $aProp As String[] = ["width", "color", "radius", "style", "padding", "margin", "slash"] + +Private Const CURVE_MUL As Single = 0.44771525 + +Private Function Width_Read() As Single + + Return LeftWidth + +End + +Private Sub Width_Write(Value As Single) + + LeftWidth = Value + RightWidth = Value + TopWidth = Value + BottomWidth = Value + +End + +Private Function Radius_Read() As Single + + Return TopLeftRadius + +End + +Private Sub Radius_Write(Value As Single) + + TopLeftRadius = Value + TopRightRadius = Value + BottomLeftRadius = Value + BottomRightRadius = Value + +End + +Private Function Style_Read() As Integer + + Return LeftStyle + +End + +Private Sub Style_Write(Value As Integer) + + LeftStyle = Value + RightStyle = Value + TopStyle = Value + BottomStyle = value + +End + +Private Function Color_Read() As Integer + + Return LeftColor + +End + +Private Sub Color_Write(Value As Integer) + + LeftColor = Value + RightColor = value + TopColor = Value + BottomColor = value + +End + +Private Sub GetRectF(hRect As RectF, bPadding As Boolean, TopBorder As Border, BottomBorder As Border, LeftBorder As Border, RightBorder As Border) As RectF + + Dim LM, RM, TM, BM As Single + + LM = LeftMargin + If LeftBorder Then LM = Max(LM, LeftBorder.RightMargin) / 2 + RM = RightMargin + If RightBorder Then RM = Max(RM, RightBorder.LeftMargin) / 2 + TM = TopMargin + If TopBorder Then TM = Max(TM, TopBorder.BottomMargin) / 2 + BM = BottomMargin + If BottomBorder Then BM = Max(BM, BottomBorder.TopMargin) / 2 + + hRect = hRect.Copy() + hRect.Adjust(LM, TM, RM, BM) + If bPadding Then hRect.Adjust(LeftPadding + LeftWidth, TopPadding + TopWidth, RightPadding + RightWidth, BottomPadding + BottomWidth) + + Return hRect + +End + + +Public Sub Paint((Rect) As RectF, Optional TopBorder As Border, BottomBorder As Border, LeftBorder As Border, RightBorder As Border) + + Dim fWidth As Single + Dim iStyle As Integer + Dim iColor As Integer + Dim F As Single + Dim F2 As Single + Dim bTop As Boolean + Dim bRight As Boolean + Dim bLeft As Boolean + Dim bBottom As Boolean + Dim bSlash As Boolean + Dim bBackslash As Boolean + Dim X, Y, Width, Height As Single + Dim X1, Y1, X2, Y2 As Single + Dim iClip As Integer + + Rect = GetRectF(Rect, False, TopBorder, BottomBorder, LeftBorder, RightBorder) + If Rect.IsVoid() Then Return + + X = Rect.X + Y = Rect.Y + Width = Rect.W + Height = Rect.H + + Paint.Save + Paint.LineCap = Paint.LineCapSquare + + If TopStyle And If TopWidth Then bTop = True + If BottomStyle And If BottomWidth Then bBottom = True + If RightStyle And If RightWidth Then bRight = True + If LeftStyle And If LeftWidth Then bLeft = True + If SlashStyle And If SlashWidth Then bSlash = True + If BackslashStyle And If BackslashWidth Then bBackslash = True + + If bTop Then + + If TopStyle = LeftStyle And If TopStyle = RightStyle And If TopStyle = BottomStyle Then + If TopColor = LeftColor And If TopColor = RightColor And If TopColor = BottomColor Then + If TopWidth = LeftWidth And If TopWidth = RightWidth And If TopWidth = BottomWidth Then + + iStyle = TopStyle + fWidth = TopWidth + iColor = TopColor + + GoSub DRAW_BORDER + + Paint.Restore + Return + + Endif + Endif + Endif + + Paint.Save + + iClip = 0 + If bLeft And If TopLeftRadius > TopWidth Then iClip += 1 + If bRight And If TopRightRadius > TopWidth Then iClip += 2 + + Select Case iClip + + Case 0 + Paint.Rectangle(X, Y, Width, TopWidth) + + Case 1 + Paint.MoveTo(X, Y) + 'Print "MoveTo:";; X;; Y + Paint.LineTo(X + Width / 2, Y + Width / 2) + 'Print "LineTo:";; X + Width / 2;; Y + Width / 2 + Paint.LineTo(X + Width / 2, Y + TopWidth) + 'Print "LineTo:";; X + Width / 2;; Y + TopWidth + Paint.LineTo(X + Width, Y + TopWidth) + 'Print "LineTo:";; X + Width;; Y + TopWidth + Paint.LineTo(X + Width, Y) + 'Print "LineTo:";; X + Width;; Y + Paint.LineTo(X, Y) + 'Print "LineTo:";; X;; Y + + Case 2 + Paint.MoveTo(X, Y) + Paint.LineTo(X + Width, Y) + Paint.LineTo(X + Width / 2, Y + Width / 2) + Paint.LineTo(X + Width / 2, Y + TopWidth) + Paint.LineTo(X, Y + TopWidth) + Paint.ClosePath + + Case 3 + Paint.MoveTo(X, Y) + Paint.LineTo(X + Width, Y) + Paint.LineTo(X + Width / 2, Y + Width / 2) + Paint.ClosePath + + End Select + + Paint.Clip + + Paint.Rectangle(X, Y, Width, Height - TopWidth) + Paint.Clip + + GoSub CLIP_BORDER + + iStyle = TopStyle + fWidth = TopWidth + iColor = TopColor + + GoSub DRAW_BORDER + + Paint.Restore + + Endif + + If bRight Then + + Paint.Save + + iClip = 0 + If bTop And If TopRightRadius > RightWidth Then iClip += 1 + If bBottom And If BottomRightRadius > RightWidth Then iClip += 2 + + Select Case iClip + + Case 0 + Paint.Rectangle(X + Width - RightWidth, Y, RightWidth, Height) + + Case 1 + Paint.MoveTo(X + Width, Y) + Paint.LineTo(X + Width - Height / 2, Y + Height / 2) + Paint.LineTo(X + Width - RightWidth, Y + Height / 2) + Paint.LineTo(X + Width - RightWidth, Y + Height) + Paint.LineTo(X + Width, Y + Height) + Paint.ClosePath + + Case 2 + Paint.MoveTo(X + Width, Y) + Paint.LineTo(X + Width, Y + Height) + Paint.LineTo(X + Width - Height / 2, Y + Height / 2) + Paint.LineTo(X + Width - RightWidth, Y + Height / 2) + Paint.LineTo(X + Width - RightWidth, Y) + Paint.ClosePath + + Case 3 + Paint.MoveTo(X + Width, Y) + Paint.LineTo(X + Width - Height / 2, Y + Height / 2) + Paint.LineTo(X + Width, Y + Height) + Paint.ClosePath + + End Select + + ' If bTop And If TopRightRadius > RightWidth Then + ' Paint.MoveTo(X + Width - Height / 2, Y + Height / 2) + ' Paint.LineTo(X + Width, Y) + ' Paint.LineTo(X + Width, Y + Height / 2) + ' Paint.ClosePath + ' Else + ' Paint.Rectangle(X + Width - RightWidth, Y, RightWidth, Height / 2) + ' Endif + ' + ' If bBottom And If BottomRightRadius > RightWidth Then + ' Paint.MoveTo(X + Width - Height / 2, Y + Height / 2) + ' Paint.LineTo(X + Width, Y + Height) + ' Paint.LineTo(X + Width, Y + Height / 2) + ' Paint.ClosePath + ' Else + ' Paint.Rectangle(X + Width - RightWidth, Y + Height / 2, RightWidth, Height / 2) + ' Endif + + Paint.Clip + + Paint.Rectangle(X + RightWidth, Y, Width - RightWidth, Height) + Paint.Clip + + GoSub CLIP_BORDER + + iStyle = RightStyle + fWidth = RightWidth + iColor = RightColor + + GoSub DRAW_BORDER + + Paint.Restore + + Endif + + If bBottom Then + + Paint.Save + + iClip = 0 + If bLeft And If BottomLeftRadius > BottomWidth Then Inc iClip + If bRight And If BottomRightRadius > BottomWidth Then iClip += 2 + + Select Case iClip + + Case 0 + Paint.Rectangle(X, Y + Height - BottomWidth, Width, BottomWidth) + + Case 1 + Paint.MoveTo(X, Y + Height) + Paint.LineTo(X + Width / 2, Y + Height - Width / 2) + Paint.LineTo(X + Width / 2, Y + Height - BottomWidth) + Paint.LineTo(X + Width, Y + Height - BottomWidth) + Paint.LineTo(X + Width, Y + Height) + Paint.ClosePath + + Case 2 + Paint.MoveTo(X, Y + Height) + Paint.LineTo(X + Width, Y + Height) + Paint.LineTo(X + Width / 2, Y + Height - Width / 2) + Paint.LineTo(X + Width / 2, Y + Height - BottomWidth) + Paint.LineTo(X, Y + Height - BottomWidth) + Paint.ClosePath + + Case 3 + Paint.MoveTo(X, Y + Height) + Paint.LineTo(X + Width / 2, Y + Height - Width / 2) + Paint.LineTo(X + Width, Y + Height) + Paint.ClosePath + + End Select + + ' If bLeft And If BottomLeftRadius > BottomWidth Then + ' Paint.MoveTo(X + Width / 2, Y + Height - Width / 2) + ' Paint.LineTo(X + Width / 2, Y + Height) + ' Paint.LineTo(X, Y + Height) + ' Paint.ClosePath + ' Else + ' Paint.Rectangle(X, Y + Height - BottomWidth, Width / 2, BottomWidth) + ' Endif + ' + ' If bRight And If BottomRightRadius > BottomWidth Then + ' Paint.MoveTo(X + Width / 2, Y + Height - Width / 2) + ' Paint.LineTo(X + Width / 2, Y + Height) + ' Paint.LineTo(X + Width, Y + Height) + ' Paint.ClosePath + ' Else + ' Paint.Rectangle(X + Width / 2, Y + Height - BottomWidth, Width / 2, BottomWidth) + ' Endif + + Paint.Clip + + Paint.Rectangle(X, Y + BottomWidth, Width, Height - BottomWidth) + Paint.Clip + + GoSub CLIP_BORDER + + iStyle = BottomStyle + fWidth = BottomWidth + iColor = BottomColor + + GoSub DRAW_BORDER + + Paint.Restore + + Endif + + If bLeft Then + + Paint.Save + + iClip = 0 + If bTop And If TopLeftRadius > LeftWidth Then Inc iClip + If bBottom And If BottomLeftRadius > LeftWidth Then iClip += 2 + + Select Case iClip + + Case 0 + Paint.Rectangle(X, Y, LeftWidth, Height) + + Case 1 + Paint.MoveTo(X, Y) + Paint.LineTo(X + Height / 2, Y + Height / 2) + Paint.LineTo(X + LeftWidth, Y + Height / 2) + Paint.LineTo(X + LeftWidth, Y + Height) + Paint.LineTo(X, Y + Height) + Paint.ClosePath + + Case 2 + Paint.MoveTo(X, Y) + Paint.LineTo(X, Y + Height) + Paint.LineTo(X + LeftWidth, Y + Height) + Paint.LineTo(X + LeftWidth, Y + Height / 2) + Paint.LineTo(X + Height / 2, Y + Height / 2) + Paint.ClosePath + + Case 3 + Paint.MoveTo(X, Y) + Paint.LineTo(X + Height / 2, Y + Height / 2) + Paint.LineTo(X, Y + Height) + Paint.ClosePath + + End Select + + ' If bTop And If TopLeftRadius > LeftWidth Then + ' Paint.MoveTo(X + Height / 2, Y + Height / 2) + ' Paint.LineTo(X, Y) + ' Paint.LineTo(X, Y + Height / 2) + ' Paint.ClosePath + ' Else + ' Paint.Rectangle(X, Y, LeftWidth, Height / 2) + ' Endif + ' + ' If bBottom And If BottomLeftRadius > LeftWidth Then + ' Paint.MoveTo(X + Height / 2, Y + Height / 2) + ' Paint.LineTo(X, Y + Height) + ' Paint.LineTo(X, Y + Height / 2) + ' Paint.ClosePath + ' Else + ' Paint.Rectangle(X, Y + Height / 2, LeftWidth, Height / 2) + ' Endif + + Paint.Clip + + Paint.Rectangle(X, Y, Width - LeftWidth, Height) + Paint.Clip + + GoSub CLIP_BORDER + + iStyle = LeftStyle + fWidth = LeftWidth + iColor = LeftColor + + GoSub DRAW_BORDER + + Paint.Restore + + Endif + + If bSlash Or If bBackslash Then + + Paint.Save + + PaintRoundRectangle(X, Y, Width, Height, TopLeftRadius, TopRightRadius, BottomLeftRadius, BottomRightRadius, True) + + If bSlash Then + + X1 = X + Y1 = Y + Height + X2 = X + Width + Y2 = Y + + iStyle = SlashStyle + fWidth = SlashWidth + iColor = SlashColor + + GoSub DRAW_LINE + + Endif + + If bBackslash Then + + X1 = X + Y1 = Y + X2 = X + Width + Y2 = Y + Height + + iStyle = BackslashStyle + fWidth = BackslashWidth + iColor = BackslashColor + + GoSub DRAW_LINE + + Endif + + Paint.Restore + + Endif + + Paint.Restore + Return + +CLIP_BORDER: + + PaintRoundRectangle(X, Y, Width, Height, TopLeftRadius, TopRightRadius, BottomLeftRadius, BottomRightRadius, True) + Return + +INIT_STYLE: + + Paint.Background = iColor + + Select Case iStyle And 15 + Case Dotted + Paint.Dash = [0, 2] + Case Dashed + Paint.Dash = [3, 2] + Case Else + Paint.Dash = Null + End Select + + If iStyle And Double Then + + F = fWidth / 3 + F2 = F / 2 + + Else + + F = fWidth + F2 = F / 2 + + Endif + + Paint.LineWidth = F + + Return + +DRAW_BORDER: + + GoSub INIT_STYLE + + If iStyle And Double Then + + PaintRoundRectangle(X + F2, Y + F2, Width - F, Height - F, TopLeftRadius - F2, TopRightRadius - F2, BottomLeftRadius - F2, BottomRightRadius - F2) + Paint.Stroke + + PaintRoundRectangle(X + F * 2 + F2, Y + F * 2 + F2, Width - F * 5, Height - F * 5, TopLeftRadius - F2 - F * 2, TopRightRadius - F2 - F * 2, BottomLeftRadius - F2 - F * 2, BottomRightRadius - F2 - F * 2) + Paint.Stroke + + Else + + PaintRoundRectangle(X + F2, Y + F2, Width - F, Height - F, TopLeftRadius - F2, TopRightRadius - F2, BottomLeftRadius - F2, BottomRightRadius - F2) + Paint.Stroke + + Endif + + Return + +DRAW_LINE: + + GoSub INIT_STYLE + + If iStyle And Double Then + + Paint.MoveTo(X1 - F - F2, Y1) + Paint.LineTo(X2 - F - F2, Y2) + Paint.Stroke + + Paint.MoveTo(X1, Y1 - F - F2) + Paint.LineTo(X2, Y2 - F - F2) + Paint.Stroke + + Else + + Paint.MoveTo(X1, Y1) + Paint.LineTo(X2, Y2) + Paint.Stroke + + Endif + + Return + +End + +Private Sub ConvertToRect(hRect As RectF) As Rect + + Dim X, Y, W, H As Integer + + X = CInt(Ceil(hRect.X)) + Y = CInt(Ceil(hRect.Y)) + W = CInt(Floor(hRect.Right)) - X + H = CInt(Floor(hRect.Bottom)) - Y + + If W <= 0 Or If H <= 0 Then Return + + Return Rect(X, Y, W, H) + +End + + +Public Sub GetRect((Rect) As RectF, Optional WithPadding As Boolean, Optional TopBorder As Border, BottomBorder As Border, LeftBorder As Border, RightBorder As Border) As Rect + + Rect = GetRectF({Rect}, WithPadding, TopBorder, BottomBorder, LeftBorder, RightBorder) + If Rect.IsVoid() Then Return + + Return ConvertToRect(Rect) + +End + + +Public Sub Clip((Rect) As RectF, Optional TopBorder As Border, BottomBorder As Border, LeftBorder As Border, RightBorder As Border) As Rect + + Rect = GetRectF(Rect, False, TopBorder, BottomBorder, LeftBorder, RightBorder) + If Rect.IsVoid() Then Return Null + + PaintRoundRectangle(Rect.X, Rect.Y, Rect.Width, Rect.Height, TopLeftRadius, TopRightRadius, BottomLeftRadius, BottomRightRadius, True) + + Return ConvertToRect(Rect) + +End + + +Private Sub PaintRoundRectangle(X As Single, Y As Single, W As Single, H As Single, TL As Single, TR As Single, BL As Single, BR As Single, Optional bClip As Boolean) + + 'Paint.Debug = True + + If W <= 0 Or If H <= 0 Then + If bClip Then + Paint.Rectangle(X, Y, 0, 0) + Paint.Clip + Endif + 'Paint.Debug = False + Return + Endif + + TL = Max(0, Min(TL, Min(W, H) / 2)) + TR = Max(0, Min(TR, Min(W, H) / 2)) + BL = Max(0, Min(BL, Min(W, H) / 2)) + BR = Max(0, Min(BR, Min(W, H) / 2)) + + If TL <= 0 And If TR <= 0 And If BL <= 0 And If BR <= 0 Then + If bClip Then + Paint.Rectangle(X, Y, W, H) + Else + Paint.MoveTo(X, Y) + Paint.LineTo(X + W, Y) + Paint.MoveTo(X, Y) + Paint.LineTo(X, Y + H) + Paint.MoveTo(X + W, Y) + Paint.LineTo(X + W, Y + H) + Paint.MoveTo(X, Y + H) + Paint.LineTo(X + W, Y + H) + Endif + Else + ' PAINT->MoveTo(THIS, x + r, y); + ' PAINT->LineTo(THIS, x + w - r, y); + ' PAINT->CurveTo(THIS, x + w - r2, y, x + w, y + r2, x + w, y + r); + ' PAINT->LineTo(THIS, x + w, y + h - r); + ' PAINT->CurveTo(THIS, x + w, y + h - r2, x + w - r2, y + h, x + w - r, y + h); + ' PAINT->LineTo(THIS, x + r, y + h); + ' PAINT->CurveTo(THIS, x + r2, y + h, x, y + h - r2, x, y + h - r); + ' PAINT->LineTo(THIS, x, y + r); + ' PAINT->CurveTo(THIS, x, y + r2, x + r2, y, x + r, y); + ' + + Paint.MoveTo(X + TL, Y) + Paint.LineTo(X + W - TR, Y) + If TR > 0 Then Paint.CurveTo(X + W - TR * CURVE_MUL, Y, X + W, Y + TR * CURVE_MUL, X + W, Y + TR) + Paint.LineTo(X + W, Y + H - BR) + If BR > 0 Then Paint.CurveTo(X + W, Y + H - BR * CURVE_MUL, X + W - BR * CURVE_MUL, Y + H, X + W - BR, Y + H) + Paint.LineTo(X + BL, Y + H) + If BL > 0 Then Paint.CurveTo(X + BL * CURVE_MUL, Y + H, X, Y + H - BL * CURVE_MUL, X, Y + H - BL) + Paint.LineTo(X, Y + TL) + If TL > 0 Then Paint.CurveTo(X, Y + TL * CURVE_MUL, X + TL * CURVE_MUL, Y, X + TL, Y) + Paint.LineTo(X + TL, Y) + Endif + + If bClip Then Paint.Clip + + 'Paint.Debug = False + +End + +Private Function Padding_Read() As Single + + Return LeftPadding + +End + +Private Sub Padding_Write(Value As Single) + + LeftPadding = Value + RightPadding = Value + TopPadding = Value + BottomPadding = Value + +End + +Private Sub SetProperty(sProp As String, sValue As String) + + Dim vValue As Variant + Dim aValue As String[] + + aValue = Split(sValue, " ") + If aValue.Count >= 2 Then + If Not $aProp.Exist(sProp) Then Return + If aValue.Count < 3 Then aValue.Add(aValue[0]) + If aValue.Count < 4 Then aValue.Add(aValue[1]) + SetProperty("top" & sProp, aValue[0]) + SetProperty("right" & sProp, aValue[1]) + SetProperty("bottom" & sProp, aValue[2]) + SetProperty("left" & sProp, aValue[3]) + Return + Endif + + If sProp Ends "style" Then + Try vValue = Classes["Border"][Replace(sValue, "-", "")].Value + Else If sProp Ends "color" Then + Try vValue = Object.GetProperty(Classes["Color"], Replace(sValue, "-", "")) + If Left(sValue) = "#" Then + Try vValue = Val("&H" & Mid$(sValue, 2) & "&") + Endif + Else + Try vValue = CSingle(sValue) + Endif + If Error Then Return + + Try Object.SetProperty(Me, sProp, vValue) + +End + +Private Sub NormalyzeOneStyle(ByRef iStyle As Byte, ByRef fWidth As Single) + + If iStyle Then + If fWidth = 0 Then fWidth = 1 + Else + fWidth = 0 + Endif + +End + + +Private Sub NormalizeStyle() + + NormalyzeOneStyle(ByRef LeftStyle, ByRef LeftWidth) + NormalyzeOneStyle(ByRef RightStyle, ByRef RightWidth) + NormalyzeOneStyle(ByRef TopStyle, ByRef TopWidth) + NormalyzeOneStyle(ByRef BottomStyle, ByRef BottomWidth) + NormalyzeOneStyle(ByRef SlashStyle, ByRef SlashWidth) + NormalyzeOneStyle(ByRef BackslashStyle, ByRef BackslashWidth) + +End + +Static Public Sub _call(Optional (Style) As String) As SpreadSheetCellBorder + + Return New SpreadSheetCellBorder(Style) + +End + + +Public Sub _new(Optional (Style) As String) + + Dim aStyle As String[] + Dim sStyle As String + Dim iPos As Integer + Dim sProp As String + Dim sValue As String + + If Style Then + + aStyle = Split(Style, ";", "", True) + + For Each sStyle In aStyle + + iPos = InStr(sStyle, ":") + If iPos = 0 Then Continue + sProp = Replace(LCase(Trim(Left(sStyle, iPos - 1))), "-", "") + sValue = Trim(Mid$(sStyle, iPos + 1)) + If Not sProp Then Continue + If Not sValue Then Continue + + SetProperty(sProp, sValue) + + Next + + NormalizeStyle + + Endif + +End + +Private Function Margin_Read() As Single + + Return LeftMargin + +End + +Private Sub Margin_Write(Value As Single) + + LeftMargin = Value + RightMargin = Value + TopMargin = Value + BottomMargin = Value + +End + +Public Sub Copy() As Border + + Dim hBorder As New Border + + With hBorder + .BottomColor = BottomColor + .BottomLeftRadius = BottomLeftRadius + .BottomMargin = BottomMargin + .BottomPadding = BottomPadding + .BottomRightRadius = BottomRightRadius + .BottomStyle = BottomStyle + .BottomWidth = BottomWidth + .LeftColor = LeftColor + .LeftMargin = LeftMargin + .LeftPadding = LeftPadding + .LeftStyle = LeftStyle + .LeftWidth = LeftWidth + .RightColor = RightColor + .RightMargin = RightMargin + .RightPadding = RightPadding + .RightStyle = RightStyle + .RightWidth = RightWidth + .TopColor = TopColor + .TopLeftRadius = TopLeftRadius + .TopMargin = TopMargin + .TopPadding = TopPadding + .TopRightRadius = TopRightRadius + .TopStyle = TopStyle + .TopWidth = TopWidth + .SlashColor = SlashColor + .SlashStyle = SlashStyle + .SlashWidth = SlashWidth + .BackslashColor = BackslashColor + .BackslashStyle = BackslashStyle + .BackslashWidth = BackslashWidth + End With + + Return hBorder + +End + +Public Sub IsVoid() As Boolean + + If TopStyle And If TopWidth Then Return + If BottomStyle And If BottomWidth Then Return + If LeftStyle And If LeftWidth Then Return + If RightStyle And If RightWidth Then Return + + Return True + +End diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/SpreadSheetCellBorder2.class b/comp/src/gb.spreadsheet/.src/SpreadSheet/SpreadSheetCellBorder2.class new file mode 100644 index 000000000..ded99ff53 --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/SpreadSheetCellBorder2.class @@ -0,0 +1,120 @@ +' Gambas class file + +Public Enum Solid = 1, Dotted = 2, Dashed = 3, Double = 16 + +Property Width As Single + +Property Style As Integer +Property Color As Integer + +Public LeftStyle As Byte = Solid +Public RightStyle As Byte = Solid +Public TopStyle As Byte = Solid +Public BottomStyle As Byte = Solid + +Public LeftWidth As Single = 1 +Public RightWidth As Single = 1 +Public TopWidth As Single = 1 +Public BottomWidth As Single = 1 + +Public LeftColor As Integer +Public RightColor As Integer +Public TopColor As Integer +Public BottomColor As Integer + +Public TopLeftRadius As Single +Public TopRightRadius As Single +Public BottomLeftRadius As Single +Public BottomRightRadius As Single + +Public LeftPadding As Single +Public RightPadding As Single +Public TopPadding As Single +Public BottomPadding As Single + +Public LeftMargin As Single +Public RightMargin As Single +Public TopMargin As Single +Public BottomMargin As Single + +Public SlashStyle As Byte +Public BackslashStyle As Byte +Public SlashColor As Integer +Public BackslashColor As Integer +Public SlashWidth As Single +Public BackslashWidth As Single + +Static Private $aProp As String[] = ["width", "color", "radius", "style", "padding", "margin", "slash"] + +Private Const CURVE_MUL As Single = 0.44771525 + +Private Function Width_Read() As Single + + Return LeftWidth + +End + +Private Sub Width_Write(Value As Single) + + LeftWidth = Value + RightWidth = Value + TopWidth = Value + BottomWidth = Value + +End + +Private Function Radius_Read() As Single + + Return TopLeftRadius + +End + +Private Sub Radius_Write(Value As Single) + + TopLeftRadius = Value + TopRightRadius = Value + BottomLeftRadius = Value + BottomRightRadius = Value + +End + +Private Function Style_Read() As Integer + + Return LeftStyle + +End + +Private Sub Style_Write(Value As Integer) + + LeftStyle = Value + RightStyle = Value + TopStyle = Value + BottomStyle = value + +End + +Private Function Color_Read() As Integer + + Return LeftColor + +End + +Private Sub Color_Write(Value As Integer) + + LeftColor = Value + RightColor = value + TopColor = Value + BottomColor = value + +End + +Public Sub IsVoid() As Boolean + + If TopStyle And If TopWidth Then Return + If BottomStyle And If BottomWidth Then Return + If LeftStyle And If LeftWidth Then Return + If RightStyle And If RightWidth Then Return + + Return True + +End \ No newline at end of file diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetCell.class b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetCell.class new file mode 100644 index 000000000..f9264ba78 --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetCell.class @@ -0,0 +1,189 @@ +' Gambas class file + +Static Public _Cells As New Collection +Static Private $aIsAbon As New String[] +Static Private $aAbonTo As New String[] +'Static Private $hBaseCell As New _SpreadSheetCell +Property Alignment As Integer +Property Border As SpreadSheetCellBorder +Property Text, Formula As String +Property Read Value As Variant +Property Font As Font +Property Format As String +Property Read IsError As Boolean +Property Foreground As Integer +Property BackGround As Integer + +Private $iForeground As Integer +Private $iBackGround As Integer = -1 +Private $iAlignment As Integer +Private $hBorder As SpreadSheetCellBorder +Private $hFont As Font +Private $sFormula As String +Private $vValue As Variant +Private $sFormat As String +Public _Key As String +Event Change + +Static Public Function _call(sKey As String) As _SpreadSheetCell + + Dim hCell As New _SpreadSheetCell + + hCell._Key = sKey + +End + +Private Function Alignment_Read() As Integer + + Return $iAlignment + +End + +Private Sub Alignment_Write(Value As Integer) + + If $iAlignment = Value Then Return + + $iAlignment = Value + Raise Change + + +End + +Private Function Border_Read() As SpreadSheetCellBorder + + Return $hBorder + +End + +Private Sub Border_Write(Value As SpreadSheetCellBorder) + + If $hBorder = Value Then Return + + $hBorder = Value + Raise Change + + + +End + +Private Function Text_Read() As String + + Return $sFormula + +End + +Private Sub Text_Write(Value As String) + + If Value = $sFormula Then Return + + $sFormula = Value + Raise Change + + +End + +Private Function Value_Read() As Variant + + Return $vValue + +End + +Private Function Font_Read() As Font + + Return $hFont + +End + +Private Sub Font_Write(Value As Font) + + If $hFont = Value Then Return + + $hFont = Value + Raise Change + +End + +Private Function Format_Read() As String + + Return $sFormat + +End + +Private Sub Format_Write(Value As String) + + If $sFormat = Value Then Return + + $sFormat = Value + Raise Change + +End + +Private Function IsError_Read() As Boolean + +End + +Public Sub AbonTo(l As Long) + + $aIsAbon.Add(Me._Index) + $aAbonTo.Add(l) + +End + +Public Function GetFollowers() As String[] + + Dim iPos, ifind As Integer + Dim aret As New String[] + + Repeat + ifind = $aAbonTo.Find(_key,, iPos) + If ifind > -1 Then + iPos = ifind + 1 + aret.Add($aIsAbon[iPos]) + Endif + Until ifind > -1 + +End + +Public Function RemoveRegister() + +End + +Private Function Foreground_Read() As Integer + + Return $iForeground + +End + +Private Sub Foreground_Write(Value As Integer) + + If $iForeground = Value Then Return + + $iForeground = Value + Raise Change + +End + +Private Function BackGround_Read() As Integer + + Return $iBackGround + +End + +Private Sub BackGround_Write(Value As Integer) + + If $iBackGround = Value Then Return + + $iBackGround = Value + Raise Change + +End + +Public Function NeedSave() As Boolean + + If $sFormula <> "" Then Return True + If $iBackGround <> Color.Background Then Return True + If $iForeground <> Color.Foreground Then Return True + If $iAlignment <> Align.Normal Then Return True + If $hBorder <> Null Then Return True + If $hFont <> Null Then Return True +End diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetColumn.class b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetColumn.class new file mode 100644 index 000000000..04991aa58 --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetColumn.class @@ -0,0 +1,26 @@ +' Gambas class file + +Property Width As Integer +Static Public _BaseWidth As Integer = 100 +Private $iWidth As Integer = _BaseWidth +Public _X As Integer +Event _Foo + +Private Function Width_Read() As Integer + + Return $iWidth + +End + +Private Sub Width_Write(Value As Integer) + + $iWidth = Value + GetParent().SetColumnsPos() + +End + +Private Function GetParent() As _SpreadSheetColumns + + Return Object.Parent(Me) + +End diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetColumns.class b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetColumns.class new file mode 100644 index 000000000..a2bb7290a --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetColumns.class @@ -0,0 +1,111 @@ +' Gambas class file + +Private $hColumns As New _SpreadSheetColumn[] +Private $iFullWidth As Integer +Property Read _FullWidth As Integer +Property Read Max As Integer +Property Read Count As Integer + +Event _Foo + +Public Sub _New(Optional NbreColumn As Integer) + + Dim i As Integer + + If NbreColumn = 0 Then Return + $hColumns.Resize(NbreColumn) + For i = 0 To $hColumns.Max + $hColumns[i] = New _SpreadSheetColumn As "Column" + + Next + SetColumnsPos + +End + +Public Sub _get(Index As Integer) As _SpreadSheetColumn + + Return $hColumns[Index] + +End + +Public Function _Next() As _SpreadSheetColumn + + If IsNull(Enum.Index) Then Enum.Index = -1 + Enum.Index += 1 + If Enum.Index > $hColumns.Max Then + Enum.Stop + Return + Endif + Return $hColumns[Enum.Index] + +End + +Private Function GetParent() As SpreadSheet + + Return Object.Parent(Me) + +End + +Public Sub SetColumnsPos(Optional iFrom As Integer = 0) + + Dim i As Integer + Dim iX As Integer = GetParent()._NumbersWidth + + If iFrom > 0 Then iX = $hColumns[iFrom - 1]._X + $hColumns[iFrom - 1].Width + For i = iFrom To $hColumns.Max + $hColumns[i]._X = iX + iX += $hColumns[i].Width + Next + $iFullWidth = iX + +End + +Public Function FindColumnByPos(X As Integer) As Integer + + Dim iStart, iMiddle As Integer + Dim iEnd As Integer = $hColumns.Max + Dim iCol As Integer = -1 + + + Repeat + iMiddle = Int(iStart + (iEnd - iStart) / 2) + If x > $hColumns[iMiddle]._X - 1 And If x < $hColumns[iMiddle]._X + $hColumns[iMiddle].Width Then + 'trouvé + iCol = iMiddle + Else + If x < $hColumns[iMiddle]._X Then + iEnd = iMiddle - 1 + Else + iStart = iMiddle + 1 + Endif + + Endif + Until iCol <> -1 Or iMiddle > iEnd + 1 Or iStart > iEnd + + + If iCol = -1 Then + If X > $iFullWidth Then Return $hColumns.Max + Endif + + + Return iCol + +End + +Private Function _FullWidth_Read() As Integer + + Return $iFullWidth + +End + +Private Function Max_Read() As Integer + + Return $hColumns.Max + +End + +Private Function Count_Read() As Integer + + Return $hColumns.Count + +End diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetRow.class b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetRow.class new file mode 100644 index 000000000..783b7a0c7 --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetRow.class @@ -0,0 +1,33 @@ +' Gambas class file + +Property Height As Integer +Static Public _BaseHeight As Integer = 22 +Private $iHeight As Integer = _BaseHeight +Public _Y As Integer + +Event _Foo + +Public Sub _New(Optional iHeight As Integer) + + $iHeight = iHeight + +End + +Private Function Height_Read() As Integer + + Return $iHeight + +End + +Private Sub Height_Write(Value As Integer) + + $iHeight = Value + GetParent().SetRowsPos + +End + +Private Function GetParent() As _SpreadSheetRows + + Return Object.Parent(Me) + +End diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetRows.class b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetRows.class new file mode 100644 index 000000000..cdf75af19 --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetRows.class @@ -0,0 +1,108 @@ +' Gambas class file + +Private $hRows As New _SpreadSheetRow[] +Private $iFullHeight As Integer +Property Read _FullHeight As Integer +Property Read Max As Integer +Property Read Count As Integer + +Event _Foo + +Public Sub _New(Optional NbrRow As Integer) + + Dim i As Integer + + If NbrRow = 0 Then Return + $hRows.Resize(NbrRow) + For i = 0 To $hRows.Max + + $hRows[i] = New _SpreadSheetRow(GetParent().Font.Height + 5) As "Row" + + Next + SetRowsPos + GetParent()._NumbersWidth = GetParent().Font.TextWidth($hRows.Count) + 5 + +End + +Private Function GetParent() As SpreadSheet + + Return Object.Parent(Me) + +End + +Public Function _next() As _SpreadSheetRow + + If IsNull(Enum.Index) Then Enum.Index = -1 + Enum.Index += 1 + If Enum.Index > $hRows.Max Then + Enum.Stop + Return + Endif + Return $hRows[Enum.Index] + +End + +Public Sub _get(Index As Integer) As _SpreadSheetRow + + Return $hRows[Index] + +End + +Public Sub SetRowsPos(Optional iFrom As Integer = 0) + + Dim i As Integer + Dim iY As Integer = GetParent()._NumbersHeight + + If iFrom > 0 Then iY = $hRows[iFrom - 1]._Y + $hRows[iFrom - 1].Height + For i = iFrom To $hRows.Max + $hRows[i]._Y = iY + iY += $hRows[i].Height + Next + $iFullHeight = iY + +End + +Public Sub FindRowByPos(Y As Integer) As Integer + + Dim iStart, iMiddle As Integer + Dim iEnd As Integer = $hRows.Max + Dim iRow As Integer = -1 + + Repeat + iMiddle = Int(iStart + (iEnd - iStart) / 2) + If Y > $hRows[iMiddle]._Y - 1 And If Y < $hRows[iMiddle]._Y + $hRows[iMiddle].Height Then + 'trouvé + iRow = iMiddle + Else + If Y < $hRows[iMiddle]._Y Then + iEnd = iMiddle - 1 + Else + iStart = iMiddle + 1 + Endif + + Endif + Until iRow <> -1 Or iMiddle > iEnd + 1 Or iStart > iEnd + + If Y > $iFullHeight Then iRow = $hRows.Max + + Return iRow + +End + +Private Function _FullHeight_Read() As Integer + + Return $iFullHeight + +End + +Private Function Max_Read() As Integer + + Return $hRows.Max + +End + +Private Function Count_Read() As Integer + + Return $hRows.Count + +End diff --git a/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetSelection.class b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetSelection.class new file mode 100644 index 000000000..9a6b24c0d --- /dev/null +++ b/comp/src/gb.spreadsheet/.src/SpreadSheet/_SpreadSheetSelection.class @@ -0,0 +1,19 @@ +' Gambas class file + +Public StartColumn As Integer +Public StartRow As Integer +Public EndRow As Integer +Public EndColumn As Integer + +Static Public Function _call(StartRow As Integer, StartColumn As Integer, EndRow As Integer, EndColumn As Integer) As _SpreadSheetSelection + + Dim hRet As New _SpreadSheetSelection + + hRet.StartRow = StartRow + hRet.StartColumn = StartColumn + hRet.EndRow = EndRow + hRet.EndColumn = EndColumn + + Return hRet +End + diff --git a/comp/src/gb.spreadsheet/FunctionsList.txt b/comp/src/gb.spreadsheet/FunctionsList.txt new file mode 100644 index 000000000..af58f008d --- /dev/null +++ b/comp/src/gb.spreadsheet/FunctionsList.txt @@ -0,0 +1,52 @@ +asin +asinh +atan +atan2 +atanh +cos +cosh +deg +hyp +mag +pi +sin +sinh +tan +tanh +rad +abs +ceil +fix +floor +frac +int +max +min +round +sgn +asc +chr +comp +instr +lcase +left +len +ltrim +mida +quote +replace +right +rinstr +rtrim +space +string +trim +ucase +unquote +if +and +or +not +true +false +sqr \ No newline at end of file diff --git a/comp/src/gb.spreadsheet/Text1 b/comp/src/gb.spreadsheet/Text1 new file mode 100644 index 000000000..caf235c01 --- /dev/null +++ b/comp/src/gb.spreadsheet/Text1 @@ -0,0 +1,22 @@ +' Private Function ValueToLetter(iValue As Integer) As String +' Dim BaseDigit As New Integer[] +' Dim iR, iDiv As Integer +' Dim i As Integer +' Dim sRet As String +' Do +' If iValue < 25 Then Break +' iDiv = iValue Div 25 +' iR = iValue - (25 * iDiv) +' BaseDigit.Push(iR + 1) +' iValue = iDiv +' Loop +' +' BaseDigit.Push(iValue + 1) +' +' For i = 0 To BaseDigit.Max +' sRet &= Chr(65 + BaseDigit.Pop() - 1) +' +' Next +' Return sRet +' +' End diff --git a/comp/src/gb.spreadsheet/cross.png b/comp/src/gb.spreadsheet/cross.png new file mode 100644 index 000000000..c14ee08b2 Binary files /dev/null and b/comp/src/gb.spreadsheet/cross.png differ diff --git a/comp/src/gb.spreadsheet/cursorcol.png b/comp/src/gb.spreadsheet/cursorcol.png new file mode 100644 index 000000000..bb5a43ac0 Binary files /dev/null and b/comp/src/gb.spreadsheet/cursorcol.png differ diff --git a/comp/src/gb.spreadsheet/cursorrow.png b/comp/src/gb.spreadsheet/cursorrow.png new file mode 100644 index 000000000..e275dd321 Binary files /dev/null and b/comp/src/gb.spreadsheet/cursorrow.png differ