예제 #1
0
class Widget(gvent.GventReceiver):
    logger = logging.getLogger("GyUI.Widget")

    font = FontProperty('font')
    fg_color = ThemeProperty('fg_color')
    bg_color = ThemeProperty('bg_color')
    bg_image = ThemeProperty('bg_image')
    scale_bg = ThemeProperty('scale_bg')
    border_width = ThemeProperty('border_width')
    border_color = ThemeProperty('border_color')
    sel_color = ThemeProperty('sel_color')
    margin = ThemeProperty('margin')
    menu_bar = overridable_property('menu_bar')
    is_gl_container = overridable_property('is_gl_container')

    # rect properties accesses
    left = rect_property('left')
    right = rect_property('right')
    top = rect_property('top')
    bottom = rect_property('bottom')
    width = rect_property('width')
    height = rect_property('height')
    size = rect_property('size')
    topleft = rect_property('topleft')
    topright = rect_property('topright')
    bottomleft = rect_property('bottomleft')
    bottomright = rect_property('bottomright')
    midleft = rect_property('midleft')
    midright = rect_property('midright')
    midtop = rect_property('midtop')
    midbottom = rect_property('midbottom')
    center = rect_property('center')
    centerx = rect_property('centerx')
    centery = rect_property('centery')

    # local_rect properties accesses
    local_left = local_rect_property('left')
    local_right = local_rect_property('right')
    local_top = local_rect_property('top')
    local_bottom = local_rect_property('bottom')
    local_width = local_rect_property('width')
    local_height = local_rect_property('height')
    local_size = local_rect_property('size')
    local_topleft = local_rect_property('topleft')
    local_topright = local_rect_property('topright')
    local_bottomleft = local_rect_property('bottomleft')
    local_bottomright = local_rect_property('bottomright')
    local_midleft = local_rect_property('midleft')
    local_midright = local_rect_property('midright')
    local_midtop = local_rect_property('midtop')
    local_midbottom = local_rect_property('midbottom')
    local_center = local_rect_property('center')
    local_centerx = local_rect_property('centerx')
    local_centery = local_rect_property('centery')

    def __init__(self, rect=None):
        '''
        Constructor for Widget
        '''
        gvent.GventReceiver.__init__(self)

        self.dirty = 1
        self.parent = None
        if rect is None:
            self._rect = pygame.Rect((0, 0), (100, 100))
        elif rect:
            self._rect = pygame.Rect(rect)


#            self._rect = rect
        self._local_rect = pygame.Rect((0, 0), (100, 100))

    def get_rect(self):
        '''
        Getter for rect property
        '''
        return self._rect

    def set_rect(self, rect):
        '''
        Setter for rect property
        '''
        old_rect = self._rect
        self._rect = pygame.Rect(rect)
        self._rect_global_to_local()
        self._moved(old_rect.topleft)
        self._resized(old_rect.size)

    rect = property(get_rect, set_rect)

    def get_local_rect(self):
        '''
        Getter for local_rect property
        '''
        return self._local_rect

    def set_local_rect(self, rect):
        '''
        Setter for local_rect property
        '''
        old_rect = self._local_rect
        self._local_rect = pygame.Rect(rect)
        self._rect_local_to_global()
        self._moved(old_rect.topleft)
        self._resized(old_rect.size)

    local_rect = property(get_local_rect, set_local_rect)

    def _rect_global_to_local(self):
        '''
        Set local rect from global rect
        '''
        if self.parent:
            move_by = (self.parent.left * -1, self.parent.top * -1)
            self._local_rect = self._rect.move(move_by)
        else:
            self._local_rect = self._rect
        print self, "new local_rect:", self._local_rect

    def _rect_local_to_global(self):
        '''
        Set global rect from local rect
        '''
        if self.parent:
            self._rect = self._local_rect.move(self.parent.topleft)
        else:
            self._rect = self._local_rect

    def _resized(self, old_size):
        '''
        Inform widget that it's size has changed
        '''
        if self._rect.size != tuple(old_size):
            # new size is different
            pass

    def _moved(self, old_pos):
        if self._rect.topleft != tuple(old_pos):
            # new pos is actually different
            self.set_dirty()

    def _parent_moved(self, old_pos):
        # recalculate local rect with new parent position
        self._rect_local_to_global()

    def _set_parent(self, parent):
        self.parent = parent
        #        self._parent_resized(None)
        self._parent_moved(None)

    def get_widget_at(self, pos):
        '''
        Get widged at that (global) position
        
        This is mainly useful as recursion end from Bin widgets 
        '''
        return self

    def _draw(self, surface):
        '''
        Execute actual draw of this very widget
        '''
        pygame.draw.rect(surface, (0xff, 0, 0), self.rect)

    def draw(self, surface):
        '''
        '''
        self._draw(surface)

    def set_dirty(self):
        '''
        Set this widget to be redrawn next draw
        '''
        if not self.dirty:
            self.dirty = 1

    def set_dirty_all(self):
        self.set_dirty()
예제 #2
0
class Widget(object):
    #  rect            Rect       bounds in parent's coordinates
    #  parent          Widget     containing widget
    #  subwidgets      [Widget]   contained widgets
    #  focus_switch    Widget     subwidget to receive key events
    #  fg_color        color      or None to inherit from parent
    #  bg_color        color      to fill background, or None
    #  visible         boolean
    #  border_width    int        width of border to draw around widget, or None
    #  border_color    color      or None to use widget foreground color
    #  tab_stop        boolean    stop on this widget when tabbing
    #  anchor          string     of 'ltrb'

    font = FontProperty('font')
    fg_color = ThemeProperty('fg_color')
    bg_color = ThemeProperty('bg_color')
    bg_image = ThemeProperty('bg_image')
    scale_bg = ThemeProperty('scale_bg')
    border_width = ThemeProperty('border_width')
    border_color = ThemeProperty('border_color')
    sel_color = ThemeProperty('sel_color')
    margin = ThemeProperty('margin')
    menu_bar = overridable_property('menu_bar')
    is_gl_container = overridable_property('is_gl_container')

    tab_stop = False
    enter_response = None
    cancel_response = None
    anchor = 'ltwh'
    debug_resize = False
    _menubar = None
    _visible = True
    _is_gl_container = False
    redraw_every_event = True

    tooltip = None
    tooltipText = None
    doNotTranslate = False

    def __init__(self, rect=None, **kwds):
        if rect and not isinstance(rect, Rect):
            raise TypeError("Widget rect not a pygame.Rect")
        self._rect = Rect(rect or (0, 0, 100, 100))
        self.parent = None
        self.subwidgets = []
        self.focus_switch = None
        self.is_modal = False
        self.set(**kwds)
        self.root = self.get_root()

    def set(self, **kwds):
        for name, value in kwds.iteritems():
            if not hasattr(self, name):
                raise TypeError("Unexpected keyword argument '%s'" % name)
            setattr(self, name, value)

    def get_rect(self):
        return self._rect

    def set_rect(self, x):
        old_size = self._rect.size
        self._rect = Rect(x)
        self._resized(old_size)

    #    def get_anchor(self):
    #        if self.hstretch:
    #            chars ='lr'
    #        elif self.hmove:
    #            chars = 'r'
    #        else:
    #            chars = 'l'
    #        if self.vstretch:
    #            chars += 'tb'
    #        elif self.vmove:
    #            chars += 'b'
    #        else:
    #            chars += 't'
    #        return chars
    #
    #    def set_anchor(self, chars):
    #        self.hmove = 'r' in chars and not 'l' in chars
    #        self.vmove = 'b' in chars and not 't' in chars
    #        self.hstretch = 'r' in chars and 'l' in chars
    #        self.vstretch = 'b' in chars and 't' in chars
    #
    #    anchor = property(get_anchor, set_anchor)

    resizing_axes = {'h': 'lr', 'v': 'tb'}
    resizing_values = {'': [0], 'm': [1], 's': [0, 1]}

    def set_resizing(self, axis, value):
        chars = self.resizing_axes[axis]
        anchor = self.anchor
        for c in chars:
            anchor = anchor.replace(c, '')
        for i in self.resizing_values[value]:
            anchor += chars[i]
        self.anchor = anchor + value

    def _resized(self, (old_width, old_height)):
        new_width, new_height = self._rect.size
        dw = new_width - old_width
        dh = new_height - old_height
        if dw or dh:
            self.resized(dw, dh)
예제 #3
0
class TextScreen(Screen):

    #    bg_color = (0, 0, 0)
    #    fg_color = (255, 255, 255)
    #    border = 20

    heading_font = FontProperty('heading_font')
    button_font = FontProperty('button_font')

    def __init__(self, shell, filename, **kwds):
        text = get_text(filename)
        text_pages = text.split("\nPAGE\n")
        pages = []
        page_size = (0, 0)
        for text_page in text_pages:
            lines = text_page.strip().split("\n")
            page = Page(self, lines[0], lines[1:])
            pages.append(page)
            page_size = maximum(page_size, page.size)
        self.pages = pages
        bf = self.button_font
        b1 = Button("Prev Page", font=bf, action=self.prev_page)
        b2 = Button("Menu", font=bf, action=self.go_back)
        b3 = Button("Next Page", font=bf, action=self.next_page)
        b = self.margin
        page_rect = Rect((b, b), page_size)
        gap = (0, 18)
        b1.topleft = add(page_rect.bottomleft, gap)
        b2.midtop = add(page_rect.midbottom, gap)
        b3.topright = add(page_rect.bottomright, gap)
        Screen.__init__(self, shell, **kwds)
        self.size = add(b3.bottomright, (b, b))
        self.add(b1)
        self.add(b2)
        self.add(b3)
        self.prev_button = b1
        self.next_button = b3
        self.set_current_page(0)

    def draw(self, surface):
        b = self.margin
        self.pages[self.current_page].draw(surface, self.fg_color, (b, b))

    def at_first_page(self):
        return self.current_page == 0

    def at_last_page(self):
        return self.current_page == len(self.pages) - 1

    def set_current_page(self, n):
        self.current_page = n
        self.prev_button.enabled = not self.at_first_page()
        self.next_button.enabled = not self.at_last_page()

    def prev_page(self):
        if not self.at_first_page():
            self.set_current_page(self.current_page - 1)

    def next_page(self):
        if not self.at_last_page():
            self.set_current_page(self.current_page + 1)

    def go_back(self):
        self.parent.show_menu()
예제 #4
0
class TabPanel(Widget):
    #  pages         [Widget]
    #  current_page  Widget

    tab_font = FontProperty('tab_font')
    tab_height = ThemeProperty('tab_height')
    tab_border_width = ThemeProperty('tab_border_width')
    tab_spacing = ThemeProperty('tab_spacing')
    tab_margin = ThemeProperty('tab_margin')
    tab_fg_color = ThemeProperty('tab_fg_color')
    default_tab_bg_color = ThemeProperty('default_tab_bg_color')
    tab_area_bg_color = ThemeProperty('tab_area_bg_color')
    tab_dimming = ThemeProperty('tab_dimming')
    tab_titles = None

    #use_page_bg_color_for_tabs = ThemeProperty('use_page_bg_color_for_tabs')

    def __init__(self, pages=None, **kwds):
        Widget.__init__(self, **kwds)
        self.pages = []
        self.current_page = None
        if pages:
            w = h = 0
            for title, page in pages:
                w = max(w, page.width)
                h = max(h, page.height)
                self._add_page(title, page)
            self.size = (w, h)
            self.show_page(pages[0][1])

    def content_size(self):
        return self.width, self.height - self.tab_height

    def content_rect(self):
        return Rect((0, self.tab_height), self.content_size())

    def page_height(self):
        return self.height - self.tab_height

    def add_page(self, title, page):
        self._add_page(title, page)
        if not self.current_page:
            self.show_page(page)

    def _add_page(self, title, page):
        page.tab_title = _(title)
        page.anchor = 'ltrb'
        self.pages.append(page)

    def remove_page(self, page):
        try:
            i = self.pages.index(page)
            del self.pages[i]
        except IndexError:
            pass
        if page is self.current_page:
            self.show_page(None)

    def show_page(self, page):
        if self.current_page:
            self.remove(self.current_page)
        self.current_page = page
        if page:
            th = self.tab_height
            page.rect = Rect(0, th, self.width, self.height - th)
            self.add(page)
            page.focus()

    def draw(self, surf):
        self.draw_tab_area_bg(surf)
        self.draw_tabs(surf)

    def draw_tab_area_bg(self, surf):
        bg = self.tab_area_bg_color
        if bg:
            surf.fill(bg, (0, 0, self.width, self.tab_height))

    def draw_tabs(self, surf):
        font = self.tab_font
        fg = self.tab_fg_color
        b = self.tab_border_width
        if b:
            surf.fill(fg, (0, self.tab_height - b, self.width, b))
        for i, title, page, selected, rect in self.iter_tabs():
            x0 = rect.left
            w = rect.width
            h = rect.height
            r = rect
            if not selected:
                r = Rect(r)
                r.bottom -= b
            self.draw_tab_bg(surf, page, selected, r)
            if b:
                surf.fill(fg, (x0, 0, b, h))
                surf.fill(fg, (x0 + b, 0, w - 2 * b, b))
                surf.fill(fg, (x0 + w - b, 0, b, h))
            buf = font.render(title, True, page.fg_color or fg)
            r = buf.get_rect()
            r.center = (x0 + w // 2, h // 2)
            surf.blit(buf, r)

    def iter_tabs(self):
        pages = self.pages
        current_page = self.current_page
        n = len(pages)
        b = self.tab_border_width
        s = self.tab_spacing
        h = self.tab_height
        m = self.tab_margin
        width = self.width - 2 * m + s - b
        x0 = m
        for i, page in enumerate(pages):
            x1 = m + (i + 1) * width // n  # self.tab_boundary(i + 1)
            selected = page is current_page
            yield i, page.tab_title, page, selected, Rect(
                x0, 0, x1 - x0 - s + b, h)
            x0 = x1

    def draw_tab_bg(self, surf, page, selected, rect):
        bg = self.tab_bg_color_for_page(page)
        if not selected:
            bg = brighten(bg, self.tab_dimming)
        surf.fill(bg, rect)

    def tab_bg_color_for_page(self, page):
        return getattr(page, 'tab_bg_color', None) \
               or page.bg_color \
               or self.default_tab_bg_color

    def mouse_down(self, e):
        x, y = e.local
        if y < self.tab_height:
            i = self.tab_number_containing_x(x)
            if i is not None:
                self.show_page(self.pages[i])

    def tab_number_containing_x(self, x):
        n = len(self.pages)
        m = self.tab_margin
        width = self.width - 2 * m + self.tab_spacing - self.tab_border_width
        i = (x - m) * n // width
        if 0 <= i < n:
            return i

    def gl_draw_self(self, root, offset):
        self.gl_draw(root, offset)

    def gl_draw(self, root, offset):
        pages = self.pages

        if len(pages) > 1:
            tlcorner = (offset[0] + self.bottomleft[0],
                        offset[1] + self.bottomleft[1])
            pageTabContents = []
            current_page = self.current_page
            n = len(pages)
            b = self.tab_border_width
            s = self.tab_spacing
            h = self.tab_height
            m = self.tab_margin
            tabWidth = (self.size[0] - (s * n) - (2 * m)) / n
            width = self.width - 2 * m + s - b
            x0 = m + tlcorner[0]

            font = self.tab_font
            fg = self.tab_fg_color
            surface = Surface(self.size, SRCALPHA)

            glEnable(GL_BLEND)

            for i, page in enumerate(pages):
                x1 = x0 + tabWidth
                selected = page is current_page
                if selected:
                    glColor(1.0, 1.0, 1.0, 0.5)
                else:
                    glColor(0.5, 0.5, 0.5, 0.5)
                glRectf(x0, tlcorner[1] - (m + b), x1, tlcorner[1] - (h))
                buf = font.render(self.pages[i].tab_title, True, self.fg_color
                                  or fg)
                r = buf.get_rect()

                offs = ((tabWidth - r.size[0]) / 2) + m + ((s + tabWidth) * i)

                surface.blit(buf, (offs, m))
                x0 = x1 + s

            data = image.tostring(surface, 'RGBA', 1)
            rect = self.rect.move(offset)
            w, h = root.size
            glViewport(0, 0, w, h)
            glMatrixMode(GL_PROJECTION)
            glLoadIdentity()
            gluOrtho2D(0, w, 0, h)
            glMatrixMode(GL_MODELVIEW)
            glLoadIdentity()
            glRasterPos2i(rect.left, h - rect.bottom)
            glPushAttrib(GL_COLOR_BUFFER_BIT)
            glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA)
            glDrawPixels(self.width, self.height, GL_RGBA, GL_UNSIGNED_BYTE,
                         fromstring(data, dtype='uint8'))
            glPopAttrib()
            glFlush()

            glDisable(GL_BLEND)
예제 #5
0
class TabPanel(Widget):
    #  pages         [Widget]
    #  current_page  Widget

    tab_font = FontProperty('tab_font')
    tab_height = ThemeProperty('tab_height')
    tab_border_width = ThemeProperty('tab_border_width')
    tab_spacing = ThemeProperty('tab_spacing')
    tab_margin = ThemeProperty('tab_margin')
    tab_fg_color = ThemeProperty('tab_fg_color')
    default_tab_bg_color = ThemeProperty('default_tab_bg_color')
    tab_area_bg_color = ThemeProperty('tab_area_bg_color')
    tab_dimming = ThemeProperty('tab_dimming')

    #use_page_bg_color_for_tabs = ThemeProperty('use_page_bg_color_for_tabs')

    def __init__(self, pages=None, **kwds):
        Widget.__init__(self, **kwds)
        self.pages = []
        self.current_page = None
        if pages:
            w = h = 0
            for title, page in pages:
                w = max(w, page.width)
                h = max(h, page.height)
                self._add_page(title, page)
            self.size = (w, h)
            self.show_page(pages[0][1])

    def content_size(self):
        return (self.width, self.height - self.tab_height)

    def content_rect(self):
        return Rect((0, self.tab_height), self.content_size())

    def page_height(self):
        return self.height - self.tab_height

    def add_page(self, title, page):
        self._add_page(title, page)
        if not self.current_page:
            self.show_page(page)

    def _add_page(self, title, page):
        page.tab_title = title
        page.anchor = 'ltrb'
        self.pages.append(page)

    def remove_page(self, page):
        try:
            i = self.pages.index(page)
            del self.pages[i]
        except IndexError:
            pass
        if page is self.current_page:
            self.show_page(None)

    def show_page(self, page):
        if self.current_page:
            self.remove(self.current_page)
        self.current_page = page
        if page:
            th = self.tab_height
            page.rect = Rect(0, th, self.width, self.height - th)
            self.add(page)
            page.focus()

    def draw(self, surf):
        self.draw_tab_area_bg(surf)
        self.draw_tabs(surf)

    def draw_tab_area_bg(self, surf):
        bg = self.tab_area_bg_color
        if bg:
            surf.fill(bg, (0, 0, self.width, self.tab_height))

    def draw_tabs(self, surf):
        font = self.tab_font
        fg = self.tab_fg_color
        b = self.tab_border_width
        if b:
            surf.fill(fg, (0, self.tab_height - b, self.width, b))
        for i, title, page, selected, rect in self.iter_tabs():
            x0 = rect.left
            w = rect.width
            h = rect.height
            r = rect
            if not selected:
                r = Rect(r)
                r.bottom -= b
            self.draw_tab_bg(surf, page, selected, r)
            if b:
                surf.fill(fg, (x0, 0, b, h))
                surf.fill(fg, (x0 + b, 0, w - 2 * b, b))
                surf.fill(fg, (x0 + w - b, 0, b, h))
            buf = font.render(title, True, page.fg_color or fg)
            r = buf.get_rect()
            r.center = (x0 + w // 2, h // 2)
            surf.blit(buf, r)

    def iter_tabs(self):
        pages = self.pages
        current_page = self.current_page
        n = len(pages)
        b = self.tab_border_width
        s = self.tab_spacing
        h = self.tab_height
        m = self.tab_margin
        width = self.width - 2 * m + s - b
        x0 = m
        for i, page in enumerate(pages):
            x1 = m + (i + 1) * width // n  #self.tab_boundary(i + 1)
            selected = page is current_page
            yield i, page.tab_title, page, selected, Rect(
                x0, 0, x1 - x0 - s + b, h)
            x0 = x1

    def draw_tab_bg(self, surf, page, selected, rect):
        bg = self.tab_bg_color_for_page(page)
        if not selected:
            bg = brighten(bg, self.tab_dimming)
        surf.fill(bg, rect)

    def tab_bg_color_for_page(self, page):
        return getattr(page, 'tab_bg_color', None) \
         or page.bg_color \
         or self.default_tab_bg_color

    def mouse_down(self, e):
        x, y = e.local
        if y < self.tab_height:
            i = self.tab_number_containing_x(x)
            if i is not None:
                self.show_page(self.pages[i])

    def tab_number_containing_x(self, x):
        n = len(self.pages)
        m = self.tab_margin
        width = self.width - 2 * m + self.tab_spacing - self.tab_border_width
        i = (x - m) * n // width
        if 0 <= i < n:
            return i