GUIs - A Modest Proposal

lkcl luke.leighton at gmail.com
Mon Jun 14 10:15:08 EDT 2010


On Jun 13, 2:34 pm, Stephen Hansen <me+list/pyt... at ixokai.io> wrote:
> On 6/13/10 4:29 AM, lkcl wrote:
>
> >  it's in fact how the entire pyjamas UI widget set is created, by
> > doing nothing more than direct manipulation of bits of DOM and direct
> > manipulation of the style properties.  really really simple.
>
> Did you just call DOM manipulation simple with a straight face? I don't
> think I've ever seen that before.

 *lol* - wait for it: see below.  summary: once you start using high-
level widgets: yes.  without such, yeah you're damn right.

> HTML+CSS have some very strong advantages. Simplicity is not one of
> them. Precision web design these days is a dark art. (Go center an image
> vertically and horizontally in an arbitrary sized field!)

 stephen, _thank_ you - that was _exactly_ why i decided i flat-out
was NEVER going to do "plain" HTML/CSS programming _ever_ again.  i
spent twwoooooo weeeeeeks trying to do exactly this (well, it was 7
boxes, not an image) - and i failed.

 i succeeded on firefox to get the boxes centred, but with IE, when
you resized the screen, the bloody boxes went off the top!  they were
so "centred" that they went off the top of the screen!  and the bloody
idiotic IE team forgot that you can't scroll _up_ off the top of the
screen :)

 in desperation, i blindly wandered into pyjamas, and went "yessss" -
and within 50 minutes i had converted my site to do exactly this.

 you can see the results here: http://lkcl.net and the main code is
here:
http://lkcl.net/site_code/index.py

 the relevant (crucial) function is the onWindowResized function which
gets called because of this: Window.addWindowResizeListener(self)


   def onWindowResized(self, width, height):

        self.toprow.removeFromParent()
        self.middlerow.removeFromParent()
        self.bottomrow.removeFromParent()
        self.html.removeFromParent()
        self.ads.removeFromParent()

        self.create_layout()

 the create_layout function basically does this:

        width = Window.getClientWidth()

        if width > 800:

            toprow = HorizontalPanel()
            middlerow = HorizontalPanel()
            bottomrow = HorizontalPanel()

        elif width > 640:

            # different types of layout panels

        else:

            # utterly skinny vertical-only panels

 those three panels are added into another panel which has 100% width
and 100% height, and has "centre" properties attached to its cells;
voila, the boxes always sit in the middle of the screen.  when the
screen is too big for the 100% height outer panel, the boxes "push"
against the constraints of their outer panel, thus forcing the screen
to become bigger and thus automatically a vertical scroll-bar is
added.  for some browsers this results in another onWindowResize
notification and for some it doesn't (eurgh) - but that's another
story :)

 this is what i was referring to in another message... rats, can't
find it now: it was the one asking about why qt4 and gtk2 layouts
don't cut it, and i explained about the recursive complex child-parent
interaction rules between DOM objects.


 but - allow me to write a quick app which does what you ask:

 from pyjamas.ui.Image import Image
 from pyjamaas.ui.AbsolutePanel import AbsolutePanel
 from pyjamaas.ui import RootPanel
 from pyjamas import Window

 class Thingy:
    def __init__(self):
       self.panel = AbsolutePanel(Width="100%", Height="100%")
       self.image = Image("http://python.org/python.png")
       self.panel.add(image, 0, 0) # add in top-left just for now

       # make a "fake" initial window resize notification
       self.onWindowResized(Window.getClientWidth(),
Window.getClientHeight())
       Window.addResizeListener(self)

    def onWindowResized(self, width, height):
       """ ok - ignore the image's width and height
           because you have to wait for it to load, first,
           and that means doing an onImageLoad async notification
           and this is supposed to be a short demo!
        """
       self.panel.setWidgetPosition(self.image, width/2, height/2)

  RootPanel.add(Thingy())


and... yes, honest to god, that's a web application.  _really_ a web
application.  not an HTML/CSS one, but it's still a web application -
and not a single line of javascript or even DOM manipulation in sight.

if you had to do that as javascript, it would be... eurgh - 300 lines
of unreadable crap?  if you had to do that *without the pyjamas ui
widget set* it would be ... ergh... 150 lines of barely tolerable
crap.  but with the AbsolutePanel class, and the Image widget, and the
neat "wrapping" of event handling?  pffh - complete doddle.

i think... this is what's making pyjamas so hard for people to grasp.
it sits literally in the middle between _both_ technologies: web
browsers which have a reputation for being utterly utterly useless and
"hard to program" because any real programmer wouldn't _dream_ of
calling HTML an actual programming language; and on the other side
there's people who use existing python widget sets who believe that
anything that's based on web technology couldn't _possibly_ be up to
the job.

 oh look - there's a common theme, there: "web technology equals
useless" :)

 l.



More information about the Python-list mailing list