From 5f958623a4e4d04e2e316afc0050521551420235 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Beno=C3=AEt=20Minisini?= Date: Tue, 9 Aug 2022 17:04:06 +0200 Subject: [PATCH] Continue 'Paint' implementation, and make the DrawingArea canvas resize automatically. [GB.WEB.GUI] * NEW: DrawingArea: The canvas now resizes automatically, and send its size to the server. * NEW: Paint: Implement 'Width' and 'Height' properties. * NEW: Paint: Add 'Translate()', 'Rotate()', 'Scale()' and 'Reset()' methods. * NEW: Paint: Add write-only 'Operator' property. Not all composition modes are supported at the moment. * BUG: Move focus frame when the window is resized. --- comp/src/gb.web.gui/.src/Paint/Paint.class | 39 ++++++++++- .../gb.web.gui/.src/Paint/PaintDriver.class | 19 ++++++ .../Paint/PaintDriver_WebDrawingArea.class | 66 ++++++++++++++++++- .../.src/Test/FTestDrawingArea.class | 4 ++ .../.src/Test/FTestDrawingArea.webform | 16 ++--- comp/src/gb.web.gui/.src/WebDrawingArea.class | 38 +++-------- comp/src/gb.web.gui/.src/WebForm.class | 3 +- comp/src/gb.web.gui/lib.js | 49 ++++++++++++-- comp/src/gb.web.gui/style.css | 9 +++ 9 files changed, 194 insertions(+), 49 deletions(-) diff --git a/comp/src/gb.web.gui/.src/Paint/Paint.class b/comp/src/gb.web.gui/.src/Paint/Paint.class index c747e2f5f..ca797d6f1 100644 --- a/comp/src/gb.web.gui/.src/Paint/Paint.class +++ b/comp/src/gb.web.gui/.src/Paint/Paint.class @@ -5,8 +5,14 @@ Export Static Private $aStack As New PaintDriver[] Static Property Read Device As WebControl -Static Property Write LineWidth As Float Static Property Brush As PaintBrush +Static Property W, Width As Integer Use $iWidth +Static Property H, Height As Integer Use $iHeight + +Static Property Write LineWidth As Float +Static Property Write Operator As Integer + +Public Enum OperatorOver, OperatorIn, OperatorOut, OperatorATop, OperatorDestOver, OperatorDestIn, OperatorDestOut, OperatorDestATop, OperatorAdd, OperatorSource, OperatorXor Static Private $hCurrent As New PaintDriver @@ -172,3 +178,34 @@ Static Public Sub DrawImage(Image As String, X As Float, Y As Float, Optional Wi $hCurrent.DrawImage(Image, X, Y, Width, Height, Opacity, Source) End + +Static Public Sub Translate(TX As Float, TY As Float) + + $hCurrent.Translate(TX, TY) + +End + +Static Public Sub Rotate(Angle As Float) + + $hCurrent.Rotate(Angle) + +End + +Static Public Sub Scale(SX As Float, Optional SY As Float) + + If IsMissing(SY) Then SY = SX + $hCurrent.Scale(SX, SY) + +End + +Static Public Sub Reset() + + $hCurrent.Reset() + +End + +Static Private Sub Operator_Write(Value As Integer) + + $hCurrent.SetOperator(Value) + +End diff --git a/comp/src/gb.web.gui/.src/Paint/PaintDriver.class b/comp/src/gb.web.gui/.src/Paint/PaintDriver.class index 16cb82651..3ec6ae529 100644 --- a/comp/src/gb.web.gui/.src/Paint/PaintDriver.class +++ b/comp/src/gb.web.gui/.src/Paint/PaintDriver.class @@ -73,3 +73,22 @@ Public Sub DrawImage((Image) As String, (X) As Float, (Y) As Float, (Width) As F End +Public Sub Translate((TX) As Float, (TY) As Float) + +End + +Public Sub Rotate((Angle) As Float) + +End + +Public Sub Scale((SX) As Float, (SY) As Float) + +End + +Public Sub Reset() + +End + +Public Sub SetOperator((Op) As Integer) + +End diff --git a/comp/src/gb.web.gui/.src/Paint/PaintDriver_WebDrawingArea.class b/comp/src/gb.web.gui/.src/Paint/PaintDriver_WebDrawingArea.class index a1e40f26d..1c8ed8f7d 100644 --- a/comp/src/gb.web.gui/.src/Paint/PaintDriver_WebDrawingArea.class +++ b/comp/src/gb.web.gui/.src/Paint/PaintDriver_WebDrawingArea.class @@ -6,8 +6,15 @@ Private $aEnd As New String[] Public Sub Begin() - WebForm._AddJavascript("{ var $_c = $_(" & JS(Me.Device.Name) & ").getContext('2d');") + Dim hDrawingArea As WebDrawingArea + + WebForm._AddJavascript("{ var $_c = $_(" & JS(Me.Device.Name & ":canvas") & ").getContext('2d');") WebForm._AddJavascript("$_c.beginPath();") + + hDrawingArea = Me.Device + + Paint.W = hDrawingArea._Width + Paint.H = hDrawingArea._Height End @@ -198,3 +205,60 @@ Public Sub DrawImage(Image As String, X As Float, Y As Float, Width As Float, He $aEnd.Add("});\n") End + +Public Sub Translate(TX As Float, TY As Float) + + WebForm._AddJavascript("$_c.translate(" & JS(TX) & "," & JS(TY) & ");") + +End + +Public Sub Rotate(Angle As Float) + + WebForm._AddJavascript("$_c.rotate(" & JS(Angle) & ");") + +End + +Public Sub Scale(SX As Float, SY As Float) + + WebForm._AddJavascript("$_c.scale(" & JS(SX) & "," & JS(SY) & ");") + +End + +Public Sub Reset() + + WebForm._AddJavascript("$_c.resetTransform();") + +End + +Public Sub SetOperator(Op As Integer) + + Dim sOp As String + + Select Case Op + Case Paint.OperatorOver + sOp = "source-over" + Case Paint.OperatorIn + sOp = "source-in" + Case Paint.OperatorOut + sOp = "source-out" + Case Paint.OperatorATop + sOp = "source-atop" + Case Paint.OperatorDestOver + sOp = "destination-over" + Case Paint.OperatorDestIn + sOp = "destination-in" + Case Paint.OperatorDestOut + sOp = "destination-out" + Case Paint.OperatorDestATop + sOp = "destination-atop" + Case Paint.OperatorAdd + sOp = "lighter" + Case Paint.OperatorSource + sOp = "copy" + Case Paint.OperatorXor + sOp = "xor" + End Select + + If sOp Then WebForm._AddJavascript("$_c.globalCompositeOperation = " & JS(sOp) & ";") + +End diff --git a/comp/src/gb.web.gui/.src/Test/FTestDrawingArea.class b/comp/src/gb.web.gui/.src/Test/FTestDrawingArea.class index 92d546b7a..679289119 100644 --- a/comp/src/gb.web.gui/.src/Test/FTestDrawingArea.class +++ b/comp/src/gb.web.gui/.src/Test/FTestDrawingArea.class @@ -34,6 +34,10 @@ Public Sub WebDrawingArea1_Draw() Paint.Fill() Paint.DrawImage("favicon.png", 150, 10, 200, 200, 0.5, Rect(10, 10, 100, 100)) + + Paint.Rectangle(5.5, 5.5, Paint.W - 12, Paint.H - 12) + Paint.LineWidth = 1 + Paint.Stroke(Color.Red) End diff --git a/comp/src/gb.web.gui/.src/Test/FTestDrawingArea.webform b/comp/src/gb.web.gui/.src/Test/FTestDrawingArea.webform index 2879ea167..9d9179d1f 100644 --- a/comp/src/gb.web.gui/.src/Test/FTestDrawingArea.webform +++ b/comp/src/gb.web.gui/.src/Test/FTestDrawingArea.webform @@ -2,20 +2,18 @@ { WebForm WebForm #MoveScaled(0,0,64,91) + Height = "40em" + Background = Color.SoftYellow Arrangement = Arrange.Vertical Margin = True Spacing = True - { WebContainer1 WebHBox - #MoveScaled(1,1,62,32) - { WebDrawingArea1 WebDrawingArea - #MoveScaled(1,1,34,30) - Width = "400px" - Height = "400px" - Border = True - } + { WebDrawingArea1 WebDrawingArea + #MoveScaled(1,1,62,30) + Expand = True + Border = True } { WebHBox1 WebHBox - #MoveScaled(1,34,62,7) + #MoveScaled(1,32,62,7) { WebButton1 WebButton #MoveScaled(1,1,16,5) Text = ("Refresh") diff --git a/comp/src/gb.web.gui/.src/WebDrawingArea.class b/comp/src/gb.web.gui/.src/WebDrawingArea.class index 45dd2ae13..472e21dfd 100644 --- a/comp/src/gb.web.gui/.src/WebDrawingArea.class +++ b/comp/src/gb.web.gui/.src/WebDrawingArea.class @@ -7,6 +7,9 @@ Public Const _Properties As String = "*,Border" Public Const _DrawWith As String = "DrawingArea" Public Const _DefaultEvent As String = "Draw" +Public _Width As Integer +Public _Height As Integer + Event Draw ' Event MouseDown ' Event MouseMove @@ -19,46 +22,21 @@ Public Sub _new() End -Public Sub _BeforeRender() - - Dim sWidth As String - Dim iWidth As Integer - Dim sHeight As String - Dim iHeight As Integer - - sWidth = Me.Width - If sWidth Ends "px" Then Try iWidth = CInt(Left(sWidth, -2)) - - sHeight = Me.Height - If sHeight Ends "px" Then Try iHeight = CInt(Left(sHeight, -2)) - - Print ""; - -End - Public Sub _Render() - If Object.CanRaise(Me, "Draw") Then WebForm._AddJavascript("gw.update(" & JS(Me.Name) & ",'#',null);") + Print ""; + WebForm._AddJavascript("gw.paint.init(" & JS(Me.Name) & ");") End -Public Sub _UpdateProperty(sProp As String, (vValue) As Variant) +Public Sub _UpdateProperty(sProp As String, vValue As Variant) If sProp = "#" Then + _Width = vValue[0] + _Height = vValue[1] Paint.Begin(Me) Raise Draw Paint.End Endif End - -Public Sub _AfterRender() - - Raise Render - Print ""; - -End - diff --git a/comp/src/gb.web.gui/.src/WebForm.class b/comp/src/gb.web.gui/.src/WebForm.class index 64ada780c..7cbc9a2db 100644 --- a/comp/src/gb.web.gui/.src/WebForm.class +++ b/comp/src/gb.web.gui/.src/WebForm.class @@ -791,7 +791,7 @@ Public Sub Render() $aJavascript.Clear - Print "" + Print "" If $sActiveControl Then $aJavascript.Add("gw.setFocus(" & JS($sActiveControl) & ");") @@ -1684,3 +1684,4 @@ Static Public Function _GetActiveControl() As WebControl Endif End + diff --git a/comp/src/gb.web.gui/lib.js b/comp/src/gb.web.gui/lib.js index 9ac6e4121..d96ed17e5 100644 --- a/comp/src/gb.web.gui/lib.js +++ b/comp/src/gb.web.gui/lib.js @@ -249,7 +249,8 @@ gw = { { if (xhr.status == 200 && xhr.responseText) { - xhr.gw_command && gw.log('==> ' + xhr.gw_command + '...'); + if (gw.debug && xhr.gw_command) + gw.log('==> ' + xhr.gw_command + '...'); gw.focus = false; var save = gw.saveFocus(); @@ -1783,6 +1784,31 @@ gw = { paint: { + init: function(id) + { + if (!gw.resizeObserver) + { + gw.resizeObserver = new ResizeObserver(function(entries) + { + for (let elt of entries) + gw.paint.update(elt.target.id); + }); + } + + gw.resizeObserver.observe($_(id)); + gw.paint.update(id); + }, + + update: function(id) + { + var w = $_(id + ':canvas').offsetWidth; + var h = $_(id + ':canvas').offsetHeight; + $_(id + ':canvas').width = w; + $_(id + ':canvas').height = h; + console.log('gw.paint.update: ' + w + ',' + h); + gw.update(id, '#', [w, h]); + }, + makeGradient: function(ctx, mo, coords, stops) { var grad, i, st; @@ -1898,14 +1924,23 @@ gw = { gw.sendKeyPress(event, id); }, - onload: function() + body: { - document.body.addEventListener('focusin', gw.onFocus); - document.body.addEventListener('focusout', gw.onFocus); - gw.raise(null, 'open'); - document.body.style.opacity = '1'; - document.body.style.pointerEvents = 'auto'; + onLoad: function() + { + document.body.addEventListener('focusin', gw.onFocus); + document.body.addEventListener('focusout', gw.onFocus); + gw.raise(null, 'open'); + document.body.style.opacity = '1'; + document.body.style.pointerEvents = 'auto'; + }, + + onResize: function() + { + gw.onFocus(); + } } + } document.onkeydown = gw.onKeyDown; diff --git a/comp/src/gb.web.gui/style.css b/comp/src/gb.web.gui/style.css index b6aa9c35d..ccf029827 100644 --- a/comp/src/gb.web.gui/style.css +++ b/comp/src/gb.web.gui/style.css @@ -1105,9 +1105,18 @@ TD.gw-table-check { } .gw-drawingarea { + position: relative; border: solid 1px #C0C0C0; } .gw-drawingarea.gw-noborder { border: none; } + +.gw-drawingarea > CANVAS { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; +}