How to get the size of an upcoming widget in a plugin declaration?

52 views
Skip to first unread message

stefano franchi

unread,
Feb 13, 2019, 2:29:23 PM2/13/19
to TiddlyWikiDev
The library I am adapting for a TW plugin builds a complex SVG structure inside a div and the basic parameter it uses to compute the layout is the width of the parent container it is inserted in, which it gets with:

parentWidth = parseFloat(getComputedStyle(container.parentElement).width)

This of course does not work in the plugin's render function, where I instantiate the new div, because there is no parent yet and in fact there is no widget yet Is there any way to get the width of the widget to be as it is about to be inserted in the story river (or, even better in general)??Is it provided by the theme and is it accessible?

Thanks for the help,

S.

__________________________________________________
Stefano Franchi

stefano...@gmail.com
http://stefano.cleinias.org

Simon Huber

unread,
Feb 13, 2019, 4:56:29 PM2/13/19
to TiddlyWikiDev
Hi stefano,

from within the render method it should be possible to access the parent if I recall correctly,

could you post a bit of code to work with?

stefano franchi

unread,
Feb 13, 2019, 5:43:03 PM2/13/19
to TiddlyWikiDev
On Wed, Feb 13, 2019 at 3:56 PM Simon Huber <hypnotize...@gmail.com> wrote:
Hi stefano,

from within the render method it should be possible to access the parent if I recall correctly,

could you post a bit of code to work with?


Well, it is all very rudimentary still, but the idea is the following:
In my plugin I import the library and instantiate it, then create the div to pass to it. Then I call the constructor of my library's main object with the div as its argument:
''''
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var    Widget = require("$:/core/modules/widgets/widget.js").widget;

//The library I use, besogo:
var     besogoPlayer = require("$:/plugins/cleinias/SgfEditor/besogo").besogo

var GoGameWidget = function(parseTreeNode,options) {
    this.initialise(parseTreeNode,options);
};

GoGameWidget.prototype = new Widget();
   
/*
Render this widget into the DOM
*/
GoGameWidget.prototype.render = function(parent,nextSibling) {
    this.parentDomNode = parent;
    this.computeAttributes();
    var div = this.document.createElement("div");
    this.goGamePlayer = besogoPlayer;
//
// This is where I would need to know the width of the future widget, so I can pass it to the create function
//   this.goGamePlayer.create(div);
    var twSgfFile = this.getAttribute("sgfFile");
    parent.insertBefore(div,nextSibling);
    this.domNodes.push(div);
};
''''
he goGamePlayer.create(div) function is the call to the besogo library,  where all the magic happens.  Its resizer function computes a bunch of parameters. Withouth going into unnecessary details (I append the function below, relevant lines are bolded and italicized), the width of the parentElement is crucial to determining the overall width of the final widget. For now, I got around the problem in testing by hardcoding a number into the code, but it would really be nice to have a flexible and responsive solution

Cheers,

S.



''''
        resizer = function() {
            var windowHeight = window.innerHeight, // Viewport height
                // Calculated width of parent element
                parentWidth = parseFloat(getComputedStyle(container.parentElement).width),
                maxWidth = +(options.maxwidth || -1),
                orientation = options.orient || 'auto',

                portraitRatio = +(options.portratio || 200) / 100,
                landscapeRatio = +(options.landratio || 200) / 100,
                minPanelsWidth = +(options.minpanelswidth || 350),
                minPanelsHeight = +(options.minpanelsheight || 400),
                minLandscapeWidth = +(options.transwidth || 600),

                // Initial width parent
                width = (maxWidth > 0 && maxWidth < parentWidth) ? maxWidth : parentWidth,
                height; // Initial height is undefined

            // Determine orientation if 'auto' or 'view'
            if (orientation !== 'portrait' && orientation !== 'landscape') {
                if (width < minLandscapeWidth || (orientation === 'view' && width < windowHeight)) {
                    orientation = 'portrait';
                } else {
                    orientation = 'landscape';
                }
            }

            if (orientation === 'portrait') { // Portrait mode
                if (!isNaN(portraitRatio)) {
                    height = portraitRatio * width;
                    if (panelsDiv) {
                        height = (height - width < minPanelsHeight) ? width + minPanelsHeight : height;
                    }
                } // Otherwise, leave height undefined
            } else if (orientation === 'landscape') { // Landscape mode
                if (!panelsDiv) { // No panels div
                    height = width; // Square overall
                } else if (isNaN(landscapeRatio)) {
                    height = windowHeight;
                } else { // Otherwise use ratio
                    height = width / landscapeRatio;
                }

                if (panelsDiv) {
                    // Reduce height to ensure minimum width of panels div
                    height = (width < height + minPanelsWidth) ? (width - minPanelsWidth) : height;
                }
            }

            setDimensions(width, height);
            container.style.width = width + 'px';
        }
''''

 
 
The library I am adapting for a TW plugin builds a complex SVG structure inside a div and the basic parameter it uses to compute the layout is the width of the parent container it is inserted in, which it gets with:

parentWidth = parseFloat(getComputedStyle(container.parentElement).width)

This of course does not work in the plugin's render function, where I instantiate the new div, because there is no parent yet and in fact there is no widget yet Is there any way to get the width of the widget to be as it is about to be inserted in the story river (or, even better in general)??Is it provided by the theme and is it accessible?

Thanks for the help,

S.

__________________________________________________
Stefano Franchi

stefano...@gmail.com
http://stefano.cleinias.org

--
You received this message because you are subscribed to the Google Groups "TiddlyWikiDev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to tiddlywikide...@googlegroups.com.
To post to this group, send email to tiddly...@googlegroups.com.
Visit this group at https://groups.google.com/group/tiddlywikidev.
To view this discussion on the web visit https://groups.google.com/d/msgid/tiddlywikidev/dbda1e52-33d9-46c7-b401-5eb659ae8f9c%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


--

Simon Huber

unread,
Feb 13, 2019, 6:06:19 PM2/13/19
to TiddlyWikiDev


On Wed, Feb 13, 2019 at 3:56 PM Simon Huber <hypnotize...@gmail.com> wrote:
Hi stefano,

from within the render method it should be possible to access the parent if I recall correctly,

could you post a bit of code to work with?


Well, it is all very rudimentary still, but the idea is the following:
In my plugin I import the library and instantiate it, then create the div to pass to it. Then I call the constructor of my library's main object with the div as its argument:
''''
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var    Widget = require("$:/core/modules/widgets/widget.js").widget;

//The library I use, besogo:
var     besogoPlayer = require("$:/plugins/cleinias/SgfEditor/besogo").besogo

var GoGameWidget = function(parseTreeNode,options) {
    this.initialise(parseTreeNode,options);
};

GoGameWidget.prototype = new Widget();
   
/*
Render this widget into the DOM
*/
GoGameWidget.prototype.render = function(parent,nextSibling) {
    this.parentDomNode = parent;
    this.computeAttributes();
    var div = this.document.createElement("div");
    this.goGamePlayer = besogoPlayer;

Stefano, here you should be able to get dimensions of the parent domnode by

var rect = this.parentDomNode.getBoundingClientRect();

for example ...

var width = rect.width;

hope this helps

stefano franchi

unread,
Feb 13, 2019, 6:28:53 PM2/13/19
to TiddlyWikiDev
On Wed, Feb 13, 2019 at 5:06 PM Simon Huber <hypnotize...@gmail.com> wrote:


On Wed, Feb 13, 2019 at 3:56 PM Simon Huber <hypnotize...@gmail.com> wrote:
Hi stefano,

from within the render method it should be possible to access the parent if I recall correctly,

could you post a bit of code to work with?


Well, it is all very rudimentary still, but the idea is the following:
In my plugin I import the library and instantiate it, then create the div to pass to it. Then I call the constructor of my library's main object with the div as its argument:
''''
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var    Widget = require("$:/core/modules/widgets/widget.js").widget;



Stefano, here you should be able to get dimensions of the parent domnode by

var rect = this.parentDomNode.getBoundingClientRect();

for example ...

var width = rect.width;


Brilliant!
It works like a charm.


One day I will understand TW's data model and its relationship to the DOM...
But that day is still far away.

Thanks a bunch.

S.

Simon Huber

unread,
Feb 14, 2019, 6:35:44 AM2/14/19
to TiddlyWikiDev


On Wed, Feb 13, 2019 at 5:06 PM Simon Huber <hypnotize...@gmail.com> wrote:


On Wed, Feb 13, 2019 at 3:56 PM Simon Huber <hypnotize...@gmail.com> wrote:
Hi stefano,

from within the render method it should be possible to access the parent if I recall correctly,

could you post a bit of code to work with?


Well, it is all very rudimentary still, but the idea is the following:
In my plugin I import the library and instantiate it, then create the div to pass to it. Then I call the constructor of my library's main object with the div as its argument:
''''
(function(){
/*jslint node: true, browser: true */
/*global $tw: false */
"use strict";
var    Widget = require("$:/core/modules/widgets/widget.js").widget;



Stefano, here you should be able to get dimensions of the parent domnode by

var rect = this.parentDomNode.getBoundingClientRect();

for example ...

var width = rect.width;


Brilliant!
It works like a charm.


One day I will understand TW's data model and its relationship to the DOM...
But that day is still far away.


You're welcome

While trying and hacking on widgets myself I think I understand the basic model, which looks like this (anybody, correct me if I'm wrong) :

* all the widgets are layed out in a tree structure, like the DOM
* the widget tree starts with the root widget (which is accessible through $tw.rootWidget)


ROOTWIDGET

    first child widget

        child widget of first child widget

            ...

        /child widget of first child widget

    /first child widget

    sibling widget of first child widget

        ...

    /sibling widget of first child widget

/ROOTWIDGET


* if I make a widget and it's rendered, it will be somewhere within this tree
* I can access its parent widget from within my widget with this parentWidget
* I can walk up the tree until the root widget is reached (this.parentWidget.parentWidget.parentWidget ... )
* a widget that makes child widgets through this.makeChildWidgets() - most widgets call it in the execute method at the bottom I believe - has an accessible "children" array which contains its child widgets (this.parentWidget.children / this.children)
* the widgets in the tiddlywiki core follow a "rule" when they create a dom node. they push that created node to the "this.domNodes" array by this.domNodes.push(myDomNode) - so that domNode becomes accessible "from outside" by walking the widget-tree up/down


this is some basic information which I gathered by searching, reading and trying ...
not everything must be necessarily correct, anyone, just correct me where
I think we need to add some simple explanations somewhere

all the best

PMario

unread,
Feb 14, 2019, 6:55:48 AM2/14/19
to TiddlyWikiDev
Hi Stefano,


-m

stefano franchi

unread,
Feb 14, 2019, 9:47:19 AM2/14/19
to TiddlyWikiDev
Hi Simon,

thanks for your discussion of the general model behind TW's widget. Very helpful.
When I am done, I am planning to produce a write-up of what it was like  writing a plugin for TW
with no JS, front-end development background and, most importantly, no previous exposure to a one-page app.
It might be helpful to other clueless TW newbies like me who are eager to harness the tool's potential.

Cheers,

S.


Reply all
Reply to author
Forward
0 new messages