Announcement

REXYGEN forum has been moved. This one is closed.
Head over to the new REXYGEN Community Forum at https://forum.rexygen.com.

Looking forward to meeting you there!
 

#1 2015-11-04 14:05:59

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Creating a button in Inkscape

What is the best way to create your own buttons in Inkscape?

I tried to use the existing example as a template in Inkscape but I was not very successful ... it is working but the layout/graphics are changed after uploading it to the webserver.

Last edited by scoobsalamander (2015-11-05 17:25:16)

Offline

#2 2015-11-16 21:43:26

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

Oops, I totally missed your post, sorry. Do you mean creating your own graphical objects which will work like buttons? Something like General/PushOnOff but with another face, right?

I'll post a tutorial here but I'll start with simple on/off indicator and advance to custom button afterwards, ok?

Offline

#3 2015-11-16 22:04:23

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

No problem...

Yes indeed, that's exactly what I meant.

I was trying to build a GUI for the heating control @ home but the WAF (Wife Acceptance Factor) of the original button was not high enough ;-) . Therefore I wanted to create my own buttons but all this SVG/HTML5 and javascript is more or less new to me so a little help is more than welcome.


An on/off indicator is nice to start with....(but isn't this already covered in the pool examples by using 'Group animation-color change'?)


thx

Last edited by scoobsalamander (2015-11-17 21:46:54)

Offline

#4 2015-11-17 23:27:51

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

OK, here is a step-by-step guide to create your own component in Inkscape. For starters we'll develop a simple indicator of a Boolean (logic) signal. In this case two circles, which will light up exclusively, based on a Boolean signal in the control algorithm. You could achieve the same functionality using the Group animations but our goal is to create a button, a component which is able to control. You cannot create control components using Group animations. And you cannot create active component without understanding the principles, which are best illustrated in passive components (indicators).

  1. Open a blank document in Inkscape (without the "RexHMI Config" object)

  2. Create a SVG illustration in Inkscape (two circles, as mentioned above, place them side by side)

  3. Group the whole illustration (Ctrl+G) and save the file, see BlinkLR_src.svg for reference

  4. Go to menu Extensions->RexHMI->Group Animation, tick Rotate and click OK

  5. Go to menu Extensions->RexHMI->Group Animation, untick Rotate and click OK (by this you just wrapped the object and set internal properties which are necessary for the component to work)

  6. Open the XML editor in Inkscape (Ctrl+Shift+X)

  7. Find svg:g belonging to the newly created component (id="g4007" in the case of BlinkLR_src.svg file, it is inside the "g2990" group, which is the mentioned wrapper)

  8. Drag this group to the root object svg:svg so that it resides inside the so-called root level

  9. The remains of the original object (wrapper and also layer1) should be deleted - Delete node.

  10. In the component being created change the value of the rexsvg:module ns0:module attribute from "GeneralComponent" to "BlinkLR"

  11. Find svg:path of the left circle (id="path4005")

  12. Add the rexsvg:module ns0:tag attribute manually and set it to "LeftCirc"

  13. Find svg:path of the right circle (id="path3235")

  14. Add the rexsvg:module ns0:tag attribute manually and set it to "RightCirc"

  15. Find svg:title (id="title4104"), unfold it and change "Title" to "BlinkLRindicator"

  16. Find svg:desc (id="desc4106"), unfold and enter the description of the parameters of the component:

    {
     "connections": {"STATUS": "$T_STATUS"},
     "options": {"LeftColor": "#00ff00", "RightColor": "#ff0000"},
     "metaData": {}
    }
  17. Check the code from previous step at www.jsonlint.com, the JSON syntax must be 100% valid

  18. Close the XML editor

  19. Click on the new component (select it) and go to Extensions->RexHMI->Edit Element - a configuration dialog should appear, just like in the case of standard elements from the library

  20. Save the SVG file with the new component as "BlinkLR.svg", the name must correspond with the name from step 10 (the resulting SVG file is included in the MySvgLib.zip file for reference).

  21. In the same folder create a subfolder "js"

  22. Create a file "BlinkLR.js", the name must again correspond with step 10.

  23. The .js file defines the animation and behavior of the object. It can contain something like this:

    REX.UI.SVG.BlinkLR = function (svgElem, args) {
        // Inherit from base component
        var obj = Object.create(REX.UI.SVG.Component(svgElem, args));
        // Store options for simple usage
        var $opt = obj.options || {};
    
        // Load options or default values
        var LeftColor = $opt.LeftColor || "#ff0000";
        var RightColor = $opt.RightColor || "#00ff00";
            
        // Get SVG elements for manipulation
        var lcirc = obj.getChildByTag("LeftCirc");
        var rcirc = obj.getChildByTag("RightCirc");
    
        // Add anonymous function as event listener. There are two events
        // 'read' - it is called every time when item is read
        // 'change' - called for the first time and every time item value is changed
        obj.$c.STATUS.on('change', function onChange(itm) {
            if (itm.getValue()) {
                rcirc.setAttributeNS(null, "style", "fill-opacity:1.0; fill:" + RightColor + ";");
                lcirc.setAttributeNS(null, "style", "fill-opacity:0.0; fill:" + LeftColor + ";");
            } else {
                rcirc.setAttributeNS(null, "style", "fill-opacity:0.0; fill:" + RightColor + ";");
                lcirc.setAttributeNS(null, "style", "fill-opacity:1.0; fill:" + LeftColor + ";");
            }
        });
    
        return obj;
    };

    When developing your components, use this code as a template. Respect the sytax of the file and remember that:

    • The first line must contain the correct name of the component (again step 10), thus: REX.UI.SVG.BlinkLR = function (svgElem, args)

    • Reading options must correspond with the options from step 16.

    • Searching objects in SVG (getChildByTag) must respect the naming from steps 12 and 14.

    • Function obj.$c.STATUS.on() must correspond with "connections" from step 16.

    • Function itm.getValue() returns the value of the signal in the REX control algorithm, just like you can see it e.g. in RexView - this value can be used for arbitrary animation.

    • The component is almost ready. You should have something like the MySvgLib.zip file contains.

  24. To include the component in the exported HMI, you have to move the folder with the component and the JavaScript code to the C:\ProgramData\REX Controls\RexHMI\libs folder (name the folder e.g. MySvgLib).

  25. Now create the HMI in Inkscape just like you would with the standard components and export the HMI. Use testHMI.zip to test the component I have developed.

  26. Repeat the procedure for indicators of your taste. Always put the SVG file with the component to the MySvgLib folder as well as the corresponding .js file to the js subfolder.

  27. Explore our components for inspiration.

BEWARE! - Your user libraries might get deleted when uninstalling/updating the RexHMI extension for Inkscape. Always have a backup!

Download links:

Hope this helps. Let me know if it works for you. Later we'll advance to active (control) components.

Last edited by jaroslav_sobota (2015-11-23 11:26:49)

Offline

#5 2015-11-19 09:47:05

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

First of all, a big thank you for another well explained tutorial.
I'll give it a try today and let you know how it went....

Offline

#6 2015-11-20 12:39:01

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

first attempt didn't work....

I noticed that I do not have an attribute called rexsvg:module. In my Inkscape object it is called ns0:module, did I missed something?

Here an the XML of the example with the rexsvg:tag......

With rexsvg:tag


Here the XML of my own created object but this one doesn't get the same tags as the example.


Without rexsvg:tag

Last edited by scoobsalamander (2015-11-21 20:29:06)

Offline

#7 2015-11-23 01:46:09

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

Sorry, my fault. Use ns0:module and ns0:tag instead of rexsvg:module and rexsvg:tag. I have updated my previous post and the source files.

Offline

#8 2015-11-23 09:24:32

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

I had to copy the javascript from 'BlinkLR.js' into the existing file 'rex-ui-svg-general.js' to make it work. (adding the reference in the HTML file is also an option I guess but using the 'rex-ui-svg-general.js' file seems to be the standard way, correct...?)

The ns0:tags for the LeftCirc and RightCirc are also to be created manually because they are not automatically added during the wrapping process.

...but it is working now and I slowly start to understand how (more or less....)

ready for the next step.... ;-)

Offline

#9 2015-11-23 11:25:31

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

There is no need to modify the original libraries. As stated in step 24, create e.g. MySvgLib folder inside
C:\ProgramData\REX Controls\RexHMI\libs
RexHMI-libs.png

Put the BlinkLR.svg file into this folder and the BlinkLR.js file inside a subfolder called js.
RexHMI-MySvgLib.png

And yes, the ns0:tag attributes must be added, as stated in steps 12 and 14. I have added manually into my original post.

Let me know if it works.

Offline

#10 2015-11-23 11:30:41

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

A general overview is that you create some SVG graphics, you tag the parts which you want to animate and then you write a JavaScript which finds the tagged elements and modifies them based on the data read from the control algorithm. Hope this helps to improve your understanding.

Offline

#11 2015-11-23 13:17:31

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

That's what I did, but when exporting to html the reference to my own library is not automatically inserted into the index.html file.

Offline

#12 2015-11-23 13:25:52

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

Did you leave the Library Path field empty?
RexHMI-configuration.png

If yes, all libraries from C:\ProgramData\REX Controls\RexHMI\libs should be added automatically...

Offline

#13 2015-11-23 13:56:00

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

Yes, it's still empty.

(my index.html file)

Last edited by scoobsalamander (2015-11-23 14:00:55)

Offline

#14 2015-11-24 19:02:06

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

Please upload also your source SVG file if possible.

Offline

#15 2015-11-24 20:20:56

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

BlinkLR.zip

(don't mind my circles, they look like rectangles..... smile )

Offline

#16 2015-11-24 20:33:55

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

Everything is working fine, the only thing is that I have to include the library manually inside index.html

Offline

#17 2015-11-24 23:29:47

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

I can confirm your component is perfectly valid. However, I'm not able to replicate your bug...

Even if the generated index.html does not contain a link to the BlinkLR.js file, is the BlinkLR.js file included in the exported HMI/js folder?

Can you please try exporting the HMI with the following settings?
MySvgLib-export.png
With this settings, is the link to BlinkLR.js present in the index.html file? Can you please upload the whole exported HMI?

Thanks!

PS Your rectangular circles are beautiful wink

Offline

#18 2015-11-25 11:46:08

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

I exported with the same settings as you described above but it looks like that the paths for the libraries are not exported. It's only when I leave the field empty that the index.html file contains the path to the libraries....

exported HMI with path to libraries

exported HMI with empty field (no paths to libraries)

Offline

#19 2015-11-26 01:30:09

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

The export works as it should, except the fact that your library is ignored for some reason. With empty Library Path, all libraries from C:\ProgramData\REX Controls\RexHMI\libs are exported:

<script type="text/javascript" src="js/rex-ui-svg-general.js"></script>
<script type="text/javascript" src="js/rex-ui-svg-home.js"></script>
<script type="text/javascript" src="js/rex-ui-svg-hvac.js"></script>

When libraries are listed in Library Path, only the selected ones are included:

<script type="text/javascript" src="js/rex-ui-svg-general.js"></script>

In both cases, the line with your library should be included:

<script type="text/javascript" src="js/BlinkLR.js"></script>

However, it is ignored for some unknown reason and I do want to find out why. Thanks for your cooperation so far.

  • What Windows are you using?

  • What version of RexHMI extension are you using (Extensions->RexHMI->Version Info)?

  • Can you try running Inkscape as Administrator and do both exports once again?

  • Can you please zip the whole folder C:\ProgramData\REX Controls\RexHMI\libs as you have it at the moment and upload it here?

Offline

#20 2015-11-26 09:08:07

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

Yep, exactly. I can work around this issue but it would be nice that I can use my own libraries and that they are implemented automatically. (no rush as my own libraries do not exist yet... smile )


jaroslav_sobota wrote:
  • What Windows are you using? Windows 10 Pro

  • What version of RexHMI extension are you using (Extensions->RexHMI->Version Info)?version 0.7.185

  • Can you try running Inkscape as Administrator and do both exports once again? see below

  • Can you please zip the whole folder C:\ProgramData\REX Controls\RexHMI\libs as you have it at the moment and upload it here? Link to REX-Controls.zip

exported files as administrator :

exported HMI with path to libraries

exported HMI with empty field (no paths to libraries)


I think I did the conversion to Windows 10 when REXControl was already installed, maybe I should try to remove the complete installation and start all over with a fresh clean installation?

(FYI : I was not able to copy objects out of the library into my project when Inkscape was started as administrator. So I prepared a project as normal user and exported as administrator.)

Last edited by scoobsalamander (2015-11-26 09:08:42)

Offline

#21 2015-11-26 10:00:05

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

Thanks, now I understand. The problem is that you have your custom component in C:\ProgramData\REX Controls\RexHMI\libs\MySvgLib\BlinkLR. You have to move it one level up to the folder C:\ProgramData\REX Controls\RexHMI\libs\MySvgLib which is shown here:
RexHMI-MySvgLib.png

Hope this is the problem. If you placed the component in the subfolder by mistake, then no problem. If some part of the tutorial convinced you to put the files in the subfolder, please let me know which one so I can make it more clear for other users.

Offline

#22 2015-11-26 10:20:36

scoobsalamander
Member
From: Belgium - Hulshout
Registered: 2015-10-27
Posts: 217

Re: Creating a button in Inkscape

....feel stupid again....sorry for wasting your time.

It's there now....thanks for the help!!

2015-11-26-10_17_23-Photos.png

Last edited by scoobsalamander (2015-11-26 11:12:18)

Offline

#23 2015-12-28 02:12:45

jaroslav_sobota
Administrator
Registered: 2015-10-27
Posts: 535

Re: Creating a button in Inkscape

Here is the second part of the tutorial. We'll create a simple button to control a Boolean signal and display its status. The best part is that you can create a button which is completely yours so it can match your style.

  1. Open a blank document in Inkscape (without the "RexHMI Config" object).

  2. Create an SVG illustration in Inkscape (a rectangle and a text, the text overlays the rectangle and stands for the label of the button).

  3. Group the whole illustration (Ctrl+G) and save the file, see MyButton_src.svg.

  4. Extensions->RexHMI->Group Animation, tick Rotate and click OK.

  5. Extensions->RexHMI->Group Animation, untick Rotate and click OK (by this you just wrapped the object and set internal properties which are necessary for the component to work).

  6. Open the XML editor in Inkscape (Ctrl+Shift+X).

  7. Find svg:g belonging to the newly created component (id="g2993" in the case of MyButton_src.svg file, it is inside another group, which is the mentioned wrapper).

  8. Drag this group to the root object svg:svg so that it resides inside the so-called root level.

  9. The remains of the original object (wrapper and also layer1) should be deleted - Delete node.

  10. In the component being created change the value of the ns0:module attribute from "GeneralComponent" to "MyButton".

  11. Find svg:rect (the rectangle, id="rect2985")..

  12. Add the ns0:tag attribute manually and set it to "ButtonRect".

  13. Find svg:text (the text object, id="text2987"). Alternatively it also could be an svg:tspan object.

  14. Add the ns0:tag attribute manually and set it to "Label".

  15. Find svg:title (id="title3000"), unfold it and change "Title" to "ButtonElement".

  16. Find svg:desc (id="desc3002"), unfold and enter the description of the parameters of the component:

    {
    "connections":{"RSTATUS":"$T_RSTATUS","WSTATUS":"$T_WSTATUS"},
    "metaData":{},
    "options":{"OffColor":"#ff8000","OnColor":"#008000","LabelOffColor":"#ffffff","LabelOnColor":"#ffffff","LabelOff":"OFF","LabelOn":"ON"}
    }
  17. Check the code from previous step at www.jsonlint.com, the JSON syntax must be 100% valid.

  18. Close the XML editor.

  19. Click on the new component (select it) and go to Extensions->RexHMI->Edit Element - a configuration dialog should appear, just like in the case of standard elements from the library.

  20. Save the SVG file with the new component as "MyButton.svg", the name must correspond with the name from step 10 (the resulting SVG file is included in the MySvgLib.zip file for reference).

  21. In the same folder create a subfolder "js".

  22. Inside the "js" subfolder, create a file "MyButton.js", the name must correspond with step 10 again.

  23. The .js file defines the animation and behavior of the object. It can contain something like this:

    REX.UI.SVG.MyButton = function (svgElem, args) {
        // Inherit from base component
        var obj = Object.create(REX.UI.SVG.Component(svgElem, args));
        // Store options for simple usage
        var $opt = obj.options || {};
    
        // Load options or default values
        var OffColor = $opt.OffColor || "#ff8000";
        var OnColor = $opt.OnColor || "#008000";
        var LabelOffColor = $opt.LabelOffColor || "#ffffff";
        var LabelOnColor = $opt.LabelOnColor || "#ffffff";
        var LabelOff = $opt.LabelOff || "OFF";
        var LabelOn = $opt.LabelOn || "ON";
            
        // Get SVG elements for manipulation
        var rect = obj.getChildByTag("ButtonRect");
        var label = obj.getChildByTag("Label");
    
    	// This function changes current state of the button according to the 
    	// value read from item.
    	function refreshState(itm){
    		if(itm.getValue()){ // Value is 'non zero' value
                // Use jQuery to change fill style parameter
    			$(rect).css('fill',OnColor);
          $(label).css('fill',LabelOnColor);
          label.textContent = LabelOn;
            }
    		else{ // Value is 'zero'
    			$(rect).css('fill',OffColor);
          $(label).css('fill',LabelOffColor);
          label.textContent = LabelOff;
    		}
    	}
    	
    	// Every writable component should be synchronized with current state of the 
    	// control system. Variable 'referesh_from' stores the value of readable connection (fallback to the writable connection)
    	var refresh_from = obj.$c.RSTATUS || obj.$c.WSTATUS;
        refresh_from.on('change', refreshState);
    
    // Create jQuery object from the button (parent of the rectangle element), then add new listener for 'mousedown' event
    	$(rect).parent().on('mousedown',function(evt){
    		// Prevent propagation of the event to the children of the target element
    		evt.preventDefault();
    		// Disable refreshing of the value to allow user to change input 
    		// (e.q. Number in input, position of the slider, etc.)
    		refresh_from.disableRefresh = true;		
    		
    		// Process the parameters of the event.
    		if(evt.which === 1){ // Left mouse button
    			// Write some value to the writable connection 
    		    // Write number '1' immediately 			
    			obj.$c.WSTATUS.setValue(1,true);
    		}				
    		// Enable refresh again
    		refresh_from.disableRefresh = false;		
    	});
      
      $(rect).parent().on('mouseup',function(evt){
    		// Prevent propagation of the event to the children of the target element
    		evt.preventDefault();
    		// Disable refreshing of the value to allow user to change input 
    		// (e.q. Number in input, position of the slider, etc.)
    		refresh_from.disableRefresh = true;		
    		
    		// Process the parameters of the event.
    		if(evt.which === 1){ // Left mouse button
    			// Write some value to the writable connection 
    		    // Write number '0' immediately 			
    			obj.$c.WSTATUS.setValue(0,true);
    		}				
    		// Enable refresh again
    		refresh_from.disableRefresh = false;		
    	});
    
        return obj;
    };

    When developing your components, use this code as a template. Respect the sytax of the file and remember that:

    • The first line must contain the correct name of the component (again step 10), thus: REX.UI.SVG.MyButton = function (svgElem, args)

    • Loading options must correspond with the options from step 16.

    • Searching objects in SVG (getChildByTag) must respect the naming from steps 12 and 14.

    • obj.$c.RSTATUS and obj.$c.WSTATUS must correspond with "connections" from step 16.

    • Function itm.getValue() returns the value of the signal in the REX control algorithm, just like you can see it e.g. in RexView - this value can be used for arbitrary animation.

  24. The component is almost ready. You should have something like the MySvgLib-button.zip file contains.

  25. To include the component in the exported HMI, you have to move the folder with the component and the JavaScript code to the C:\ProgramData\REX Controls\RexHMI\libs folder (name the folder e.g. MySvgLib).

  26. Now create the HMI in Inkscape just like you would with the standard components and export the HMI. Use testHMI-button.zip to test the component I have developed.

  27. Repeat the procedure for additional buttons of your taste. Always put the SVG file with the component to the MySvgLib folder as well as the corresponding .js file to the js subfolder.

  28. Explore our components for inspiration.


BEWARE! - Your user libraries might get deleted when uninstalling/updating the RexHMI extension for Inkscape. Always have a backup!

Download links:

Hope this helps. Let me know if it works for you.

Offline

#24 2017-02-28 09:51:13

stepan.ozana
Member
Registered: 2016-10-06
Posts: 34

Re: Creating a button in Inkscape

Hi, this does not work for me:
var obj = Object.create(REX.UI.SVG.Component(svgElem, args));
Instead, I had to use this:
var obj = new REX.UI.SVG.Component(svgElem,args);

Offline

#25 2017-02-28 14:37:43

osevera
REX developer
Registered: 2015-10-27
Posts: 13
Website

Re: Creating a button in Inkscape

Yes that is correct for the new version of the components, REX version > 2.50.1

Offline

Board footer

Powered by FluxBB