How styling PyMT Widget ?

25 views
Skip to first unread message

Mathieu Virbel

unread,
May 13, 2009, 5:45:55 AM5/13/09
to pymt-dev
Hi everyone.

Yesterday, i've been in front of a new design problem.
I would like to add more css styling in actual widget.
The problem is, how initialize a widget with special style ?

Take the MTButton. MTButton have duplicate way to set a style :
* in css with : "color-down" and "bg-color"
* in __init__ with : color_down, bg_color, font_size, bold,
border_radius

This is not simplest to understand which css name to use for an
attribute.

So, i would like to move all style attribute from init into style
attribute.
Before:
m = MTButton(text="Hello", color_down=(1,0,1), font_size=16,
bg_color=(0,0,0))

After:
m = MTButton(text="Hello", style={'color-down': (1,0,1), 'font-
size': 16, 'bg-color': (0,0,0)})

Plus :
+ Same attribute will be used for styling from __init__ or css
+ No more code to check what user want to use (__init__ attribute or
default css ?)
+ One documentation for styling

Cons:
- Break current styling with __init__.

Since we are only in a alpha/beta stage (0.2), i think we can do it.


Guys ?

++tito;


Sharath Patali

unread,
May 13, 2009, 5:58:15 AM5/13/09
to pymt...@googlegroups.com
Yo Plopers!
This seems like a good idea and as it will definitely make things clearer to understand and put a more standard structure to widget styling and in my opinion i feel its best to separate styling from the actual parameters which are passed in a _init_, plus a standard styling documentation is a plus!!, yes one bad thing is we need to rewrite the existing apps that we wrote, if im not wrong

~Sharath

tito -

unread,
May 13, 2009, 7:57:21 AM5/13/09
to pymt...@googlegroups.com
Exact, you'll need to convert your source to match the new syntax.

> - Break current styling with __init__.

2009/5/13 Sharath Patali <sharath...@gmail.com>:

xelapond

unread,
May 13, 2009, 10:04:52 AM5/13/09
to pymt...@googlegroups.com
+1

We don't have that many apps that use custom styling, so it shouldn't be a problem.

Nathanaël Lécaudé

unread,
May 13, 2009, 10:11:56 AM5/13/09
to pymt...@googlegroups.com
Using this scheme, will it be possible to modify an attribute at
run-time (ie after init)
I assume we would just modify the property, so let's say I want to
modify the background color of my widget while the program is running,
I would do mybutton.bgcolor = newcolor
or would I need to use the style ?

2009/5/13 Mathieu Virbel <txp...@gmail.com>:

tito -

unread,
May 13, 2009, 10:16:32 AM5/13/09
to pymt...@googlegroups.com
You will use style :

# raw way
mybutton.style['bg-color'] = newcolor

Or

# standard way
mybutton.apply_css({'bg-color': newcolor})



2009/5/13 Nathanaël Lécaudé <n...@studioimaginaire.com>:

tito -

unread,
May 13, 2009, 10:31:20 AM5/13/09
to pymt...@googlegroups.com
Well, accessing on the style dict directly can be a problem... The
widget must hook all the update in style to update his component
(MTButton use pyglet Label...).
It's already done in apply_css... Well, i can fix that too.

2009/5/13 tito - <txp...@gmail.com>:

Nathanaël Lécaudé

unread,
May 13, 2009, 10:31:28 AM5/13/09
to pymt...@googlegroups.com
Cool, elegant

2009/5/13 tito - <txp...@gmail.com>:

tito -

unread,
May 13, 2009, 10:48:35 AM5/13/09
to pymt...@googlegroups.com
I prefer to forbid the Raw solution.
Imagine you wanna change 3 styles attributes, apply_css can update the
whole style in only one time, instead of 3 times with the Raw
Solution...


2009/5/13 tito - <txp...@gmail.com>:

Thomas Hansen

unread,
May 13, 2009, 1:45:45 PM5/13/09
to pymt...@googlegroups.com
I liek it. Ho we decide what thing is part of style/widget? e.g. for
html css has pos/size/width etc. are all part of style, shoudl we do
this also? i think for html many things always draw the same (box
like, they have padding etc.), but in pymt you can do many different
things for drawing and have different style parameters for each widget
which looks unique.

Does InnerAnimation work with style attribs? that would be super cool.

To get around backwards comnpatability, why not allow both(maybe just
for little while..maybe doesnt matter)? just have to make make sure
one always overwrits the other so it has consitent behaviour. liek
e.g. in init of MTWidget do (or other way around)

for s in kwargs:
if style.has_key(s) or is_style_parameter(s):
style[s] = kwargs[s]


--
Thoams

Nathanaël Lécaudé

unread,
May 13, 2009, 2:03:08 PM5/13/09
to pymt...@googlegroups.com
I wanted to add :
I don't think it's too late for these types of design changes.
PyMT is very young and I think it's important we get a solid base,
even if it means re-writing a lot of stuff.

My 2 cents.

Nat

2009/5/13 Thomas Hansen <thomas...@gmail.com>:

Thomas Hansen

unread,
May 13, 2009, 2:07:00 PM5/13/09
to pymt...@googlegroups.com
agreed :) i do like idea of putting styles into one place for every widget!


Also related to style. tito raised interresting question on IRC:

<tito> for example, we provide MTButton, a very very simple class
<tito> but we derivate from button lot of widget
<tito> imagine, i want to change the drawing of button, make it nicer
<tito> should i change the base class for everyone ?
<tito> or making a new class, and derivate all the other class too ?

very interresting question. not sure about best solution. maybe use
delegates? (I remeber talking with tito about delegates a little a
while ago, but for something else). You could have like a
ButtonRenderer class which is used by any button class to render
itself, when you want button rendered differently, you swicth its
ButtonRenderer with a different one like PrettyButtonRenderer (really
these just have to imlpement draw...mayeb we can even just switch draw
method dynamically without need for objects). with python we can hide
a lot of this behind the scenes.


--
Thomas

tito -

unread,
May 13, 2009, 2:35:21 PM5/13/09
to pymt...@googlegroups.com
Does we really want to maintain compat between 0.2 and 0.x ?

I was thinking that pos / size is not styling.
Style is padding / marging / color / border...

In the core-enhance-theme, you could do that :

from pymt import *

additional_css = '''
button.btnA {
draw-text-shadow: 1;
draw-alpha-background: 1;
bg-color: #ff5c00;
draw-border: 1;
border-radius: 20;
font-size: 16;
border-precision: .1;
}
'''

css_add_sheet(additional_css)

m = MTWindow()
m.add_widget(MTButton(label='Coucou', pos=(100, 100)))
m.add_widget(MTButton(label='Coucou', cls='btnA', pos=(100, 210)))
runTouchApp()

And the result :
http://txzone.net/files/projects/pymt/cssbutton.png



You can build your app without style. And make styling after, in a
seperated css.
Look really like HTML document :)


2009/5/13 Thomas Hansen <thomas...@gmail.com>:

tito -

unread,
May 13, 2009, 2:38:12 PM5/13/09
to pymt...@googlegroups.com
About my irc speech, my head was burned :)
There is a better way to do styling: use css.
Like a web navigator, you have base widget, with lot of possibility.
(border, color...)
For the example before, i've enhanced MTButton, but by default, it
look like before.

Having a theme by replacing the draw() function is too bad. It will be
hard to make change
in all theme if we change the core. We've started to use CSS, so i
think we can use it for
the whole styling.

2009/5/13 Thomas Hansen <thomas...@gmail.com>:

Thomas Hansen

unread,
May 13, 2009, 2:48:33 PM5/13/09
to pymt...@googlegroups.com
NICE! those buttons look awesome. I see what you are saying, so make
core widgets very flexible in drawing and then just use CSS.

Are there specific things I have to make sure when writing new widget
that use style? I will make a line graph widget with style support.
I'm assuming some style properties should always be named the same
across widgets like: color, bg-color, border-size, font-size etc.
What about specific properties? can I just add key/value for specific
widget for that?

So for line graph I'm thinking for example color of each line.
depends on how many lines there are, can i specify arrays of values in
css?

--
Thomas

tito -

unread,
May 13, 2009, 3:20:39 PM5/13/09
to pymt...@googlegroups.com
If you want to support style (for example, slider-color.)
* remove all style declaration in init.
* add a default value for "slider-color" in the default css file in
colors.py. You can add it to the * {} rules for example : this will be
the same value for all widget using slider-color. (you can move to a
more specific declaration, but maybe another widget use the same css
declaration.)
* in draw code, just use: set_color(*self.style.get('slider-color')).

All the rest is done by mtwidget :)

Look :
http://code.google.com/p/pymt/source/browse/pymt/ui/widgets/button.py?spec=svn266b5b9ffce3989879d27cac92f0ce488893af7d&r=0e4472918a3f55fa5603ade8d142f78833d88ada#111

2009/5/13 Thomas Hansen <thomas...@gmail.com>:

tito -

unread,
May 13, 2009, 3:51:27 PM5/13/09
to pymt...@googlegroups.com
I forget to respond about inner animation.
I'll make it work with style :)

2009/5/13 tito - <txp...@gmail.com>:

tito -

unread,
May 14, 2009, 8:45:16 AM5/14/09
to pymt...@googlegroups.com
Work in progress :

Feature:
* featured "cls" : a widget can have one or multiple classes.
* starting documentation in wiki :
http://code.google.com/p/pymt/wiki/StylingWidget

Screenshot : http://txzone.net/files/projects/pymt/pymt-css.png

Code:
-------------------------------------------------------------------------------------
from pymt import *

additional_css = '''
.simple {
draw-alpha-background: 1;
draw-border: 1;
draw-slider-alpha-background: 1;
draw-slider-border: 1;
draw-text-shadow: 1;
}

.colored {
bg-color: #ff5c00;
border-radius: 20;
border-radius-precision: .1;
font-size: 16;
slider-border-radius-precision: .1;
slider-border-radius: 10;
}

slider.colored {
bg-color: #222222;
}
'''

css_add_sheet(additional_css)

m = MTWindow()

h = MTBoxLayout(padding=20, spacing=20)

v = MTBoxLayout(orientation='vertical', padding=20, spacing=20)
v.add_widget(MTButton(label='Coucou', pos=(100, 100)))
v.add_widget(MTButton(label='Coucou', cls='simple', pos=(100, 210)))
v.add_widget(MTButton(label='Coucou', cls=('simple', 'colored'),
pos=(100, 210)))
h.add_widget(v)

v2 = MTBoxLayout(orientation='vertical', padding=20, spacing=20)
v2.add_widget(MTSlider(orientation='horizontal', value=50))
v2.add_widget(MTSlider(cls='simple', orientation='horizontal', value=50))
v2.add_widget(MTSlider(cls=('simple', 'colored'),
orientation='horizontal', value=50))
h.add_widget(v2)

m.add_widget(h)
runTouchApp()
-------------------------------------------------------------------------------------


2009/5/13 tito - <txp...@gmail.com>:
Reply all
Reply to author
Forward
0 new messages