gtk.py :  » Ajax » pyjamas » src » pygtkweb » library » Python Open Source

Home
Python Open Source
1.3.1.2 Python
2.Ajax
3.Aspect Oriented
4.Blog
5.Build
6.Business Application
7.Chart Report
8.Content Management Systems
9.Cryptographic
10.Database
11.Development
12.Editor
13.Email
14.ERP
15.Game 2D 3D
16.GIS
17.GUI
18.IDE
19.Installer
20.IRC
21.Issue Tracker
22.Language Interface
23.Log
24.Math
25.Media Sound Audio
26.Mobile
27.Network
28.Parser
29.PDF
30.Project Management
31.RSS
32.Search
33.Security
34.Template Engines
35.Test
36.UML
37.USB Serial
38.Web Frameworks
39.Web Server
40.Web Services
41.Web Unit
42.Wiki
43.Windows
44.XML
Python Open Source » Ajax » pyjamas 
pyjamas » src » pygtkweb » library » gtk.py
import pyjd
from pyjamas import log

import browser
import gdk
#import lxml.etree


# WINDOW TYPES
WINDOW_TOPLEVEL = 1

# GTK OPTIONS (flags)
EXPAND = 1
FILL = 2

# GTK WIDGET FLAGS
TOPLEVEL = 1
NO_WINDOW = 2
REALIZED = 4
MAPPED = 8
VISIBLE = 16
SENSITIVE = 32
PARENT_SENSITIVE = 64
CAN_FOCUS = 128
HAS_FOCUS = 256
CAN_DEFAULT = 512
HAS_DEFAULT = 1024
HAS_GRAB = 2048
RC_STYLE = 4096
COMPOSITE_CHILD = 8192
NO_REPARENT = 16384
APP_PAINTABLE = 32768
RECEIVES_DEFAULT = 65536
DOUBLE_BUFFERED = 131072

# GTK Update Type Constants
UPDATE_CONTINUOUS = 1
UPDATE_DISCONTINUOUS = 2
UPDATE_DELAYED = 4

# GTK Position Type Constants
POS_LEFT = 1
POS_RIGHT = 2
POS_TOP = 4
POS_BOTTOM = 8


class GObject:
    def __init__(self):
        self.callbacks = {}
        self.connections = 0

    def connect(self, detailed_signal, handler, *data):
        detailed_signal = detailed_signal.replace('_', '-')
        l = self.callbacks.setdefault(detailed_signal,[])
        l.append((handler, data))
        self.connections += 1
        return self.connections

    def connect_object(self, detailed_signal, handler, gobject, data=None):
        detailed_signal = detailed_signal.replace('_', '-')
        def inner(widget, data):
            if handler.func_code.co_argcount == 1:
                handler(widget)
            else:
                handler(widget, data)
        self.connect(detailed_signal, inner, data)

    def emit(self, detailed_signal, *args):
        detailed_signal = detailed_signal.replace('_', '-')
        if self.callbacks.has_key(detailed_signal):
            for pair in self.callbacks[detailed_signal]:
                if pair[1]:
                    pair[0](self, *pair[1])
                else:
                    pair[0](self)

    def dom_event(self, event, element):
        pass


class Object(GObject):
    def __init__(self):
        GObject.__init__(self)
        self.flags = 0

    def set_flags(self, flags):
        self.flags = flags


class Widget(Object):
    def __init__(self):
        Object.__init__(self)
        self._visible = False
        self.widget_cont = browser.Element('div')
        self.widget_cont.setStyle('visibility', 'hidden')
        self.widget_cont.setStyle('position', 'absolute')
        self.widget_cont.setStyle('overflow', 'hidden')
        self.minheight = 1
        self.minwidth = 1
        self.widget_cont.setPxStyle('minHeight', self.minheight)
        self.widget_cont.setPxStyle('minWidth', self.minwidth)
        self.margin = 0
        self.widget_cont.setPxStyle('margin', self.margin)
        self._parent = None

    def get_allocation(self):
        x = self.widget_cont.getX()
        y = self.widget_cont.getY()
        w = self.widget_cont.getWidth()
        h = self.widget_cont.getHeight()
        return gdk.Rectangle(x, y, w, h)

    def show(self):
        self._visible = True
        self.widget_cont.setStyle('visibility', 'visible')
        self._redraw()

    def hide(self):
        self._visible = False
        self.widget_cont.setStyle('visibility', 'hidden')

    def show_all(self):
        self.show()

    def hide_all(self):
        self.hide()

    def destroy(self):
        self.emit('destroy')

    def grab_default(self):
        pass #TODO

    def set_size_request(self, width, height):
        pass

    def _redraw(self):
        container = self.widget_cont
        container.setPxStyle('minHeight', self.minheight)
        container.setPxStyle('minWidth', self.minwidth)
        container.setPxStyle('margin', self.margin)


class Entry(Widget):
    def __init__(self):
        Widget.__init__(self)
        self.widget_int = browser.Document.createElement('input')
        self.widget_cont.append(self.widget_int)


class Container(Widget):
    def __init__(self):
        Widget.__init__(self)
        self.children = []
        self.widget_int = browser.Document.createElement('div')
        self.widget_int.setStyle('position', 'absolute')
        self.widget_cont.append(self.widget_int)

    def add(self, child):
        if self._visible: child.show()
        child._parent = self
        self.children.append(child)
        self.widget_int.append(child.widget_cont)
        self.minwidth += child.minwidth
        self.minheight += child.minheight

    def set_border_width(self, border_width):
        self.margin = border_width
        self._redraw()

    def get_border_width(self):
        return self.margin

    def _redraw(self):
        Widget._redraw(self)
        container = self.widget_cont
        container.setPxStyle('width', container.getWidth())
        container.setPxStyle('height', container.getHeight())
        self.minwidth = 2 * self.margin
        self.minheight = 2 * self.margin
        for child in self.children:
            child._redraw()
        if len(self.children) == 1:
            self.minwidth += self.children[0].minwidth
            self.minheight += self.children[0].minheight
        container.setPxStyle('minHeight', self.minheight)
        container.setPxStyle('minWidth', self.minwidth)

    def show_all(self):
        for child in self.children:
            child.show_all()
        Widget.show_all(self)

    def hide_all(self):
        for child in self.children:
            child.hide_all()
        Widget.hide_all(self)

    def child_set_property(self, child, prop, value):
        setattr(child, prop, value)


class Bin(Container):
    def __init__(self):
        Container.__init__(self)

    def get_child(self):
        if len(self.children)>0:
            return self.children[0]
        else:
            return None

    def add(self, child):
        if len(self.children)>0:
            pass #TODO: GtkWarning !!!
        Container.add(self, child)


class Table(Container):
    def __init__(self, rows=1, columns=1, homogeneous=False):
        Container.__init__(self)
        self.rows = rows
        self.columns = columns
        self.vert_inc = 100.0/rows
        self.horitz_inc = 100.0/columns

    def attach(self, child, left_attach, right_attach,
               top_attach, bottom_attach, xoptions=None,
               yoptions=None, xpadding=0, ypadding=0):
        if xoptions is None:
            xoptions = EXPAND | FILL
        if yoptions is None:
            yoptions = EXPAND | FILL

        Container.add(self, child)
        child_container = child.widget_cont
        child_container.setPercentStyle('left', left_attach * self.horitz_inc)
        child_container.setPercentStyle('right',
                                        100 - right_attach * self.horitz_inc)
        child_container.setPercentStyle('top', top_attach * self.vert_inc)
        child_container.setPercentStyle('bottom',
                                        100 - bottom_attach * self.vert_inc)


class Box(Container):
    def __init__(self):
        Container.__init__(self)

    def _add_element(self, element):
        Container.add(self, element)

    def pack_start(self, child, expand=True, fill=True, padding=0):
        child.expand = expand
        child.fill = fill
        child.padding = padding
        self._add_element(child)

    def add(self, child):
        child.expand = True
        child.fill = True
        child.padding = 0
        self._add_element(child)


class HBox(Box):
    def __init__(self, homogeneous=False, spacing=0):
        Box.__init__(self)
        self.homogeneous = homogeneous
        self.spacing = spacing

    def _add_element(self, element):
        Box._add_element(self, element)
        element.widget_cont.setPxStyle('height', self.widget_cont.getHeight() -
                                                 2 * self.margin)
        self._redraw()

    def _redraw(self):
        Box._redraw(self)
        count = 0
        fix_width = 0
        if not self.homogeneous:
            for child in self.children:
                if child.expand:
                    count += 1
                else:
                    fix_width += child.minwidth + self.spacing + \
                                 child.padding + 2 * child.margin
        else:
            count = len(self.children)
        container = self.widget_cont
        left = self.margin
        for child in self.children:
            if len(self.children) != 1:
                if child.minheight + 2 * self.margin > self.minheight:
                    self.minheight = child.minheight + 2 * self.margin
                self.minwidth += child.minwidth + 2 * child.margin + \
                                 self.spacing + child.padding
        container.setPxStyle('minHeight', self.minheight)
        container.setPxStyle('minWidth', self.minwidth)

        count = max(count, 1)
        horiz_inc = (container.getWidth() - 2*self.margin - fix_width) / count

        for child in self.children:
            child_container = child.widget_cont
            child_container.setPxStyle('height',
                                       container.getHeight() - 2 * self.margin)
            child_container.setPxStyle('left', left + self.spacing / 2 +
                                               child.padding / 2)
            if child.expand:
                left += horiz_inc
            else:
                left += child.minwidth + 2 * child.margin + self.spacing + \
                        child.padding

            right = container.getWidth() - self.margin - left
            right = max(right, self.margin)
            child_container.setPxStyle('right', right + self.spacing / 2 +
                                                child.padding / 2)
            child._redraw()


class VBox(Box):
    def __init__(self, homogeneous=False, spacing=0):
        Box.__init__(self)
        self.homogeneous = homogeneous
        self.spacing = spacing

    def _add_element(self, element):
        Box._add_element(self, element)
        element.widget_cont.setPxStyle('width', self.widget_cont.getWidth() -
                                                2 * self.margin)
        self._redraw()

    def _redraw(self):
        Box._redraw(self)
        count = 0
        fix_height = 0
        if not self.homogeneous:
            for child in self.children:
                if child.expand:
                    count += 1
                else:
                    fix_height += child.minheight + self.spacing + \
                                  child.padding + 2 * child.margin
        else:
            count = len(self.children)
        top = self.margin
        for child in self.children:
            if len(self.children) != 1:
                if child.minwidth + 2 * self.margin > self.minwidth:
                    self.minwidth = child.minwidth + 2 * self.margin
                self.minheight += child.minheight + 2 * child.margin + \
                                  self.spacing + child.padding
        self.widget_cont.setPxStyle('minHeight', self.minheight)
        self.widget_cont.setPxStyle('minWidth', self.minwidth)

        count = max(count, 1)
        vert_inc = (self.widget_cont.getHeight() - 2 * self.margin -
                    fix_height) / count
        for child in self.children:
            child.widget_cont.setPxStyle('width', self.widget_cont.getWidth() -
                                                  2 * self.margin)
            child.widget_cont.setPxStyle('top', top + self.spacing / 2 +
                                                child.padding / 2)
            if child.expand:
                top += vert_inc
            else:
                top += child.minheight + 2 * child.margin + self.spacing + \
                       child.padding

            bottom = self.widget_cont.getHeight() - self.margin - top
            bottom = max(bottom, self.margin)
            child.widget_cont.setPxStyle('bottom', bottom + self.spacing / 2 +
                                                   child.padding / 2)
            child._redraw()


class Window(Bin):
    def __init__(self, type=WINDOW_TOPLEVEL):
        Bin.__init__(self)
        browser.Document.window.catchEvents(['resize'], self)

        self.type = type
        self.title = ''
        self.child = None
        # XXX using a tuple here isn't supported yet
        for style in ['top', 'bottom', 'right', 'left']:
            self.widget_cont.setPxStyle(style, 0)
        if self.type == WINDOW_TOPLEVEL:
            browser.Document.append(self.widget_cont)
        else:
            pass #TODO: Create pop-up

    def add(self, child):
        Bin.add(self, child)
        child.widget_cont.setPxStyle('width', self.widget_cont.getWidth())
        child.widget_cont.setPxStyle('height', self.widget_cont.getHeight())
        self.child = child

    def set_title(self, title):
        self.title = title
        if self.type == WINDOW_TOPLEVEL:
            browser.Document.setTitle(title)
        else:
            pass #TODO

    def show(self):
        self._redraw()
        Bin.show(self)

    def _redraw(self):
        if self.child:
            self.child.widget_cont.setPxStyle('width',
                                              self.widget_cont.getWidth())
            self.child.widget_cont.setPxStyle('height',
                                              self.widget_cont.getHeight())
        Bin._redraw(self)

    def dom_event(self, event, element):
        if event.type in ['resize']:
            self._redraw()


class Button(Bin):
    def __init__(self, label=None):
        Bin.__init__(self)
        self.widget_cont.catchEvents(['click'], self)
        self.child = None
        if label is not None:
            self.add(Label(label))

        self.widget_int.setStyle('textAlign', 'center')
        self.widget_int.setProperty('className', 'button')
        self.minheight = 25
        self.minwidth = 20

    def add(self, child):
        Bin.add(self, child)
        self.child = child
        self._redraw()

    def _redraw(self):
        Bin._redraw(self)
        self.minheight += self.child.minheight
        self.minwidth += self.child.minwidth
        width = self.widget_cont.getWidth()
        width = max(width, self.minwidth + 2)
        height = self.widget_cont.getHeight()
        height = max(height, self.minheight + 2)
        self.widget_int.setPxStyle('width', width - 2)
        self.widget_int.setPxStyle('height', height - 2)
        self.child.widget_cont.setPxStyle('width', width)
        self.child.widget_cont.setPxStyle('height', height)
        self.child._redraw()

    def dom_event(self, event, element):
        if event.type == 'click':
            self.emit('clicked')


class ToggleButton(Button):
    def __init__(self, label=None):
        Button.__init__(self, label)
        self.connect("toggled", self.toggled)
        self.istoggled = False
        self.widget_int.setProperty('className', 'togglebutton')

    def toggled(self, widget, event=None, data=None):
        self.istoggled = not self.istoggled
        if self.istoggled:
            self.widget_int.setProperty('className', 'togglebutton-toggled')
        else:
            self.widget_int.setProperty('className', 'togglebutton')

    def set_active(self, is_active):
        if (is_active and not self.istoggled) or \
           (not is_active and self.istoggled):
            self.emit('toggled')

    def get_active(self):
        return self.istoggled

    def dom_event(self, event, element):
        if event.type == 'click':
            self.emit('toggled')


class CheckButton(ToggleButton):
    def __init__(self, label=None):
        ToggleButton.__init__(self)
        self.check = browser.Element('input')
        self.check.setStyle('position', 'absolute')
        self.check.setStyle('width', 'auto')
        self.check.setStyle('height', 'auto')
        self.check.setPxStyle('left', 0)
        self.check.setProperty('type', 'checkbox')
        self.check_widget = Widget()
        self.check_widget.widget_cont.append(self.check)
        self.check_widget.show()

        self.box = HBox(spacing=6)
        self.box.show()
        self.box.pack_start(self.check_widget, False)
        self.add(self.box)

        if label is not None:
            self.label = Label(label)
            self.box.pack_start(self.label, False)
        self.widget_int.setProperty('className', 'checkbutton')

    def add(self, child):
        #TODO Check that no more than one widget is added.
        ToggleButton.add(self, child)

    def toggled(self, widget, event=None, data=None):
        self.istoggled = not self.istoggled
        if self.istoggled:
            self.check.setProperty('checked', "1")
        else:
            self.check.setProperty('checked', None)

    def _redraw(self):
        ToggleButton._redraw(self)
        # XXX what's this half pixel in 2.5?
        self.check.setPxStyle('top',
          self.check_widget.widget_cont.getHeight() / 2 -
          self.check.getHeight() / 2 - 2.5)
        self.check_widget.minwidth = self.check.getWidth() + 2
        self.check_widget.minheight = self.check.getHeight() + 2
        self.check_widget._redraw()


class RadioButton(CheckButton):
    counter = 0
    groups = {}
    running = False

    def __init__(self, group=None, label=None):
        CheckButton.__init__(self, label)
        self.check.setProperty('type', 'radio')
        if group is None:
            self.group = RadioButton.counter
            RadioButton.counter += 1
            RadioButton.groups[self.group] = [self]
        else:
            self.group = group.group
            RadioButton.groups[self.group].append(self)

    def toggled(self, widget, event=None, data=None):
        if RadioButton.running:
            return
        RadioButton.running = True
        for b in RadioButton.groups[self.group]:
            if b.istoggled:
                b.check.setProperty('checked', False)
                b.istoggled = False
                b.emit('toggled')
        self.check.setProperty('checked', True)
        self.istoggled = True
        RadioButton.running = False


class Misc(Widget):
    def __init__(self):
        Widget.__init__(self)
        self.xalign = 0.5
        self.yalign = 0.5

    def set_alignment(self, xalign, yalign):
        self.xalign = xalign
        self.yalign = yalign

    def get_alignment(self):
        return (self.xalign, self.yalign)


class Image(Misc):
    def __init__(self):
        Misc.__init__(self)
        self.img = browser.Element('img')
        self.img.setStyle('position', 'absolute')
        self.img.setStyle('width', 'auto')
        self.img.setStyle('height', 'auto')
        self.widget_cont.append(self.img)
        self.widget_cont.setProperty('className', 'image')

    def set_from_file(self, filename):
        self.img.setProperty('src', filename)

    def _redraw(self):
        Misc._redraw(self)
        self.img.setPxStyle('top', (self.widget_cont.getHeight() -
                                    self.img.getHeight()) * self.yalign)
        self.img.setPxStyle('left', (self.widget_cont.getWidth() -
                                     self.img.getWidth()) * self.xalign)
        self.minwidth = self.img.getWidth()
        self.minheight = self.img.getHeight()


class Label(Misc):
    def __init__(self, str=None):
        Misc.__init__(self)

        self.label = browser.Element('div')
        self.label.setStyle('position', 'absolute')
        self.label.setStyle('width', 'auto')
        self.label.setStyle('height', 'auto')
        self.label.setStyle('whiteSpace', 'nowrap')
        self.label.setHTML(str)

        self.widget_cont.append(self.label)
        self.widget_cont.setStyle('visibility', 'visible')
        self.widget_cont.setProperty('className', 'label')

    def set_text(self, str):
        self.label.setHTML(str)

    def get_text(self):
        return self.label.getHTML()

    def _redraw(self):
        Misc._redraw(self)
        self.label.setPxStyle('top', (self.widget_cont.getHeight() -
                                      self.label.getHeight()) * self.yalign)
        self.label.setPxStyle('left', (self.widget_cont.getWidth() -
                                       self.label.getWidth()) * self.xalign)
        self.minwidth = self.label.getWidth()
        self.minheight = self.label.getHeight()


class Separator(Widget):
    def __init__(self):
        Widget.__init__(self)


class HSeparator(Separator):
    def __init__(self):
        Separator.__init__(self)
        self.separator = browser.Element('hr')
        self.widget_cont.append(self.separator)
        self.widget_cont.setProperty('className', 'hseparator')
        self.minheight = 10


class Adjustment(Object):
    def __init__(self, value=0, lower=0, upper=0, step_incr=0, page_incr=0,
                 page_size=0):
        Object.__init__(self)
        self.value = value
        self.lower = lower
        self.upper = upper
        self.step_incr = step_incr
        self.page_incr = page_incr
        self.page_size = page_size

    def get_value(self):
        return self.value

    def set_value(self, value):
        self.value = value
        if self.value < self.lower:
            self.value = self.lower
        if self.value > self.upper:
            self.value = self.upper
        self.emit('value-changed')

    def changed(self):
        self.emit('changed')


class Range(Widget):
    def __init__(self, adjustment=None):
        Widget.__init__(self)
        self.value = browser.Element('div')
        self.value.setStyle('position', 'absolute')
        self.widget_cont.append(self.value)
        if adjustment is not None:
            self.adjustment = adjustment
        else:
            self.adjustment = Adjustment()
        self.adjustment.connect('value-changed', self._adjustment_value_changed)
        self.adjustment.connect('changed', self._adjustment_changed)
        self.value.setHTML(str(self.adjustment.get_value()))

    def set_update_policy(self, policy):
        pass

    def _adjustment_value_changed(self, sender):
        self.value.setHTML(str(self.adjustment.get_value()))

    def _adjustment_changed(self):
        self._redraw()


class Scale(Range):
    def __init__(self, adjustment=None):
        Range.__init__(self, adjustment)
        self.line = browser.Element('div')
        self.line.setStyle('position', 'absolute')
        self.line.setProperty('className', 'scale')
        self.line.catchEvents(['click'], self)
        self.cursor = browser.Element('div')
        self.cursor.setStyle('position', 'absolute')
        self.cursor.setProperty('className', 'scale-cursor')
        self.widget_cont.append(self.line)
        self.mouseover = False
        self.value_pos = POS_TOP
        self.draw_value = True
        self.digits = 1
        self.cursor.catchEvents(['mousedown'], self)
        browser.Document.document.catchEvents(['mousemove'], self)
        browser.Document.document.catchEvents(['mouseup'], self)

    def set_digits(self, digits):
        self.digits = digits
        self._redraw()

    def set_draw_value(self, draw_value):
        self.draw_value = draw_value
        self._redraw()

    def get_draw_value(self):
        return self.draw_value

    def set_value_pos(self, pos):
        self.value_pos = pos
        self._redraw()

    def get_value_pos(self):
        return self.value_pos

    def _adjustment_value_changed(self, sender):
        value = self.adjustment.get_value()
        value = browser.round_val(value, self.digits)
        self.value.setHTML(str(value))

    def _move_cursor(self, event):
        pass

    def dom_event(self, event, element):
        if event.type == 'mousedown':
            self.mouseover = True
        elif event.type == 'mousemove' and self.mouseover:
            self._move_cursor(event)
        elif event.type == 'click':
            self._move_cursor(event)
        elif event.type == 'mouseup':
            self.mouseover = False


class VScale(Scale):
    def __init__(self, adjustment=None):
        Scale.__init__(self, adjustment)
        self.line.setPxStyle('width', 15)
        self.cursor.setPxStyle('height', 30)
        self.cursor.setPxStyle('width', 13)
        self.line.append(self.cursor)
        self.minwidth = 30
        self.minheight = 60

    def _redraw(self):
        Scale._redraw(self)
        # define shortcuts
        container = self.widget_cont
        line = self.line
        value = self.value
        # geometric properties
        container_width = container.getWidth()
        container_height = container.getHeight()
        line_width = self.line.getWidth()
        value_width = self.value.getWidth()
        value_height = self.value.getHeight()
        if not self.draw_value:
            line.setPxStyle('left', (container_width - line_width) / 2)
            line.setPxStyle('top', 0)
            line.setPxStyle('height', container_height - 2)
            value.setStyle('visibility', 'hidden')
        else:
            value.setStyle('visibility', 'visible')
            if self.value_pos == POS_TOP:
                value.setPxStyle('left', (container_width - value_width) / 2)
                value.setPxStyle('top', 0)
                line.setPxStyle('left', (container_width - line_width) / 2)
                line.setPxStyle('top', value_height + 2)
                line.setPxStyle('height', container_height - value_height - 4)
            elif self.value_pos == POS_LEFT:
                value.setPxStyle('left', container_width / 2 -
                                         (value_width + line_width) / 2)
                line.setPxStyle('left', container_width / 2 +
                                        (value_width + line_width) / 2)
                line.setPxStyle('top', 0)
                line.setPxStyle('height', container_height - 2)
            elif self.value_pos == POS_RIGHT:
                value.setPxStyle('left', container_width / 2 +
                                         (value_width + line_width) / 2)
                line.setPxStyle('left', container_width / 2 -
                                        (value_width + line_width) / 2)
                line.setPxStyle('top', 0)
                line.setPxStyle('height', container_height - 2)
            else:
                value.setPxStyle('left', (container_width - value_width) / 2)
                value.setPxStyle('top', container_height - value_height)
                line.setPxStyle('left', (container_width - line_width) / 2)
                line.setPxStyle('top', 0)
                line.setPxStyle('height', container_height - value_height - 4)
        self._adjustment_value_changed(self)

    def _move_cursor(self, event):
        Scale._move_cursor(self, event)
        y = event.clientY - self.line.getY() - self.cursor.getHeight() / 2
        y = max(y, 0)
        y = min(y, self.line.getHeight() - self.cursor.getHeight() - 2)

        value = (y / (self.line.getHeight() - self.cursor.getHeight() - 2)) * \
                (self.adjustment.upper - self.adjustment.page_size)
        if self.draw_value:
            value = round(value, self.digits)
        if event.type == 'click':
            old_value = self.adjustment.get_value()
            incr = self.adjustment.page_incr
            if value > old_value:
                self.adjustment.set_value(old_value + incr)
            elif value < old_value:
                self.adjustment.set_value(old_value - incr)
        else:
            self.adjustment.set_value(value)

    def _adjustment_value_changed(self, sender):
        Scale._adjustment_value_changed(self, self)
        value = self.adjustment.get_value()
        if self.draw_value:
            value = round(value, self.digits)
        y = (value - self.adjustment.lower) / \
            (self.adjustment.upper - self.adjustment.page_size) * \
            (self.line.getHeight() - self.cursor.getHeight() - 2)
        self.cursor.setPxStyle('top', y)
        if self.value_pos in (POS_LEFT, POS_RIGHT):
            pos = y - self.value.getHeight() / 2 + self.cursor.getHeight() / 2
            self.value.setPxStyle('top', pos)


class HScale(Scale):
    def __init__(self, adjustment=None):
        Scale.__init__(self, adjustment)
        self.line.setPxStyle('height', 15)
        self.cursor.setPxStyle('height', 13)
        self.cursor.setPxStyle('width', 30)
        self.line.append(self.cursor)
        self.minwidth = 60
        self.minheight = 37

    def _redraw(self):
        Scale._redraw(self)
        # define shortcuts
        container = self.widget_cont
        line = self.line
        value = self.value
        # geometric properties
        container_width = container.getWidth()
        container_height = container.getHeight()
        line_width = self.line.getWidth()
        line_height = self.line.getHeight()
        value_width = self.value.getWidth()
        value_height = self.value.getHeight()
        if not self.draw_value:
            line.setPxStyle('top', (container_height - line_height) / 2)
            line.setPxStyle('width', container_width - 2)
            value.setStyle('visibility', 'hidden')
        else:
            self.value.setStyle('visibility', 'visible')
            if self.value_pos == POS_TOP:
                value.setPxStyle('top', container_height / 2 -
                                        (line_height + value_height + 2) / 2)
                line.setPxStyle('left', 0)
                line.setPxStyle('top', container_height / 2 + line_height / 2 -
                                       value_height / 2 + 1)
                line.setPxStyle('width', container_width - 2)
            elif self.value_pos == POS_LEFT:
                value.setPxStyle('left', 0)
                value.setPxStyle('top', (container_height - value_height) / 2)
                line.setPxStyle('left', value_width + 2)
                line.setPxStyle('top', (container_height - line_height) / 2)
                line.setPxStyle('width', container_width - (value_width+2) - 2)
            elif self.value_pos == POS_RIGHT:
                value.setPxStyle('left', container_width - value_width)
                value.setPxStyle('top', (container_height - value_height) / 2)
                line.setPxStyle('left', 0)
                line.setPxStyle('top', (container_height - line_height) / 2)
                line.setPxStyle('width', container_width - (value_width+2) - 2)
            else:
                value.setPxStyle('top', container_height / 2 + line_height / 2 -
                                        value_height / 2 + 1)
                line.setPxStyle('left', 0)
                line.setPxStyle('top', container_height / 2 -
                                       (line_height + value_height + 2) / 2)
                line.setPxStyle('width', container_width - 2)
        self._adjustment_value_changed(self)

    def _move_cursor(self, event):
        Scale._move_cursor(self, event)
        x = event.clientX - self.line.getX() - self.cursor.getWidth() / 2

        x = max(x, 0)
        x = min(x, self.line.getWidth() - self.cursor.getWidth() - 2)

        value = (x / (self.line.getWidth() - self.cursor.getWidth() - 2)) * \
                (self.adjustment.upper - self.adjustment.page_size)
        if self.draw_value:
            value = round(value, self.digits)
        if event.type == 'click':
            old_value = self.adjustment.get_value()
            incr = self.adjustment.page_incr
            if value > old_value:
                self.adjustment.set_value(old_value + incr)
            elif value < old_value:
                self.adjustment.set_value(old_value - incr)
        else:
            self.adjustment.set_value(value)

    def _adjustment_value_changed(self, sender):
        Scale._adjustment_value_changed(self, self)
        value = self.adjustment.get_value()
        if self.draw_value:
            value = round(value, self.digits)
        x = (value - self.adjustment.lower) / \
            (self.adjustment.upper - self.adjustment.page_size) * \
            (self.line.getWidth() - self.cursor.getWidth() - 2)
        self.cursor.setPxStyle('left', x)
        if self.value_pos in (POS_TOP, POS_BOTTOM):
            pos = x - self.value.getWidth() / 2 + self.cursor.getWidth() / 2
            pos = max(pos, 0)
            pos = min(pos, self.line.getWidth() - self.value.getWidth())
            self.value.setPxStyle('left', pos)


class Scrollbar(Range):
    def __init__(self, adjustment=None):
        Range.__init__(self, adjustment)
        # assign instance variables
        self.down_arrow = browser.Element('div')
        self.up_arrow = browser.Element('div')
        # shortcuts
        down_arrow = self.down_arrow
        up_arrow = self.up_arrow
        # use them
        down_arrow.setStyle('position', 'absolute')
        down_arrow.setPxStyle('height', 15)
        down_arrow.setPxStyle('width', 15)
        down_arrow.catchEvents(['click'], self)
        up_arrow.setStyle('position', 'absolute')
        up_arrow.setPxStyle('height', 15)
        up_arrow.setPxStyle('width', 15)
        up_arrow.catchEvents(['click'], self)
        self.line = browser.Element('div')
        self.line.setStyle('position', 'absolute')
        self.line.setProperty('className', 'scrollbar')
        self.line.catchEvents(['click'], self)
        self.cursor = browser.Element('div')
        self.cursor.setStyle('position', 'absolute')
        self.cursor.setProperty('className', 'scrollbar-cursor')
        self.widget_cont.append(down_arrow)
        self.widget_cont.append(self.line)
        self.widget_cont.append(up_arrow)
        self.mouseover = False
        self.cursor.catchEvents(['mousedown'], self)
        self.value.setStyle('visibility', 'hidden')
        browser.Document.document.catchEvents(['mousemove'], self)
        browser.Document.document.catchEvents(['mouseup'], self)

    def _adjustment_value_changed(self, sender):
        pass

    def _move_cursor(self, event):
        pass

    def dom_event(self, event, element):
        if event.type == 'mousedown':
            self.mouseover = True
        elif event.type == 'mousemove' and self.mouseover:
            self._move_cursor(event)
        elif event.type == 'click':
            self._move_cursor(event)
        elif event.type == 'mouseup':
            self.mouseover = False


class HScrollbar(Scrollbar):
    def __init__(self, adjustment=None):
        Scrollbar.__init__(self, adjustment)
        self.down_arrow.setProperty('className', 'scrollbar-left-arrow')
        self.up_arrow.setProperty('className', 'scrollbar-right-arrow')
        self.line.setPxStyle('height', 15)
        self.cursor.setPxStyle('height', 13)
        self.line.append(self.cursor)
        self.minwidth = 60
        self.minheight = 37

    def _redraw(self):
        Scrollbar._redraw(self)
        top = (self.widget_cont.getHeight() - self.line.getHeight()) / 2
        self.down_arrow.setPxStyle('top', top)
        self.down_arrow.setPxStyle('left', 0)
        self.line.setPxStyle('top', top)
        self.line.setPxStyle('left', self.down_arrow.getWidth())
        self.line.setPxStyle('width', self.widget_cont.getWidth() - 2 -
                                      self.down_arrow.getWidth() -
                                      self.up_arrow.getWidth())
        self.up_arrow.setPxStyle('top', top)
        self.up_arrow.setPxStyle('left', self.down_arrow.getWidth() +
                                         self.line.getWidth())

        cursor_size = (self.widget_cont.getWidth() - 2) * \
                      self.adjustment.page_size / 100.0
        cursor_size = max(cursor_size, 30)
        self.cursor.setPxStyle('width', cursor_size)
        self._adjustment_value_changed(self)

    def _move_cursor(self, event):
        Scrollbar._move_cursor(self, event)
        pos = event.clientX - self.line.getX()

        x = pos - self.cursor.getWidth() / 2
        x = max(x, 0)
        x = min(x, self.line.getWidth() - self.cursor.getWidth() - 2)

        value = (x / (self.line.getWidth() - self.cursor.getWidth() - 2)) * \
                (self.adjustment.upper - self.adjustment.page_size)
        if event.type == 'click':
            old_value = self.adjustment.get_value()
            if pos < 0:
                incr = self.adjustment.step_incr
                self.adjustment.set_value(old_value - incr)
            elif pos > self.line.getWidth():
                incr = self.adjustment.step_incr
                self.adjustment.set_value(old_value + incr)
            else:
                incr = self.adjustment.page_incr
                if value > old_value:
                    self.adjustment.set_value(old_value + incr)
                elif value < old_value:
                    self.adjustment.set_value(old_value - incr)
        else:
            self.adjustment.set_value(value)

    def _adjustment_value_changed(self, sender):
        Scrollbar._adjustment_value_changed(self, self)
        value = self.adjustment.get_value()
        x = (value - self.adjustment.lower) / \
            (self.adjustment.upper - self.adjustment.page_size) * \
            (self.line.getWidth() - self.cursor.getWidth() - 2)
        self.cursor.setPxStyle('left', x)


class VScrollbar(Scrollbar):
    def __init__(self, adjustment=None):
        Scrollbar.__init__(self, adjustment)
        self.down_arrow.setProperty('className', 'scrollbar-down-arrow')
        self.up_arrow.setProperty('className', 'scrollbar-up-arrow')
        self.line.setPxStyle('width', 15)
        self.cursor.setPxStyle('width', 13)
        self.line.append(self.cursor)
        self.minwidth = 30
        self.minheight = 90

    def _redraw(self):
        Scrollbar._redraw(self)
        left = (self.widget_cont.getWidth() - self.line.getWidth()) / 2
        self.up_arrow.setPxStyle('left', left)
        self.up_arrow.setPxStyle('top', 0)
        self.line.setPxStyle('top', self.up_arrow.getHeight())
        self.line.setPxStyle('left', left)
        self.line.setPxStyle('height', self.widget_cont.getHeight() - 2 -
                                       self.up_arrow.getHeight() -
                                       self.down_arrow.getHeight())
        self.down_arrow.setPxStyle('top', self.up_arrow.getHeight() +
                                          self.line.getHeight())
        self.down_arrow.setPxStyle('left', left)

        cursor_size = (self.widget_cont.getHeight() - 2) * \
                      self.adjustment.page_size / 100.0
        cursor_size = max(cursor_size, 30)
        self.cursor.setPxStyle('height', cursor_size)
        self._adjustment_value_changed(self)

    def _move_cursor(self, event):
        Scrollbar._move_cursor(self, event)
        pos = event.clientY - self.line.getY()

        y = pos - self.cursor.getHeight() / 2
        y = max(y, 0)
        y = min(y, self.line.getHeight() - self.cursor.getHeight() - 2)

        value = (y / (self.line.getHeight() - self.cursor.getHeight() - 2)) * \
                (self.adjustment.upper - self.adjustment.page_size)
        if event.type == 'click':
            old_value = self.adjustment.get_value()
            if pos < 0:
                incr = self.adjustment.step_incr
                self.adjustment.set_value(old_value - incr)
            elif pos > self.line.getHeight():
                incr = self.adjustment.step_incr
                self.adjustment.set_value(old_value + incr)
            else:
                incr = self.adjustment.page_incr
                if value > old_value:
                    self.adjustment.set_value(old_value + incr)
                elif value < old_value:
                    self.adjustment.set_value(old_value - incr)
        else:
            self.adjustment.set_value(value)

    def _adjustment_value_changed(self, sender):
        Scrollbar._adjustment_value_changed(self)
        value = self.adjustment.get_value()
        y = (value - self.adjustment.lower) / \
            (self.adjustment.upper - self.adjustment.page_size) * \
            (self.line.getHeight() - self.cursor.getHeight() - 2)
        self.cursor.setPxStyle('top', y)


class OptionMenu(Button):
    def __init__(self):
        Button.__init__(self)
        self.ico = browser.Element('img')
        self.ico.setProperty('src', 'arr.png')
        self.ico.setStyle('position','absolute')
        self.ico.setPxStyle('right', 2)
        self.widget_int.append(self.ico)
        self.connect('clicked', self._clicked, None)
        self.menu = None
        self.menu_open = False
        self.label = Label('')
        self.label.set_alignment(0, 0.5)
        self.add(self.label)

    def _redraw(self):
        Button._redraw(self)
        rect = self.get_allocation()
        pad = rect.height / 2 - self.ico.getHeight() / 2
        self.ico.setPxStyle('top', pad)

    def _clicked(self, elem, data=None):
        self.menu_open = not self.menu_open
        if not self.menu._visible:
            rect = self.get_allocation()
            self.menu.widget_cont.setPxStyle('left', rect.x)
            self.menu.widget_cont.setPxStyle('top', rect.y + rect.height)
            self.menu.show_all()
        else:
            self.menu.hide_all()

    def _selected(self, elem, data=None):
        act = self.menu.get_active()
        if act is not None:
            self.label.set_text(act.label_cont)

    def set_menu(self, menu):
        self.label.set_text(menu.items[0].label_cont)
        self.menu = menu
        self.menu.connect('selection-done', self._selected, None)


class MenuShell(Container):
    def __init__(self):
        Container.__init__(self)
        self.items = []
        container = self.widget_cont
        container.setStyle('border','1px solid gray')
        container.setStyle('position', 'absolute')
        container.setStyle('width', 'auto')
        container.setStyle('height', '')
        container.setStyle('left', '')
        container.setStyle('right', '')
        container.setStyle('bottom', '')
        container.setStyle('top', '')
        container.setStyle('zIndex', '100')
        self.widget_int = self.widget_cont
        self.widget_int.setStyle('position', 'absolute')
        container.setProperty('className', 'menushell')
        self.hide()
        browser.Document.append(self.widget_cont)

    def append(self, child):
        child.hide()
        child.connect('select', self._selected, None)
        self.items.append(child)
        self.add(child)

    def _selected(self, elem, data=None):
        self.emit('selection-done')
        self.hide_all()

    def _redraw(self):
        Container._redraw(self)
        for child in self.children:
            self.minwidth = max(self.minwidth, child.minwidth)
            self.minheight += child.minheight
        self.widget_cont.setPxStyle('minHeight', self.minheight)
        self.widget_cont.setPxStyle('minWidth', self.minwidth)


class Menu(MenuShell):
    def append(self, child):
        child.connect('select', self._catch_active, None)
        MenuShell.append(self, child)
        self._active = None

    def _catch_active(self, elem, data=None):
        self._active = elem

    def get_active(self):
        return self._active


class Item(Bin):
    def __init__(self, name):
        Bin.__init__(self)
        self.label_cont = name
        container = self.widget_cont
        container.catchEvents(['click'], self)
        container.setStyle('position', '')
        container.setStyle('width', '100%')
        container.setStyle('bottom', '')
        container.setStyle('top', '')
        self.widget_int.setStyle('position', 'absolute')
        self.widget_int = self.widget_cont
        container.setProperty('className', 'menuitem')

        self.content = Label(name)
        self.content.hide()
        self.add(self.content)

    def dom_event(self, event, element):
        if event.type == 'click':
            self.emit('select')
            self.emit('toggle')

    def show(self):
        Bin.show(self)
        self.content.show()

    def hide(self):
        Bin.hide(self)
        self.content.hide()

    def _redraw(self):
        Bin._redraw(self)
        self.widget_cont.setPercentStyle('width', 100)


class MenuItem(Item):
    def dom_event(self, event, element):
        Item.dom_event(self, event, element)
        if event.type == 'click':
            self.emit('activate')

gtkbuildermap = {
          'GtkWindow': Window,
          'GtkTable': Table,
          'GtkLabel': Label,
          'GtkVBox': VBox,
          'GtkHBox': HBox,
          'GtkEntry': Entry
          }


def find_props(node):
    res = {}
    if not node:
        return {}
    props = node.getElementsByTagName("property")
    for i in range(props.length):
        n = props.item(n)
        name = n.attributes.getNamedItem('name').nodeValue
        log.write("find_props ")
        log.write(name)
        log.write(" ")
        log.write(n.textContent)
        log.writebr("")
        res[name] = n.textContent
    return res


class BuilderETree:
    def __init__(self):
        self.objects = []

    def create_object_from_xml_node(self, node):
        klsname = node.attrib['class']
        id = node.attrib['id']
        obj = gtkmap[klsname]()
        for prop in node.findall("property"):
            name = prop.attrib['name']
            value = prop.textContent
            try:
                setattr(obj.props, name, value)
            # XXX except without a specified exception is bad style
            # most of the time, perhaps use an AttributeError here?
            except:
                if value.isdigit():
                    setattr(obj.props, name, int(value))
                else:
                    print "setattr failed", klsname, name, value
        for childnode in node.findall("child"):
            childobj = childnode.find("object")
            if childobj is None:
                continue
            child = self.create_object_from_xml_node(childobj)
            obj.add_child(Builder(), child, klsname)
            props = find_props(childnode.find("packing"))
            for prop, value in props.items():
                if value.isdigit():
                    value = int(value)
                obj.child_set_property(child, prop, value)
            print props
        return obj

    def add_from_file(self, fname):
        s = open(fname).read()
        return s.add_from_string(s)

    def add_from_string(self, f):
        s = open(fname).read() # whoops don't expect this to work in pyjamas!
        doc = lxml.etree.fromstring(s)
        for x in doc:
            if x.tag != 'object':
                continue
            obj = self.create_object_from_xml_node(x)
            self.objects.append(obj)

    def get_objects(self):
        return self.objects


gtkmap = {'GtkWindow': Window,
          'GtkTable': Table,
          'GtkLabel': Label,
          'GtkVBox': VBox,
          'GtkHBox': HBox,
          'GtkEntry': Entry
         }


class Builder:
    def __init__(self):
        self.objects = []

    def create_object_from_xml_node(self, node):
        klsname = node.attributes.getNamedItem('class').nodeValue
        # XXX shadowing builtin id
        id = node.attributes.getNamedItem('id').nodeValue
        log.writebr("%s %s" % (klsname, id))
        obj = gtkmap[klsname]()
        props = node.getElementsByTagName("property")
        log.writebr("%s %d" % (klsname, props.length))
        for i in range(props.length):
            prop = props.item(i)
            name = prop.attributes.getNamedItem('name').nodeValue
            value = prop.textContent
            try:
                setattr(obj, name, value)
            # XXX missing exception class, should probably be AttributeError
            except:
                if value and value.isdigit():
                    setattr(obj, name, int(value))
                else:
                    print "setattr failed", klsname, name, value
        childnodes = node.getElementsByTagName("child")
        log.writebr("%s children %d" % (klsname, childnodes.length))
        for i in range(childnodes.length):
            childnode = childnodes.item(i)
            childobj = childnode.getElementsByTagName("object")
            if childobj is None:
                continue
            if childobj.length == 0:
                continue
            childobj = childobj.item(0)
            child = self.create_object_from_xml_node(childobj)
            #obj.add_child(gtk.Builder(), child, klsname)
            obj.add(child)
            packing = childnode.getElementsByTagName("packing")
            if packing is None:
                continue
            if packing.length == 0:
                continue
            packing = packing.item(0)
            props = find_props(packing)
            for prop, value in props.items():
                if value.isdigit():
                    value = int(value)
                obj.child_set_property(child, prop, value)
        return obj

    def add_from_file(self, fname):
        fobj = open(fname)
        try:
            s = fobj.read()
        finally:
            fobj.close()
        return s.add_from_string(s)

    def add_from_string(self, xmldoc):
        x = xmldoc.firstChild.firstChild
        while x:
            log.writebr(x.nodeName)
            if x.nodeName == 'object':
                log.writebr("creating object")
                obj = self.create_object_from_xml_node(x)
                self.objects.append(obj)
            x = x.nextSibling

    def get_objects(self):
        return self.objects


def main():
    pass

def main_quit():
    #TODO: In popups, close it !
    browser.Document.setContent('This application has finalized !')

www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.