Edje examples

From Openmoko

(Difference between revisions)
Jump to: navigation, search
(catchg)
 
(27 intermediate revisions by 3 users not shown)
Line 1: Line 1:
This page is meant for developers who are totally new enlightment and wish to have the simplest examples possible. These are my first steps to getting started and are tested on the host machine.
+
This page is meant for developers who are totally new enlightenment and wish to have the simplest examples possible. These are my first steps to getting started and are tested on the host machine. This page does not describe howto setup a build environment or how to deploy on openmoko (which is just a matter of copying files).  
This page does not describe howto setup a build environment or how to deploy on openmoko (which is just a matter of copying files).  
+
 
 +
Edje user interface design is simular to designing for the web (relative, sort a box model, use of images). Graphical tools used for designing web components can almost be reused for edje (buttons, background and other graphical artifacts).
 +
 
 +
For more references, check [[Edje_examples#Further_resources|Further resources]]
  
 
== Compiling edj files ==
 
== Compiling edj files ==
Edje files are compiled with the edje_cc command, eg: edje_cc edje_file.edc  
+
Edje files are compiled with the edje_cc command, eg: edje_cc edje_file.edc
  
== Proper initialization examples ==
+
I personally use eclipse with the pydev plugins, with an extra script which compiles edc files.
Note this example show how an edje example should be initialized, the examples after this will not this to make them clear as possible. Real should still do proper initialization.
+
A external builder can be defined to execute the script on modification, following setting are used in the builder.
 +
* Location: ${workspace_loc:/edje/build_edje.sh}
 +
* Arguments: ${build_files:f}
  
<TODO>
+
Next step would be to copy the files to neo with ssh and execute them.
  
== Simple box with margin ==
+
Bash build_edje.sh:
 +
<pre>
 +
#!/bin/bash
  
Python source:box_margin.py
+
for i in $*
 +
do
 +
case $i in
 +
*.edc) cd `dirname $i`; edje_cc $i;;
 +
*);;
 +
esac
 +
done
 +
</pre>
 +
 
 +
== Edje launcher ==
 +
 
 +
Program to launch example edje files, to be used if no alternative python example is provided. e.g:
 +
 
 +
python launcher.py example.edj
 +
 
 +
Python: launcher.py
 
<pre>
 
<pre>
 
#!/usr/bin/env python
 
#!/usr/bin/env python
Line 25: Line 47:
  
 
ee = ecore.evas.SoftwareX11(w=480, h=640)
 
ee = ecore.evas.SoftwareX11(w=480, h=640)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"box_margin.edj")
+
edje_file = sys.argv[1]
 +
print "opening '%s'" % edje_file
  
 
c = edje.Edje(ee.evas,file=edje_file,group="test")
 
c = edje.Edje(ee.evas,file=edje_file,group="test")
Line 34: Line 57:
 
ecore.main_loop_begin();
 
ecore.main_loop_begin();
 
</pre>
 
</pre>
 +
 +
== Proper initialization examples ==
 +
Note this example show how an edje should be initialized, the examples after this will not do this to make them clear as possible. Real applications should still do proper initialization.
 +
 +
 +
Fullscreen mode (complete screen on openmoko): ee.fullscreen = True
 +
 +
 +
snippet:
 +
<pre>
 +
#!/usr/bin/env python
 +
 +
import ecore
 +
import ecore.evas
 +
import edje
 +
import sys
 +
import os
 +
 +
# Parse command line
 +
from optparse import OptionParser
 +
 +
def parse_geometry(option, opt, value, parser):
 +
    try:
 +
        w, h = value.split("x")
 +
        w = int(w)
 +
        h = int(h)
 +
    except Exception, e:
 +
        raise optparse.OptionValueError("Invalid format for %s" % option)
 +
    parser.values.geometry = (w, h)
 +
 +
usage = "usage: %prog [options]"
 +
op = OptionParser(usage=usage)
 +
op.add_option("-e", "--engine", type="choice",
 +
              choices=("x11", "x11-16"), default="x11-16",
 +
              help=("which display engine to use (x11, x11-16), "
 +
                    "default=%default"))
 +
op.add_option("-n", "--no-fullscreen", action="store_true",
 +
              help="do not launch in fullscreen")
 +
op.add_option("-g", "--geometry", type="string", metavar="WxH",
 +
              action="callback", callback=parse_geometry,
 +
              default=(480, 640),
 +
              help="use given window geometry")
 +
op.add_option("-f", "--fps", type="int", default=20,
 +
              help="frames per second to use, default=%default")
 +
 +
 +
# Handle options and create output window
 +
options, args = op.parse_args()
 +
if options.engine == "x11":
 +
    f = ecore.evas.SoftwareX11
 +
elif options.engine == "x11-16":
 +
    if ecore.evas.engine_type_supported_get("software_x11_16"):
 +
        f = ecore.evas.SoftwareX11_16
 +
    else:
 +
        print "warning: x11-16 is not supported, fallback to x11"
 +
        f = ecore.evas.SoftwareX11
 +
 +
w, h = options.geometry
 +
ee = f(w=w, h=h)
 +
ee.fullscreen = not options.no_fullscreen
 +
edje.frametime_set(1.0 / options.fps)
 +
</pre>
 +
 +
== Simple box with margin ==
  
 
Edje source: box_margin.edc
 
Edje source: box_margin.edc
Line 65: Line 152:
 
== Relative box position ==
 
== Relative box position ==
 
This examples show to boxes where left upper corner of one box is set at the right bottom corner of the other.
 
This examples show to boxes where left upper corner of one box is set at the right bottom corner of the other.
 
Python source: relative_box_position.py
 
<pre>
 
#!/usr/bin/env python
 
 
import evas
 
import ecore
 
import ecore.evas
 
import edje
 
import sys
 
import os
 
 
ee = ecore.evas.SoftwareX11(w=400, h=400)
 
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"relative_box_position.edj")
 
 
c = edje.Edje(ee.evas,file=edje_file,group="test")
 
c.size = ee.evas.size
 
 
c.show()
 
ee.show()
 
ecore.main_loop_begin();
 
</pre>
 
  
 
Edje source: relative_box_position.edc
 
Edje source: relative_box_position.edc
Line 134: Line 199:
  
 
</pre>
 
</pre>
 +
 
== Image ==
 
== Image ==
 
Note you also need an image 'image.png' which must be located in the same directory as image.edc.
 
Note you also need an image 'image.png' which must be located in the same directory as image.edc.
 
Python source: image.py
 
<pre>
 
#!/usr/bin/env python
 
 
import evas
 
import ecore
 
import ecore.evas
 
import edje
 
import sys
 
import os
 
 
ee = ecore.evas.SoftwareX11(w=400, h=400)
 
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"image.edj")
 
 
c = edje.Edje(ee.evas,file=edje_file,group="test")
 
c.size = ee.evas.size
 
 
c.show()
 
ee.show()
 
ecore.main_loop_begin();
 
</pre>
 
  
 
Edje source: image.edc  
 
Edje source: image.edc  
Line 194: Line 238:
 
}
 
}
 
</pre>
 
</pre>
 +
 
== Signals ==
 
== Signals ==
 
This examples makes using signal in edje very clear.
 
This examples makes using signal in edje very clear.
Line 425: Line 470:
  
 
== Video ==
 
== Video ==
 +
Including video in edje is no different than including other external content with swallow  part type and smart objects, in fact emotion is a smart object.
 +
 
Not sure howto setup gstreamer because this would be the preferred method.
 
Not sure howto setup gstreamer because this would be the preferred method.
  
Line 496: Line 543:
  
 
== Transitions ==
 
== Transitions ==
 +
* If clicked on the red box the blue will enlarge en get transparant.
 +
* If clicked on the green box tje blue box will return to it's original state.
 +
* On mouse in red box they will get highlighted (sort of), on mouse they will get dehighlighted.
  
<TODO>
+
Some observations:
 +
* It seems not to be possible to goto a intermediated index (0.5 if 0 and 1 are defined).
 +
* It seems not to be possible to handle signals depeding on state (e.g: only trigger a certain program if a part is in state x x).
 +
* It seems not to be possible to apply generic signal handlers which target there source objects (not related to transitions).
 +
 
 +
 
 +
Edje source:
 +
<pre>
 +
collections {
 +
    group {
 +
      name: "test";
 +
        parts {
 +
            part {
 +
                name: "bg";
 +
                type: RECT;
 +
                mouse_events: 1;
 +
                description {
 +
                  state: "default" 0.0;
 +
                  color: 255 255 255 255;
 +
                  rel1 {
 +
                      relative: 0 0;
 +
                  }
 +
                  rel2 {
 +
                      relative: 1 1;
 +
                  }
 +
                }
 +
            }
 +
            part {
 +
                name: "main";
 +
                type: RECT;
 +
                mouse_events: 1;
 +
                description {
 +
                  state: "default" 0.0;
 +
                  color: 128 255 255 255;
 +
                  rel1 {
 +
                      relative: 0.25 0.25;
 +
                      offset: 10 10;
 +
                  }
 +
                  rel2 {
 +
                      relative: 0.75 0.75;
 +
                      offset: -10 -10;
 +
                  }
 +
                }
 +
                description {
 +
                  state: "default" 1.0;
 +
                  color: 128 255 255 50;
 +
                  rel1 {
 +
                      relative: 0.0 0.0;
 +
                      offset: 10 10;
 +
                  }
 +
                  rel2 {
 +
                      relative: 1.0 1.0;
 +
                      offset: -10 -10;
 +
                  }
 +
                }
 +
            }
 +
           
 +
            part {
 +
                name:"button_open";
 +
                type:RECT;
 +
                mouse_events:1;
 +
                description {
 +
                  state: "default" 0.0;
 +
                  color: 255 128 128 255;
 +
                  rel1 {
 +
                      relative: 0.0 0.90;
 +
                  }
 +
                  rel2 {
 +
                      relative: 0.25 1;
 +
                  }
 +
                }
 +
                description {
 +
                  state: "default" 1.0;
 +
                  color: 255 0 0 255;
 +
                  rel1 {
 +
                      relative: 0.0 0.90;
 +
                  }
 +
                  rel2 {
 +
                      relative: 0.25 1;
 +
                  }
 +
                }
 +
            }
 +
           
 +
            part {
 +
                name:"button_close";
 +
                type:RECT;
 +
                mouse_events:1;
 +
                description {
 +
                  state: "default" 0.0;
 +
                  color: 0 255 0 128;
 +
                  rel1 {
 +
                      relative: 0.25 0.90;
 +
                  }
 +
                  rel2 {
 +
                      relative: 0.50 1;
 +
                  }
 +
                }
 +
               
 +
                description {
 +
                  state: "default" 1.0;
 +
                  color: 0 255 0 255;
 +
                  rel1 {
 +
                      relative: 0.25 0.90;
 +
                  }
 +
                  rel2 {
 +
                      relative: 0.50 1;
 +
                  }
 +
                }
 +
            }
 +
        }
 +
       
 +
        programs {
 +
            program {
 +
                name: "complete";
 +
                source: "button_open";
 +
                signal: "mouse,clicked,1";
 +
               
 +
                action: STATE_SET "default" 1.0;       
 +
                target:"main";
 +
                transition:SINUSOIDAL 1;
 +
            }
 +
            program {
 +
                name: "reverse";
 +
                source: "button_close";
 +
                signal: "mouse,clicked,1";
 +
               
 +
                action: STATE_SET "default" 0.5;       
 +
                target:"main";
 +
                transition:ACCELERATE 1;
 +
            }
 +
           
 +
            program {
 +
                name:"button_open_mouse_in";
 +
                source:"button_open";
 +
                signal:"mouse,in";
 +
                action: STATE_SET "default" 1;
 +
                target:"button_open";
 +
                transition:ACCELERATE 0.5;       
 +
            }
 +
           
 +
            program {
 +
                name:"button_open_mouse_out";
 +
                source:"button_open";
 +
                signal:"mouse,out";
 +
                action: STATE_SET "default" 0;
 +
                target:"button_open";
 +
                transition:LINEAR 1;       
 +
            }
 +
            program {
 +
                name:"button_close_mouse_in";
 +
                source:"button_close";
 +
                signal:"mouse,in";
 +
                action: STATE_SET "default" 1;
 +
                target:"button_close";
 +
                transition:ACCELERATE 0.5;       
 +
            }
 +
           
 +
            program {
 +
                name:"button_close_mouse_out";
 +
                source:"button_close";
 +
                signal:"mouse,out";
 +
                action: STATE_SET "default" 0;
 +
                target:"button_close";
 +
                transition:LINEAR 1;       
 +
            }
 +
        }
 +
    }
 +
 
 +
}
 +
 
 +
 
 +
</pre>
  
 
== Macros ==
 
== Macros ==
 +
Edje uses C style macro's:
 +
* #include "filename"
 +
* #define(PARM,PARM2)
 +
Note: define requires that everything is on the same line, newlines must be escaped.
  
 
<TODO>
 
<TODO>
  
 
== Text ==
 
== Text ==
 +
* Both "font" and "size" are required but if font doesn't exist there is fallback to a default.
 +
 +
 +
<pre>
 +
part {
 +
  name:"text_part";
 +
  type:TEXT;
 +
 
 +
  description {
 +
    state: "default" 0.0;
 +
    rel1 {
 +
      relative: 0 0;
 +
    }
 +
    rel2 {
 +
      relative: 1 1;
 +
    }
 +
    text {
 +
      text: "Hello World";
 +
      font: "Sans";
 +
      size:20;
 +
    }
 +
  }
 +
}
 +
</pre>
 +
== Gradients ==
  
 
<TODO>
 
<TODO>
  
 
== Styles ==
 
== Styles ==
 +
<TODO>
  
 
== Color classes ==
 
== Color classes ==
 +
<TODO>
 +
 +
== Timers ==
 +
 +
== Further resources ==
 +
* http://docs.enlightenment.org/api/edje/html/edcref.html
 +
* http://www.cuddletech.com/edje/docs/pdf/edje_book.pdf (outdated?)
 +
 +
[[Category:Middleware]]

Latest revision as of 08:11, 19 July 2009

This page is meant for developers who are totally new enlightenment and wish to have the simplest examples possible. These are my first steps to getting started and are tested on the host machine. This page does not describe howto setup a build environment or how to deploy on openmoko (which is just a matter of copying files).

Edje user interface design is simular to designing for the web (relative, sort a box model, use of images). Graphical tools used for designing web components can almost be reused for edje (buttons, background and other graphical artifacts).

For more references, check Further resources

Contents

[edit] Compiling edj files

Edje files are compiled with the edje_cc command, eg: edje_cc edje_file.edc

I personally use eclipse with the pydev plugins, with an extra script which compiles edc files. A external builder can be defined to execute the script on modification, following setting are used in the builder.

  • Location: ${workspace_loc:/edje/build_edje.sh}
  • Arguments: ${build_files:f}

Next step would be to copy the files to neo with ssh and execute them.

Bash build_edje.sh:

#!/bin/bash

for i in $*
do
case $i in	
	*.edc) cd `dirname $i`; edje_cc $i;;
	*);;
esac
done

[edit] Edje launcher

Program to launch example edje files, to be used if no alternative python example is provided. e.g:

python launcher.py example.edj

Python: launcher.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
#import edje.decorators
import sys
import os

ee = ecore.evas.SoftwareX11(w=480, h=640)
edje_file = sys.argv[1]
print "opening '%s'" % edje_file

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

c.show()
ee.show()
ecore.main_loop_begin();

[edit] Proper initialization examples

Note this example show how an edje should be initialized, the examples after this will not do this to make them clear as possible. Real applications should still do proper initialization.


Fullscreen mode (complete screen on openmoko): ee.fullscreen = True


snippet:

#!/usr/bin/env python

import ecore
import ecore.evas
import edje
import sys
import os

# Parse command line
from optparse import OptionParser

def parse_geometry(option, opt, value, parser):
    try:
        w, h = value.split("x")
        w = int(w)
        h = int(h)
    except Exception, e:
        raise optparse.OptionValueError("Invalid format for %s" % option)
    parser.values.geometry = (w, h)

usage = "usage: %prog [options]"
op = OptionParser(usage=usage)
op.add_option("-e", "--engine", type="choice",
              choices=("x11", "x11-16"), default="x11-16",
              help=("which display engine to use (x11, x11-16), "
                    "default=%default"))
op.add_option("-n", "--no-fullscreen", action="store_true",
              help="do not launch in fullscreen")
op.add_option("-g", "--geometry", type="string", metavar="WxH",
              action="callback", callback=parse_geometry,
              default=(480, 640),
              help="use given window geometry")
op.add_option("-f", "--fps", type="int", default=20,
              help="frames per second to use, default=%default")


# Handle options and create output window
options, args = op.parse_args()
if options.engine == "x11":
    f = ecore.evas.SoftwareX11
elif options.engine == "x11-16":
    if ecore.evas.engine_type_supported_get("software_x11_16"):
        f = ecore.evas.SoftwareX11_16
    else:
        print "warning: x11-16 is not supported, fallback to x11"
        f = ecore.evas.SoftwareX11

w, h = options.geometry
ee = f(w=w, h=h)
ee.fullscreen = not options.no_fullscreen
edje.frametime_set(1.0 / options.fps)

[edit] Simple box with margin

Edje source: box_margin.edc

collections {
   group {
      name: "test";
      	parts {
	    part {
	       name: "main";
	       type: RECT;
	       mouse_events: 0;
	       description {
	          state: "default" 0.0;
	          color: 128 255 255 255;
	          rel1 {
	             relative: 0.0 0.0;
	             offset: 10 10;
	          }
	          rel2 {
	              relative: 1.0 1.0;
	              offset: -10 -10;
	          }
	       }
	    }
        }
    }
}

[edit] Relative box position

This examples show to boxes where left upper corner of one box is set at the right bottom corner of the other.

Edje source: relative_box_position.edc

collections {
    group {
        name: "test";
      	parts {
            part {
                name: "box-red";
                type: RECT;
                mouse_events: 0;
                description {
                   state: "default" 0.0;
                   color: 255 0 0 255;
                   rel1 {
                      relative: 0.0 0.0;
                      offset: 0 0;
                   }
                   rel2 {
                      relative: 0.5 0.5;
                      offset: 0 0;
                   }
                }
            }
            part {
                name: "box-blue";
                type: RECT;
                mouse_events: 0;
                description {
                    state: "default" 0.0;
                    color: 0 0 255 255;
                    rel1 {
                        relative: 1.0 1.0;
                        offset: 0 0;
                        to: "box-red";
                    }
                    rel2 {
                        relative: 1.0 1.0;
                        offset: 0 0;  
                    }
                }
            } 
        }
    }
}

[edit] Image

Note you also need an image 'image.png' which must be located in the same directory as image.edc.

Edje source: image.edc

images {
    image: "image.png" COMP;
}

collections {
    group {
        name: "test";
        parts {
            part {
                name: "image-block";
                type: IMAGE;
                
                description {
                   state: "default" 0.0;
                   
                   image { 
                      normal: "image.png"; 
                   }
                   
                   rel1 {
                      relative: 0.25 0.25;
                      offset: 0 0;
                   }
                   rel2 {
                      relative: 0.75 0.75;
                      offset: 0 0;
                   }
                }
            }
        }
    }
}

[edit] Signals

This examples makes using signal in edje very clear.

Types of signals:

  • Handle signal inside edc, e.g: program: "button_hot";
  • Handle event directly within the python code, e.g: c.signal_callback_add("mouse,clicked,1","button1",button_clicked)
  • Resize callback, e.g: ee.callback_resize = resize_callback
  • Custom signal emitted in edc program, e.g:
 action: SIGNAL_EMIT "button_clicked_signal" "button1" and
 c.signal_callback_add("button_clicked_signal","button1",button_clicked_signal)
  • Emit signal from python to edje


Python source: signal.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
import edje.decorators;
import sys
import os

ee = ecore.evas.SoftwareX11(w=400, h=400)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"signal.edj")

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

# Mouse click signal from part "button"
def button_clicked(obj, signal,source):
    print "button clicked";
c.signal_callback_add("mouse,clicked,1","button1",button_clicked)

# Resize callback
def resize_callback(ee):
    c.size = ee.evas.size
    
ee.callback_resize = resize_callback


def button_clicked_signal(obj,signal,source):
    print "Custom signal emitted after button clicked";
    c.signal_emit("signal_from_python","")

c.signal_callback_add("button_clicked_signal","button1",button_clicked_signal)

c.show()
ee.show()
ecore.main_loop_begin();

Edje source: signal.edc

fonts {
   font: "VeraBd.ttf" "Sans";
}


collections {
    group {
      name: "test";
        parts {
            part {
                name: "button1";
                type: RECT;
                mouse_events: 1;
                description {
                   state: "default" 0.0;
                   color: 0 0 255 128;
                   rel1 {
                      relative: 0.25 0.25;
                      offset: 10 10;
                   }
                   rel2 {
                      relative: 0.75 0.75;
                      offset: -10 -10;
                   }
                }
                description {
                    state: "hot" 0.0;
                    inherit: "default" 0.0;
                    color: 0 0 255 255;
                }
            }
            
            part {
                type: TEXT;
                name:"text";
                

                description {
                   color: 255 255 255 255;
                    rel1 {
                        relative: 0 0.75;
                      
                    }
                    rel2 {
                        relative: 1 1;
                    }
                    text {
                        text:"default text";
                        font:"VeraBd.ttf";
                        size: 20;
                    }
                }
                description {
                   state: "received_signal_from_python" 0;
                   color: 255 255 255 255;
                    rel1 {
                        relative: 0 0.75;
                      
                    }
                    rel2 {
                        relative: 1 1;
                    }
                    text {
                        text:"Received signal from python";
                        font:"VeraBd.ttf";
                        size: 20;
                    }
                }
            }
        }
        programs {
            program {
                name: "button_hot";
                signal: "mouse,in";
                source: "button1";
                
                action: STATE_SET "hot" 0.0;
                target: "button1";
            }
            program {
                name: "button_cold";
// Input
                signal: "mouse,out";
                source: "button1";
                
// Output
                action: STATE_SET "default" 0.0;
                target: "button1";
                
            }
// Program who emits an signal when mouse clicked.            
            program {
                name:"button_clicked_signal_program";
                signal: "mouse,clicked,1";
                source: "button1";
                
                
                action: SIGNAL_EMIT "button_clicked_signal" "button1";
            }
            program {
                name:"handle_python_signal";
                signal:"signal_from_python";
                
                action: STATE_SET "received_signal_from_python" 0;
                target:"text";
            }
        }
}

[edit] Embedded etk widget

Maybe better to replace this example with ewl or elementary (instead of the gtk mimic of edje)

Python code: widget_embed.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
import sys
import os
import etk

ee = ecore.evas.SoftwareX11(w=400, h=200)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"widget_embed.edj")

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

embed = etk.Embed(ee.evas)
entry = etk.Entry()
embed.add(entry)


c.part_swallow("input",embed.object);

embed.show_all()
c.show()
ee.show()

ecore.main_loop_begin();

Edje source: widget_embed.edc

collections {
    group {
        name: "test";
        parts {
            part {
                name: "input";
                type: SWALLOW;
                
                description {
                   state: "default" 0.0;
                   
                   rel1 {
                      relative: 0.25 0.25;
                      offset: 0 0;
                   }
                   rel2 {
                      relative: 0.75 0.75;
                      offset: 0 0;
                   }
                }
            }
        }
    }
}

[edit] Video

Including video in edje is no different than including other external content with swallow part type and smart objects, in fact emotion is a smart object.

Not sure howto setup gstreamer because this would be the preferred method.

Python source:video.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
import sys
import os
import emotion

ee = ecore.evas.SoftwareX11(w=320, h=200)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"video.edj")

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

vid = emotion.Emotion(ee.evas,module_filename="xine");
vid.file_set("video.mpeg");
c.part_swallow("video", vid)

vid.show()
vid.play = True

c.show()
ee.show()
ecore.main_loop_begin()

Edje source: video.edc

collections {
    group {
        name: "test";
        parts {
            part {
                name: "video";
                type: SWALLOW;
                
                description {
                   state: "default" 0.0;
                   aspect: 1.7 1.8;
                   rel1 {
                      relative: 0 0;
                      offset: 0 0;
                   }
                   rel2 {
                      relative: 1 1;
                      offset: 0 0;
                   }
                }
            }
        }
    }
}

[edit] SmartObject

What is a smart object ?

<TODO>

[edit] Scripting

Using the embreyo scripting language inside edc files.

<TODO>

[edit] Transitions

  • If clicked on the red box the blue will enlarge en get transparant.
  • If clicked on the green box tje blue box will return to it's original state.
  • On mouse in red box they will get highlighted (sort of), on mouse they will get dehighlighted.

Some observations:

  • It seems not to be possible to goto a intermediated index (0.5 if 0 and 1 are defined).
  • It seems not to be possible to handle signals depeding on state (e.g: only trigger a certain program if a part is in state x x).
  • It seems not to be possible to apply generic signal handlers which target there source objects (not related to transitions).


Edje source:

collections {
    group {
      name: "test";
        parts {
             part {
                name: "bg";
                type: RECT;
                mouse_events: 1;
                description {
                   state: "default" 0.0;
                   color: 255 255 255 255;
                   rel1 {
                      relative: 0 0;
                   }
                   rel2 {
                      relative: 1 1;
                   }
                }
            }
            part {
                name: "main";
                type: RECT;
                mouse_events: 1;
                description {
                   state: "default" 0.0;
                   color: 128 255 255 255;
                   rel1 {
                      relative: 0.25 0.25;
                      offset: 10 10;
                   }
                   rel2 {
                      relative: 0.75 0.75;
                      offset: -10 -10;
                   }
                }
                description {
                   state: "default" 1.0;
                   color: 128 255 255 50;
                   rel1 {
                      relative: 0.0 0.0;
                      offset: 10 10;
                   }
                   rel2 {
                      relative: 1.0 1.0;
                      offset: -10 -10;
                   }
                }
             }
            
            part {
                name:"button_open";
                type:RECT;
                mouse_events:1;
                description {
                   state: "default" 0.0;
                   color: 255 128 128 255;
                   rel1 {
                      relative: 0.0 0.90;
                   }
                   rel2 {
                      relative: 0.25 1;
                   }
                }
                description {
                   state: "default" 1.0;
                   color: 255 0 0 255;
                   rel1 {
                      relative: 0.0 0.90;
                   }
                   rel2 {
                      relative: 0.25 1;
                   }
                }
            }
            
            part {
                name:"button_close";
                type:RECT;
                mouse_events:1;
                description {
                   state: "default" 0.0;
                   color: 0 255 0 128;
                   rel1 {
                      relative: 0.25 0.90;
                   }
                   rel2 {
                      relative: 0.50 1;
                   }
                }
                
                description {
                   state: "default" 1.0;
                   color: 0 255 0 255;
                   rel1 {
                      relative: 0.25 0.90;
                   }
                   rel2 {
                      relative: 0.50 1;
                   }
                }
            }
        }
        
        programs {
            program {
                name: "complete";
                source: "button_open";
                signal: "mouse,clicked,1";
                
                action: STATE_SET "default" 1.0;        
                target:"main";
                transition:SINUSOIDAL 1;
            }
            program {
                name: "reverse";
                source: "button_close";
                signal: "mouse,clicked,1";
                
                action: STATE_SET "default" 0.5;        
                target:"main";
                transition:ACCELERATE 1;
            }
            
            program {
                name:"button_open_mouse_in";
                source:"button_open";
                signal:"mouse,in";
                action: STATE_SET "default" 1;
                target:"button_open";
                transition:ACCELERATE 0.5;        
            }
            
            program {
                name:"button_open_mouse_out";
                source:"button_open";
                signal:"mouse,out";
                action: STATE_SET "default" 0;
                target:"button_open";
                transition:LINEAR 1;        
            }
            program {
                name:"button_close_mouse_in";
                source:"button_close";
                signal:"mouse,in";
                action: STATE_SET "default" 1;
                target:"button_close";
                transition:ACCELERATE 0.5;        
            }
            
            program {
                name:"button_close_mouse_out";
                source:"button_close";
                signal:"mouse,out";
                action: STATE_SET "default" 0;
                target:"button_close";
                transition:LINEAR 1;        
            }
        }
    }

}


[edit] Macros

Edje uses C style macro's:

  • #include "filename"
  • #define(PARM,PARM2)

Note: define requires that everything is on the same line, newlines must be escaped.

<TODO>

[edit] Text

* Both "font" and "size" are required but if font doesn't exist there is fallback to a default.


part {
  name:"text_part";
  type:TEXT;
  
  description {
    state: "default" 0.0;
    rel1 {
      relative: 0 0;
    }
    rel2 {
      relative: 1 1;
    }
    text {
      text: "Hello World";
      font: "Sans";
      size:20;
    }
  } 
}

[edit] Gradients

<TODO>

[edit] Styles

<TODO>

[edit] Color classes

<TODO>

[edit] Timers

[edit] Further resources

Personal tools

This page is meant for developers who are totally new enlightment and wish to have the simplest examples possible. These are my first steps to getting started and are tested on the host machine. This page does not describe howto setup a build environment or how to deploy on openmoko (which is just a matter of copying files).

Compiling edj files

Edje files are compiled with the edje_cc command, eg: edje_cc edje_file.edc

Proper initialization examples

Note this example show how an edje example should be initialized, the examples after this will not this to make them clear as possible. Real should still do proper initialization.

<TODO>

Simple box with margin

Python source:box_margin.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
#import edje.decorators
import sys
import os

ee = ecore.evas.SoftwareX11(w=480, h=640)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"box_margin.edj")

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

c.show()
ee.show()
ecore.main_loop_begin();

Edje source: box_margin.edc

collections {
   group {
      name: "test";
      	parts {
	    part {
	       name: "main";
	       type: RECT;
	       mouse_events: 0;
	       description {
	          state: "default" 0.0;
	          color: 128 255 255 255;
	          rel1 {
	             relative: 0.0 0.0;
	             offset: 10 10;
	          }
	          rel2 {
	              relative: 1.0 1.0;
	              offset: -10 -10;
	          }
	       }
	    }
        }
    }
}

Relative box position

This examples show to boxes where left upper corner of one box is set at the right bottom corner of the other.

Python source: relative_box_position.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
import sys
import os

ee = ecore.evas.SoftwareX11(w=400, h=400)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"relative_box_position.edj")

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

c.show()
ee.show()
ecore.main_loop_begin();

Edje source: relative_box_position.edc

collections {
    group {
        name: "test";
      	parts {
            part {
                name: "box-red";
                type: RECT;
                mouse_events: 0;
                description {
                   state: "default" 0.0;
                   color: 255 0 0 255;
                   rel1 {
                      relative: 0.0 0.0;
                      offset: 0 0;
                   }
                   rel2 {
                      relative: 0.5 0.5;
                      offset: 0 0;
                   }
                }
            }
            part {
                name: "box-blue";
                type: RECT;
                mouse_events: 0;
                description {
                    state: "default" 0.0;
                    color: 0 0 255 255;
                    rel1 {
                        relative: 1.0 1.0;
                        offset: 0 0;
                        to: "box-red";
                    }
                    rel2 {
                        relative: 1.0 1.0;
                        offset: 0 0;  
                    }
                }
            } 
        }
    }
}

Image

Note you also need an image 'image.png' which must be located in the same directory as image.edc.

Python source: image.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
import sys
import os

ee = ecore.evas.SoftwareX11(w=400, h=400)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"image.edj")

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

c.show()
ee.show()
ecore.main_loop_begin();

Edje source: image.edc

images {
    image: "image.png" COMP;
}

collections {
    group {
        name: "test";
        parts {
            part {
                name: "image-block";
                type: IMAGE;
                
                description {
                   state: "default" 0.0;
                   
                   image { 
                      normal: "image.png"; 
                   }
                   
                   rel1 {
                      relative: 0.25 0.25;
                      offset: 0 0;
                   }
                   rel2 {
                      relative: 0.75 0.75;
                      offset: 0 0;
                   }
                }
            }
        }
    }
}

Signals

This examples makes using signal in edje very clear.

Types of signals:

  • Handle signal inside edc, e.g: program: "button_hot";
  • Handle event directly within the python code, e.g: c.signal_callback_add("mouse,clicked,1","button1",button_clicked)
  • Resize callback, e.g: ee.callback_resize = resize_callback
  • Custom signal emitted in edc program, e.g:
 action: SIGNAL_EMIT "button_clicked_signal" "button1" and
 c.signal_callback_add("button_clicked_signal","button1",button_clicked_signal)
  • Emit signal from python to edje


Python source: signal.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
import edje.decorators;
import sys
import os

ee = ecore.evas.SoftwareX11(w=400, h=400)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"signal.edj")

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

# Mouse click signal from part "button"
def button_clicked(obj, signal,source):
    print "button clicked";
c.signal_callback_add("mouse,clicked,1","button1",button_clicked)

# Resize callback
def resize_callback(ee):
    c.size = ee.evas.size
    
ee.callback_resize = resize_callback


def button_clicked_signal(obj,signal,source):
    print "Custom signal emitted after button clicked";
    c.signal_emit("signal_from_python","")

c.signal_callback_add("button_clicked_signal","button1",button_clicked_signal)

c.show()
ee.show()
ecore.main_loop_begin();

Edje source: signal.edc

fonts {
   font: "VeraBd.ttf" "Sans";
}


collections {
    group {
      name: "test";
        parts {
            part {
                name: "button1";
                type: RECT;
                mouse_events: 1;
                description {
                   state: "default" 0.0;
                   color: 0 0 255 128;
                   rel1 {
                      relative: 0.25 0.25;
                      offset: 10 10;
                   }
                   rel2 {
                      relative: 0.75 0.75;
                      offset: -10 -10;
                   }
                }
                description {
                    state: "hot" 0.0;
                    inherit: "default" 0.0;
                    color: 0 0 255 255;
                }
            }
            
            part {
                type: TEXT;
                name:"text";
                

                description {
                   color: 255 255 255 255;
                    rel1 {
                        relative: 0 0.75;
                      
                    }
                    rel2 {
                        relative: 1 1;
                    }
                    text {
                        text:"default text";
                        font:"VeraBd.ttf";
                        size: 20;
                    }
                }
                description {
                   state: "received_signal_from_python" 0;
                   color: 255 255 255 255;
                    rel1 {
                        relative: 0 0.75;
                      
                    }
                    rel2 {
                        relative: 1 1;
                    }
                    text {
                        text:"Received signal from python";
                        font:"VeraBd.ttf";
                        size: 20;
                    }
                }
            }
        }
        programs {
            program {
                name: "button_hot";
                signal: "mouse,in";
                source: "button1";
                
                action: STATE_SET "hot" 0.0;
                target: "button1";
            }
            program {
                name: "button_cold";
// Input
                signal: "mouse,out";
                source: "button1";
                
// Output
                action: STATE_SET "default" 0.0;
                target: "button1";
                
            }
// Program who emits an signal when mouse clicked.            
            program {
                name:"button_clicked_signal_program";
                signal: "mouse,clicked,1";
                source: "button1";
                
                
                action: SIGNAL_EMIT "button_clicked_signal" "button1";
            }
            program {
                name:"handle_python_signal";
                signal:"signal_from_python";
                
                action: STATE_SET "received_signal_from_python" 0;
                target:"text";
            }
        }
}

Embedded etk widget

Maybe better to replace this example with ewl or elementary (instead of the gtk mimic of edje)

Python code: widget_embed.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
import sys
import os
import etk

ee = ecore.evas.SoftwareX11(w=400, h=200)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"widget_embed.edj")

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

embed = etk.Embed(ee.evas)
entry = etk.Entry()
embed.add(entry)


c.part_swallow("input",embed.object);

embed.show_all()
c.show()
ee.show()

ecore.main_loop_begin();

Edje source: widget_embed.edc

collections {
    group {
        name: "test";
        parts {
            part {
                name: "input";
                type: SWALLOW;
                
                description {
                   state: "default" 0.0;
                   
                   rel1 {
                      relative: 0.25 0.25;
                      offset: 0 0;
                   }
                   rel2 {
                      relative: 0.75 0.75;
                      offset: 0 0;
                   }
                }
            }
        }
    }
}

Video

Not sure howto setup gstreamer because this would be the preferred method.

Python source:video.py

#!/usr/bin/env python

import evas
import ecore
import ecore.evas
import edje
import sys
import os
import emotion

ee = ecore.evas.SoftwareX11(w=320, h=200)
edje_file = os.path.join(os.path.dirname(sys.argv[0]),"video.edj")

c = edje.Edje(ee.evas,file=edje_file,group="test")
c.size = ee.evas.size

vid = emotion.Emotion(ee.evas,module_filename="xine");
vid.file_set("video.mpeg");
c.part_swallow("video", vid)

vid.show()
vid.play = True

c.show()
ee.show()
ecore.main_loop_begin()

Edje source: video.edc

collections {
    group {
        name: "test";
        parts {
            part {
                name: "video";
                type: SWALLOW;
                
                description {
                   state: "default" 0.0;
                   aspect: 1.7 1.8;
                   rel1 {
                      relative: 0 0;
                      offset: 0 0;
                   }
                   rel2 {
                      relative: 1 1;
                      offset: 0 0;
                   }
                }
            }
        }
    }
}

SmartObject

What is a smart object ?

<TODO>

Scripting

Using the embreyo scripting language inside edc files.

<TODO>

Transitions

<TODO>

Macros

<TODO>

Text

<TODO>

Styles

Color classes