cypress_test/integration_tests/desktop/writer/shape_operations_spec.js | 4 kit/ChildSession.cpp | 27 + kit/ChildSession.hpp | 1 loleaflet/Makefile.am | 1 loleaflet/css/loleaflet.css | 43 ++ loleaflet/src/layer/FormFieldButtonLayer.js | 154 ++++++++++ loleaflet/src/layer/tile/TileLayer.js | 14 loleaflet/src/map/Map.js | 1 wsd/ClientSession.cpp | 7 9 files changed, 248 insertions(+), 4 deletions(-)
New commits: commit e0a82365f32bc379aefee292eeac24b96c8e657b Author: Tamás Zolnai <[email protected]> AuthorDate: Thu May 7 15:34:37 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:09 2020 +0200 cypress: fix shape operations test. Change-Id: Ibdca536bc8fb2a5b16d6ed085a65c25d1bc854b4 diff --git a/cypress_test/integration_tests/desktop/writer/shape_operations_spec.js b/cypress_test/integration_tests/desktop/writer/shape_operations_spec.js index abbfe64b3..21b0a0d8c 100644 --- a/cypress_test/integration_tests/desktop/writer/shape_operations_spec.js +++ b/cypress_test/integration_tests/desktop/writer/shape_operations_spec.js @@ -8,8 +8,8 @@ describe('Shape operations', function() { helper.afterAll('shape_operations.odt', 'writer'); }); - it.skip('Insert a simple shape.', function() { - helper.loadTestDoc('shape_operations.odt'); + it('Insert a simple shape.', function() { + helper.loadTestDoc('shape_operations.odt', 'writer'); // Scroll on the up toolbar cy.get('#toolbar-up .w2ui-scroll-right').click(); commit 68017efb3caa801b733090f5b8085afc315ef529 Author: Tamás Zolnai <[email protected]> AuthorDate: Thu May 7 15:14:13 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:09 2020 +0200 MSForms: remove weird blue border dispalyed around the drop down button. Change-Id: Iddb696f10d9eb5364904021dd50431e11efc8dfb diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css index b2dc2e8cb..227658acb 100644 --- a/loleaflet/css/loleaflet.css +++ b/loleaflet/css/loleaflet.css @@ -547,6 +547,7 @@ body { .form-field-button:hover, .form-field-button:focus { background: #DDDDDD; + outline: 0; } .form-field-button-image { commit c7c690c4e805aaf5ed40b0e7f30929d26ed59327 Author: Tamás Zolnai <[email protected]> AuthorDate: Thu May 7 14:21:24 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:08 2020 +0200 MSForms: stop propagation of mouse events for the drop down button. Change-Id: Id63056f1aa39cadfc62021c5220d301f7ea26af8 diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js index 33c6b561c..0acaabce5 100644 --- a/loleaflet/src/layer/FormFieldButtonLayer.js +++ b/loleaflet/src/layer/FormFieldButtonLayer.js @@ -90,6 +90,10 @@ L.FormFieldButton = L.Layer.extend({ image.src = 'images/unfold.svg'; button.addEventListener('click', this._onClickDropDown); + + // Stop propagation to the main document + button.addEventListener('mouseup', function(event) {event.stopPropagation();}); + button.addEventListener('mousedown', function(event) {event.stopPropagation();}); }, _buildDropDownList: function(framePos, frameWidth, frameHeight) { commit 98f4b50673f9dd2e1b56a6cb63679c5e5ac723d1 Author: Tamás Zolnai <[email protected]> AuthorDate: Thu May 7 12:36:00 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:08 2020 +0200 MSForms: do some styling of drop-down form field.. Change-Id: I70d4766dcf116e31cde18f67cfea6551197657a8 diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css index 8639f504d..b2dc2e8cb 100644 --- a/loleaflet/css/loleaflet.css +++ b/loleaflet/css/loleaflet.css @@ -532,6 +532,7 @@ body { border: 1px solid; position: absolute; height: 100%; + border-radius: 2px; } .form-field-button { @@ -541,6 +542,7 @@ body { height: 100%; box-sizing: content-box; padding: 0px; + border-radius: 2px; } .form-field-button:hover, .form-field-button:focus { @@ -554,6 +556,7 @@ body { .drop-down-field-list { position: absolute; border: 1px solid; + cursor: pointer; } .drop-down-field-list-item { @@ -563,3 +566,6 @@ body { .drop-down-field-list-item.selected { background: #99CCFF; } +.drop-down-field-list-item:hover { + background: #0b87e7; +} commit 75dc61da7e6305a2f6b6e8e9a45e016ae1fc2e7d Author: Tamás Zolnai <[email protected]> AuthorDate: Wed May 6 13:59:03 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:08 2020 +0200 MSForms: send item selection event to core. Change-Id: I10fceb66a4f8cd777c43411ddace3456a315b5a2 diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp index e70cfde2e..ba8bdf8ee 100644 --- a/kit/ChildSession.cpp +++ b/kit/ChildSession.cpp @@ -301,7 +301,8 @@ bool ChildSession::_handleInput(const char *buffer, int length) tokens.equals(0, "rendershapeselection") || tokens.equals(0, "removetextcontext") || tokens.equals(0, "dialogevent") || - tokens.equals(0, "completefunction")); + tokens.equals(0, "completefunction")|| + tokens.equals(0, "formfieldevent")); if (tokens.equals(0, "clientzoom")) { @@ -446,6 +447,10 @@ bool ChildSession::_handleInput(const char *buffer, int length) { return completeFunction(buffer, length, tokens); } + else if (tokens.equals(0, "formfieldevent")) + { + return formFieldEvent(buffer, length, tokens); + } else { assert(false && "Unknown command token."); @@ -1426,6 +1431,23 @@ bool ChildSession::dialogEvent(const char* /*buffer*/, int /*length*/, const Str return true; } +bool ChildSession::formFieldEvent(const char* buffer, int length, const StringVector& /*tokens*/) +{ + std::string sFirstLine = getFirstLine(buffer, length); + std::string sArguments = sFirstLine.substr(std::string("formfieldevent ").size()); + + if (sArguments.empty()) + { + sendTextFrameAndLogError("error: cmd=formfieldevent kind=syntax"); + return false; + } + + getLOKitDocument()->setView(_viewId); + getLOKitDocument()->sendFormFieldEvent(sArguments.c_str()); + + return true; +} + bool ChildSession::completeFunction(const char* /*buffer*/, int /*length*/, const StringVector& tokens) { std::string functionName; diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp index fad3061aa..4c4dbb2ec 100644 --- a/kit/ChildSession.hpp +++ b/kit/ChildSession.hpp @@ -291,6 +291,7 @@ private: bool removeTextContext(const char* /*buffer*/, int /*length*/, const StringVector& tokens); void rememberEventsForInactiveUser(const int type, const std::string& payload); + bool formFieldEvent(const char* buffer, int length, const StringVector& tokens); virtual void disconnect() override; virtual bool _handleInput(const char* buffer, int length) override; diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js index 4cd837ffe..33c6b561c 100644 --- a/loleaflet/src/layer/FormFieldButtonLayer.js +++ b/loleaflet/src/layer/FormFieldButtonLayer.js @@ -15,6 +15,7 @@ L.FormFieldButton = L.Layer.extend({ }, onAdd: function (map) { + this.map = map; this._clearButton(); this._buildFormButton(map); }, @@ -102,7 +103,10 @@ L.FormFieldButton = L.Layer.extend({ for (var i = 0; i < itemList.length; ++i) { var option = L.DomUtil.create('div', 'drop-down-field-list-item', dropDownList); option.innerHTML = itemList[i]; + option.addEventListener('click', this._onListItemSelect); + option.map = this.map; + // Stop propagation to the main document option.addEventListener('mouseup', function(event) {event.stopPropagation();}); option.addEventListener('mousedown', function(event) {event.stopPropagation();}); @@ -116,17 +120,27 @@ L.FormFieldButton = L.Layer.extend({ this._clearButton(); }, - _onClickDropDown: function() { + _onClickDropDown: function(event) { $('.drop-down-field-list').show(); + event.stopPropagation(); }, _onListItemSelect: function(event) { + $('.drop-down-field-list').hide(); $('.drop-down-field-list-item.selected').removeClass('selected'); event.target.classList.add('selected'); - // TODO: send back - $('.drop-down-field-list').hide(); + event.stopPropagation(); - console.warn(event.target.textContent); + + // Find item index + var index = $(event.target).index(); + + var message = 'formfieldevent {\"type\": \"drop-down\",' + + '\"cmd\": \"selected\",' + + '\"data\":\"' + index.toString() + '\"}'; + + // Apply selection in the document. + this.map._socket.sendMessage(message); }, _clearButton: function() { diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index 6deb6808f..ded1b572c 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -728,7 +728,6 @@ L.TileLayer = L.GridLayer.extend({ } else if (textMsg.startsWith('formfieldbutton:')) { this._onFormFieldButtonMsg(textMsg); - console.error(textMsg); } }, diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index 956a4ba7e..41d9bbcd0 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -439,7 +439,8 @@ bool ClientSession::_handleInput(const char *buffer, int length) tokens[0] != "resizewindow" && tokens[0] != "removetextcontext" && tokens[0] != "dialogevent" && - tokens[0] != "completefunction") + tokens[0] != "completefunction" && + tokens[0] != "formfieldevent") { LOG_ERR("Session [" << getId() << "] got unknown command [" << tokens[0] << "]."); sendTextFrameAndLogError("error: cmd=" + tokens[0] + " kind=unknown"); @@ -721,6 +722,10 @@ bool ClientSession::_handleInput(const char *buffer, int length) { return forwardToChild(std::string(buffer, length), docBroker); } + else if (tokens.equals(0, "formfieldevent")) + { + return forwardToChild(firstLine, docBroker); + } else { if (tokens.equals(0, "key")) commit dc9e66f4bb3a7fc6430226e0e6dc03c506b84bd7 Author: Tamás Zolnai <[email protected]> AuthorDate: Tue May 5 17:37:26 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:08 2020 +0200 MSForms: restructure form field button rendering code. To make it more readable. Change-Id: Icfb179a5edfc65fe2dcaaebcc86c970e5d3b83b1 diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js index 14ca0f401..4cd837ffe 100644 --- a/loleaflet/src/layer/FormFieldButtonLayer.js +++ b/loleaflet/src/layer/FormFieldButtonLayer.js @@ -10,73 +10,103 @@ L.FormFieldButton = L.Layer.extend({ }, initialize: function (data) { - if (data.type === 'drop-down') { - var strTwips = data.textArea.match(/\d+/g); - var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1])); - var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3])); - var bottomRightTwips = topLeftTwips.add(offset); - this._buttonAreaTwips = [topLeftTwips, bottomRightTwips]; - this._buttonData = data; - } + console.assert(data.type === 'drop-down'); + this._buttonData = data; }, onAdd: function (map) { this._clearButton(); - this._buildFormButton(map); }, _buildFormButton: function(map) { - this._container = L.DomUtil.create('div', 'form-field-button-container', this.getPane('formfieldPane')); + // We use a container to have the frame and the drop-down button the same height + var container = L.DomUtil.create('div', 'form-field-button-container', this.getPane('formfieldPane')); - // Create a frame around the text area - this._frame = L.DomUtil.create('div', 'form-field-frame', this._container); + // Calculate button area in layer point unot + var buttonArea = this._calculateButtonArea(map); + + // Build the frame around the text area + var frameData = this._buildButtonFrame(container, buttonArea); + var framePos = frameData[0]; + var frameWidth = frameData[1]; + var frameHeight = frameData[2]; + + // We set the shared height here. + container.style.height = frameHeight + 'px'; + + // Add a drop down button to open the list + this._buildDropDownButton(container, framePos, frameWidth); + + // Build list of items opened by clicking on the drop down button + this._buildDropDownList(framePos, frameWidth, frameHeight); + }, + + _calculateButtonArea: function(map) { + // First get the data from the message in twips. + var strTwips = this._buttonData.textArea.match(/\d+/g); + var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1])); + var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3])); + var bottomRightTwips = topLeftTwips.add(offset); + var buttonAreaTwips = [topLeftTwips, bottomRightTwips]; + + // Then convert to unit which can be used on the layer. var buttonAreaLatLng = new L.LatLngBounds( - map._docLayer._twipsToLatLng(this._buttonAreaTwips[0], this._map.getZoom()), - map._docLayer._twipsToLatLng(this._buttonAreaTwips[1], this._map.getZoom())); + map._docLayer._twipsToLatLng(buttonAreaTwips[0], this._map.getZoom()), + map._docLayer._twipsToLatLng(buttonAreaTwips[1], this._map.getZoom())); var buttonAreaLayer = new L.Bounds( - this._map.latLngToLayerPoint(buttonAreaLatLng.getNorthWest()), - this._map.latLngToLayerPoint(buttonAreaLatLng.getSouthEast())); + map.latLngToLayerPoint(buttonAreaLatLng.getNorthWest()), + map.latLngToLayerPoint(buttonAreaLatLng.getSouthEast())); + + return buttonAreaLayer; + }, + + _buildButtonFrame: function(container, buttonArea) { + // Create a frame around the text area + var buttonFrame = L.DomUtil.create('div', 'form-field-frame', container); // Use a small padding between the text and the frame var extraPadding = 2; - var size = buttonAreaLayer.getSize(); - this.frameWidth = size.x + 1.5 * extraPadding; - this.frameHeight = size.y + 1.5 * extraPadding; - this._frame.style.width = this.frameWidth + 'px'; - this._container.style.height = this.frameHeight + 'px'; + var size = buttonArea.getSize(); + var frameWidth = size.x + 1.5 * extraPadding; + var frameHeight = size.y + 1.5 * extraPadding; + buttonFrame.style.width = frameWidth + 'px'; - this.framePos = new L.Point(buttonAreaLayer.min.x - extraPadding, buttonAreaLayer.min.y - extraPadding); - L.DomUtil.setPosition(this._frame, this.framePos); + var framePos = new L.Point(buttonArea.min.x - extraPadding, buttonArea.min.y - extraPadding); + L.DomUtil.setPosition(buttonFrame, framePos); - // Add a drop down button to open the list - this._button = L.DomUtil.create('button', 'form-field-button', this._container); - var buttonPos = new L.Point(buttonAreaLayer.max.x + extraPadding, buttonAreaLayer.min.y - extraPadding); - L.DomUtil.setPosition(this._button, buttonPos); - this._button.style.width = this._container.style.height; + return [framePos, frameWidth, frameHeight]; + }, + + _buildDropDownButton: function(container, framePos, frameWidth) { + var button = L.DomUtil.create('button', 'form-field-button', container); + var buttonPos = new L.Point(framePos.x + frameWidth, framePos.y); + L.DomUtil.setPosition(button, buttonPos); + button.style.width = container.style.height; - var image = L.DomUtil.create('img', 'form-field-button-image', this._button); + var image = L.DomUtil.create('img', 'form-field-button-image', button); image.src = 'images/unfold.svg'; - this._button.addEventListener('click', this._onClickDropDown); + button.addEventListener('click', this._onClickDropDown); + }, - // Build list of items - this._dropDownList = L.DomUtil.create('div', 'drop-down-field-list', this.getPane('formfieldPane')); + _buildDropDownList: function(framePos, frameWidth, frameHeight) { + var dropDownList = L.DomUtil.create('div', 'drop-down-field-list', this.getPane('formfieldPane')); $('.drop-down-field-list').hide(); - var listPos = this.framePos; - L.DomUtil.setPosition(this._dropDownList, listPos); - this._dropDownList.style.minWidth = (this.frameWidth + this.frameHeight) + 'px'; + L.DomUtil.setPosition(dropDownList, framePos); + dropDownList.style.minWidth = (frameWidth + frameHeight) + 'px'; var itemList = this._buttonData.params.items; var selected = parseInt(this._buttonData.params.selected); for (var i = 0; i < itemList.length; ++i) { - var option = L.DomUtil.create('div', 'drop-down-field-list-item', this._dropDownList); + var option = L.DomUtil.create('div', 'drop-down-field-list-item', dropDownList); option.innerHTML = itemList[i]; option.addEventListener('click', this._onListItemSelect); // Stop propagation to the main document option.addEventListener('mouseup', function(event) {event.stopPropagation();}); option.addEventListener('mousedown', function(event) {event.stopPropagation();}); + if (i === selected) option.classList.add('selected'); } @@ -101,8 +131,6 @@ L.FormFieldButton = L.Layer.extend({ _clearButton: function() { this.getPane('formfieldPane').innerHTML = ''; - this._frame = undefined; - this._button = undefined; } }); commit 6640ba5cef23ecf911b0058df34fbec155ab5b29 Author: Tamás Zolnai <[email protected]> AuthorDate: Tue May 5 15:20:22 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:08 2020 +0200 MSForms: use the actual item list for drop down field. Change-Id: Ib6021cf5d2a0c25bcd04f44771a33b3e3cea53fb diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js index cfd91a605..14ca0f401 100644 --- a/loleaflet/src/layer/FormFieldButtonLayer.js +++ b/loleaflet/src/layer/FormFieldButtonLayer.js @@ -68,17 +68,16 @@ L.FormFieldButton = L.Layer.extend({ L.DomUtil.setPosition(this._dropDownList, listPos); this._dropDownList.style.minWidth = (this.frameWidth + this.frameHeight) + 'px'; - // TODO: use the actual list here - var stringList = ['text1', 'text2', 'string', 'selected_item']; - var selected = 'selected_item'; - for (var i = 0; i < stringList.length; ++i) { + var itemList = this._buttonData.params.items; + var selected = parseInt(this._buttonData.params.selected); + for (var i = 0; i < itemList.length; ++i) { var option = L.DomUtil.create('div', 'drop-down-field-list-item', this._dropDownList); - option.innerHTML = stringList[i]; + option.innerHTML = itemList[i]; option.addEventListener('click', this._onListItemSelect); // Stop propagation to the main document option.addEventListener('mouseup', function(event) {event.stopPropagation();}); option.addEventListener('mousedown', function(event) {event.stopPropagation();}); - if (stringList[i] === selected) + if (i === selected) option.classList.add('selected'); } }, commit 3bce2d45ab344b5c7e3a20ac79ebd42620a95448 Author: Tamás Zolnai <[email protected]> AuthorDate: Fri May 1 17:57:38 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:08 2020 +0200 MSForms: build drop down list for drop-down field. Change-Id: I42a68ebf8b0201d97779f2bfc43a8dabbad9e1c0 diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css index 7f874c222..8639f504d 100644 --- a/loleaflet/css/loleaflet.css +++ b/loleaflet/css/loleaflet.css @@ -544,9 +544,22 @@ body { } .form-field-button:hover, .form-field-button:focus { - background: #DDDDDD; + background: #DDDDDD; } .form-field-button-image { margin: 3px; } + +.drop-down-field-list { + position: absolute; + border: 1px solid; +} + +.drop-down-field-list-item { + width: 100%; +} + +.drop-down-field-list-item.selected { + background: #99CCFF; +} diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js index 169f030e0..cfd91a605 100644 --- a/loleaflet/src/layer/FormFieldButtonLayer.js +++ b/loleaflet/src/layer/FormFieldButtonLayer.js @@ -2,7 +2,7 @@ /* * L.FormFieldButton is used to interact with text based form fields. */ - +/* global $ */ L.FormFieldButton = L.Layer.extend({ options: { @@ -16,6 +16,7 @@ L.FormFieldButton = L.Layer.extend({ var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3])); var bottomRightTwips = topLeftTwips.add(offset); this._buttonAreaTwips = [topLeftTwips, bottomRightTwips]; + this._buttonData = data; } }, @@ -26,8 +27,10 @@ L.FormFieldButton = L.Layer.extend({ }, _buildFormButton: function(map) { + this._container = L.DomUtil.create('div', 'form-field-button-container', this.getPane('formfieldPane')); + // Create a frame around the text area - this._frame = L.DomUtil.create('div', 'form-field-frame', this.getPane('formfieldPane')); + this._frame = L.DomUtil.create('div', 'form-field-frame', this._container); var buttonAreaLatLng = new L.LatLngBounds( map._docLayer._twipsToLatLng(this._buttonAreaTwips[0], this._map.getZoom()), map._docLayer._twipsToLatLng(this._buttonAreaTwips[1], this._map.getZoom())); @@ -39,37 +42,68 @@ L.FormFieldButton = L.Layer.extend({ // Use a small padding between the text and the frame var extraPadding = 2; var size = buttonAreaLayer.getSize(); - this._frame.style.width = (size.x + 1.5 * extraPadding) + 'px'; + this.frameWidth = size.x + 1.5 * extraPadding; + this.frameHeight = size.y + 1.5 * extraPadding; + this._frame.style.width = this.frameWidth + 'px'; + this._container.style.height = this.frameHeight + 'px'; - this.getPane('formfieldPane').style.height = (size.y + 1.5 * extraPadding) + 'px'; - - var framePos = new L.Point(buttonAreaLayer.min.x - extraPadding, buttonAreaLayer.min.y - extraPadding); - L.DomUtil.setPosition(this._frame, framePos); + this.framePos = new L.Point(buttonAreaLayer.min.x - extraPadding, buttonAreaLayer.min.y - extraPadding); + L.DomUtil.setPosition(this._frame, this.framePos); // Add a drop down button to open the list - this._button = L.DomUtil.create('button', 'form-field-button', this.getPane('formfieldPane')); + this._button = L.DomUtil.create('button', 'form-field-button', this._container); var buttonPos = new L.Point(buttonAreaLayer.max.x + extraPadding, buttonAreaLayer.min.y - extraPadding); L.DomUtil.setPosition(this._button, buttonPos); - this._button.style.width = this.getPane('formfieldPane').style.height; + this._button.style.width = this._container.style.height; var image = L.DomUtil.create('img', 'form-field-button-image', this._button); image.src = 'images/unfold.svg'; + + this._button.addEventListener('click', this._onClickDropDown); + + // Build list of items + this._dropDownList = L.DomUtil.create('div', 'drop-down-field-list', this.getPane('formfieldPane')); + $('.drop-down-field-list').hide(); + var listPos = this.framePos; + L.DomUtil.setPosition(this._dropDownList, listPos); + this._dropDownList.style.minWidth = (this.frameWidth + this.frameHeight) + 'px'; + + // TODO: use the actual list here + var stringList = ['text1', 'text2', 'string', 'selected_item']; + var selected = 'selected_item'; + for (var i = 0; i < stringList.length; ++i) { + var option = L.DomUtil.create('div', 'drop-down-field-list-item', this._dropDownList); + option.innerHTML = stringList[i]; + option.addEventListener('click', this._onListItemSelect); + // Stop propagation to the main document + option.addEventListener('mouseup', function(event) {event.stopPropagation();}); + option.addEventListener('mousedown', function(event) {event.stopPropagation();}); + if (stringList[i] === selected) + option.classList.add('selected'); + } }, onRemove: function () { this._clearButton(); }, + _onClickDropDown: function() { + $('.drop-down-field-list').show(); + }, + + _onListItemSelect: function(event) { + $('.drop-down-field-list-item.selected').removeClass('selected'); + event.target.classList.add('selected'); + // TODO: send back + $('.drop-down-field-list').hide(); + event.stopPropagation(); + console.warn(event.target.textContent); + }, + _clearButton: function() { this.getPane('formfieldPane').innerHTML = ''; - if (this._frame) { - L.DomUtil.remove(this._frame); - this._frame = undefined; - } - if (this._button) { - L.DomUtil.remove(this._button); - this._button = undefined; - } + this._frame = undefined; + this._button = undefined; } }); commit 87b862a4e2fafe2c420f672af835929d588757a2 Author: Tamás Zolnai <[email protected]> AuthorDate: Thu Apr 30 14:34:09 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:08 2020 +0200 MSForms: styling form field button. Change-Id: I4bbcc16aa8afb0fa7e8e84d34e1f18086f0b8615 diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css index 834579ade..7f874c222 100644 --- a/loleaflet/css/loleaflet.css +++ b/loleaflet/css/loleaflet.css @@ -528,7 +528,25 @@ body { -o-user-select: none; } -.drop-down-button { - background: #FF0000; +.form-field-frame { + border: 1px solid; position: absolute; + height: 100%; +} + +.form-field-button { + background: #FFFFFF; + position: absolute; + border: 1px solid; + height: 100%; + box-sizing: content-box; + padding: 0px; +} + +.form-field-button:hover, .form-field-button:focus { + background: #DDDDDD; +} + +.form-field-button-image { + margin: 3px; } diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js index bbbb0d721..169f030e0 100644 --- a/loleaflet/src/layer/FormFieldButtonLayer.js +++ b/loleaflet/src/layer/FormFieldButtonLayer.js @@ -20,11 +20,14 @@ L.FormFieldButton = L.Layer.extend({ }, onAdd: function (map) { - if (this._button) { - L.DomUtil.remove(this._button); - } + this._clearButton(); - this._button = L.DomUtil.create('div', 'drop-down-button', this.getPane('formfieldPane')); + this._buildFormButton(map); + }, + + _buildFormButton: function(map) { + // Create a frame around the text area + this._frame = L.DomUtil.create('div', 'form-field-frame', this.getPane('formfieldPane')); var buttonAreaLatLng = new L.LatLngBounds( map._docLayer._twipsToLatLng(this._buttonAreaTwips[0], this._map.getZoom()), map._docLayer._twipsToLatLng(this._buttonAreaTwips[1], this._map.getZoom())); @@ -33,17 +36,40 @@ L.FormFieldButton = L.Layer.extend({ this._map.latLngToLayerPoint(buttonAreaLatLng.getNorthWest()), this._map.latLngToLayerPoint(buttonAreaLatLng.getSouthEast())); + // Use a small padding between the text and the frame + var extraPadding = 2; var size = buttonAreaLayer.getSize(); - this._button.style.width = size.x + 'px'; - this._button.style.height = size.y + 'px'; + this._frame.style.width = (size.x + 1.5 * extraPadding) + 'px'; + + this.getPane('formfieldPane').style.height = (size.y + 1.5 * extraPadding) + 'px'; + + var framePos = new L.Point(buttonAreaLayer.min.x - extraPadding, buttonAreaLayer.min.y - extraPadding); + L.DomUtil.setPosition(this._frame, framePos); - var pos = buttonAreaLayer.min; - L.DomUtil.setPosition(this._button, pos); + // Add a drop down button to open the list + this._button = L.DomUtil.create('button', 'form-field-button', this.getPane('formfieldPane')); + var buttonPos = new L.Point(buttonAreaLayer.max.x + extraPadding, buttonAreaLayer.min.y - extraPadding); + L.DomUtil.setPosition(this._button, buttonPos); + this._button.style.width = this.getPane('formfieldPane').style.height; + + var image = L.DomUtil.create('img', 'form-field-button-image', this._button); + image.src = 'images/unfold.svg'; }, onRemove: function () { - L.DomUtil.remove(this._button); - this._button = undefined; + this._clearButton(); }, + _clearButton: function() { + this.getPane('formfieldPane').innerHTML = ''; + if (this._frame) { + L.DomUtil.remove(this._frame); + this._frame = undefined; + } + if (this._button) { + L.DomUtil.remove(this._button); + this._button = undefined; + } + } + }); commit d2629961e0ca99bdebcfa0e3711abe6d5cc8cbcb Author: Tamás Zolnai <[email protected]> AuthorDate: Wed Apr 29 13:36:05 2020 +0200 Commit: Tamás Zolnai <[email protected]> CommitDate: Sat May 9 09:54:08 2020 +0200 MSForms: handle formfieldbutton message. Change-Id: I17243823d9bc0074b7fd015bca23de9399e0e26c diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp index b02e7a17a..e70cfde2e 100644 --- a/kit/ChildSession.cpp +++ b/kit/ChildSession.cpp @@ -2568,6 +2568,9 @@ void ChildSession::loKitCallback(const int type, const std::string& payload) case LOK_CALLBACK_TAB_STOP_LIST: sendTextFrame("tabstoplistupdate: " + payload); break; + case LOK_CALLBACK_FORM_FIELD_BUTTON: + sendTextFrame("formfieldbutton: " + payload); + break; #if !ENABLE_DEBUG // we want a compilation-time failure in the debug builds; but ERR in the diff --git a/loleaflet/Makefile.am b/loleaflet/Makefile.am index afbde0ec7..11945badb 100644 --- a/loleaflet/Makefile.am +++ b/loleaflet/Makefile.am @@ -230,6 +230,7 @@ LOLEAFLET_JS =\ src/layer/vector/Path.Transform.SVG.VML.js \ src/layer/vector/Canvas.js \ src/layer/vector/Path.Transform.Canvas.js \ + src/layer/FormFieldButtonLayer.js \ src/dom/DomEvent.js \ src/dom/Draggable.js \ src/map/handler/Map.Drag.js \ diff --git a/loleaflet/css/loleaflet.css b/loleaflet/css/loleaflet.css index 40b782d95..834579ade 100644 --- a/loleaflet/css/loleaflet.css +++ b/loleaflet/css/loleaflet.css @@ -527,3 +527,8 @@ body { -webkit-user-select: none; -o-user-select: none; } + +.drop-down-button { + background: #FF0000; + position: absolute; +} diff --git a/loleaflet/src/layer/FormFieldButtonLayer.js b/loleaflet/src/layer/FormFieldButtonLayer.js new file mode 100644 index 000000000..bbbb0d721 --- /dev/null +++ b/loleaflet/src/layer/FormFieldButtonLayer.js @@ -0,0 +1,49 @@ +/* -*- js-indent-level: 8 -*- */ +/* + * L.FormFieldButton is used to interact with text based form fields. + */ + +L.FormFieldButton = L.Layer.extend({ + + options: { + pane: 'formfieldPane' + }, + + initialize: function (data) { + if (data.type === 'drop-down') { + var strTwips = data.textArea.match(/\d+/g); + var topLeftTwips = new L.Point(parseInt(strTwips[0]), parseInt(strTwips[1])); + var offset = new L.Point(parseInt(strTwips[2]), parseInt(strTwips[3])); + var bottomRightTwips = topLeftTwips.add(offset); + this._buttonAreaTwips = [topLeftTwips, bottomRightTwips]; + } + }, + + onAdd: function (map) { + if (this._button) { + L.DomUtil.remove(this._button); + } + + this._button = L.DomUtil.create('div', 'drop-down-button', this.getPane('formfieldPane')); + var buttonAreaLatLng = new L.LatLngBounds( + map._docLayer._twipsToLatLng(this._buttonAreaTwips[0], this._map.getZoom()), + map._docLayer._twipsToLatLng(this._buttonAreaTwips[1], this._map.getZoom())); + + var buttonAreaLayer = new L.Bounds( + this._map.latLngToLayerPoint(buttonAreaLatLng.getNorthWest()), + this._map.latLngToLayerPoint(buttonAreaLatLng.getSouthEast())); + + var size = buttonAreaLayer.getSize(); + this._button.style.width = size.x + 'px'; + this._button.style.height = size.y + 'px'; + + var pos = buttonAreaLayer.min; + L.DomUtil.setPosition(this._button, pos); + }, + + onRemove: function () { + L.DomUtil.remove(this._button); + this._button = undefined; + }, + +}); diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js index 4b51906fa..6deb6808f 100644 --- a/loleaflet/src/layer/tile/TileLayer.js +++ b/loleaflet/src/layer/tile/TileLayer.js @@ -726,6 +726,10 @@ L.TileLayer = L.GridLayer.extend({ this._map.fire('contextchange', {context: message[1]}); } } + else if (textMsg.startsWith('formfieldbutton:')) { + this._onFormFieldButtonMsg(textMsg); + console.error(textMsg); + } }, _onTabStopListUpdate: function (textMsg) { @@ -3353,6 +3357,17 @@ L.TileLayer = L.GridLayer.extend({ this._previewInvalidations = []; }, + _onFormFieldButtonMsg: function (textMsg) { + textMsg = textMsg.substring('formfieldbutton:'.length + 1); + var json = JSON.parse(textMsg); + if (json.action === 'show') { + this._formFieldButton = new L.FormFieldButton(json); + this._map.addLayer(this._formFieldButton); + } else { + this._map.removeLayer(this._formFieldButton); + } + }, + _debugGetTimeArray: function() { return {count: 0, ms: 0, best: Number.MAX_SAFE_INTEGER, worst: 0, date: 0}; }, diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js index 982cde654..18b168a1e 100644 --- a/loleaflet/src/map/Map.js +++ b/loleaflet/src/map/Map.js @@ -1045,6 +1045,7 @@ L.Map = L.Evented.extend({ this.createPane('overlayPane'); this.createPane('markerPane'); this.createPane('popupPane'); + this.createPane('formfieldPane'); if (!this.options.markerZoomAnimation) { L.DomUtil.addClass(panes.markerPane, 'leaflet-zoom-hide'); _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
