Source code for albow.tab_panel

# ###############################################################
#
#   Albow - Tab Panel
#
################################################################
#-# Modified by D.C.-G. for translation purpose

from OpenGL.GL import *
from OpenGL.GLU import *
from OpenGL.GLUT import *
from albow import *
from pygame import Rect, Surface, image
from pygame.locals import SRCALPHA
from widget import Widget
from theme import ThemeProperty, FontProperty
from utils import brighten
from numpy import fromstring
from translate import _ # useless?


[docs]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])
[docs] def content_size(self): return self.width, self.height - self.tab_height
[docs] def content_rect(self): return Rect((0, self.tab_height), self.content_size())
[docs] def page_height(self): return self.height - self.tab_height
[docs] def add_page(self, title, page, idx=None): self._add_page(title, page, idx) if not self.current_page: self.show_page(page)
def _add_page(self, title, page, idx=None): page.tab_title = _(title) page.anchor = 'ltrb' if idx is not None: self.pages.insert(idx, page) else: self.pages.append(page)
[docs] 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)
[docs] 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()
[docs] def draw(self, surf): self.draw_tab_area_bg(surf) self.draw_tabs(surf)
[docs] 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))
[docs] 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)
[docs] 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
[docs] 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)
[docs] 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
[docs] 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: if self.current_page: self.current_page.dispatch_attention_loss() self.show_page(self.pages[i])
[docs] 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
[docs] def gl_draw_self(self, root, offset): self.gl_draw(root, offset)
[docs] def gl_draw(self, root, offset): pages = self.pages if len(pages) > 1: tlcorner = (offset[0] + self.bottomleft[0], offset[1] + self.bottomleft[1]) 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 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)