示例#1
0
class FoldingBox(SingleContainer):
    """Collapsible container"""
    def __init__(self, title, **kwargs):
        '''Create a folding box
		
		Keyword arguments:
		name -- unique widget identifier
		content -- child container
		collapsed -- if true, container folded initially
		'''
        SingleContainer.__init__(self, **kwargs)

        self.shapes['topbar'] = Rectangle()
        self.elements['title'] = BasicLabel(title,
                                            font_size=8,
                                            color=(0, 0, 0, 255),
                                            anchor_x='left',
                                            anchor_y='center')

        self.content = kwargs.get('content', None)

        self._last_h = 15
        self._collapsed = False

        self._top_h = 0

        self.collapsed = kwargs.get('collapsed', False)

    def _get_title(self):
        return self.elements['title'].text

    def _set_title(self, title):
        self.elements['title'].text = title

    title = property(_get_title, _set_title)

    def _get_collapsed(self):
        return self._collapsed

    def _set_collapsed(self, collapsed):
        if collapsed != self._collapsed:
            self._collapsed = collapsed
            self._h, self._last_h = self._last_h, self._h
            for c in self.children:
                c.visible = not collapsed
            if self.theme:
                self.shapes['topbar'].patch = self.theme['folding_box'][(
                    'image_closed' if collapsed else 'image')]
            self.find_root().update_layout()

    collapsed = property(_get_collapsed, _set_collapsed)

    def update_theme(self, theme):
        SingleContainer.update_theme(self, theme)

        if theme:
            patch = theme['folding_box'][('image_closed'
                                          if self._collapsed else 'image')]

            self.shapes['topbar'].patch = patch
            self.elements['title'].font_name = theme['font']
            self.elements['title'].font_size = theme['font_size_small']
            self.elements['title'].color = theme['font_color']

            if self._collapsed:
                self._h = patch.padding_top
            else:
                self._last_h = patch.padding_top

            self._top_h = patch.padding_top

    def update_elements(self):
        if self.theme:
            patch = self.theme['folding_box'][('image_closed' if
                                               self._collapsed else 'image')]

            self.shapes['topbar'].update(
                self._gx + patch.padding_left,
                self._gy + self.h - patch.padding_top,
                self.w - patch.padding_left - patch.padding_right, 1)
            self.elements['title'].x = self._gx + patch.padding_left
            self.elements[
                'title'].y = self._gy + self.h - patch.padding_top / 2 + 1

            self.topbar = Rect(0, self.h - patch.padding_top, self.w,
                               patch.padding_top)

        SingleContainer.update_elements(self)

    def determine_size(self):
        self._content.determine_size()
        size = self._content._pref_size

        if self.collapsed:
            self._pref_size = Size(size[0], self._top_h)
        else:
            self._pref_size = Size(size[0], size[1] + self._top_h)

    def reset_size(self, size):
        Widget.reset_size(self, size)

        if not self.collapsed:
            self._content.reset_size(Size(size.w, size.h - self._top_h))

    def on_mouse_press(self, x, y, button, modifiers):
        if button == pyglet.window.mouse.LEFT and \
          self.topbar.hit_test(x - self._gx, y - self._gy):
            self.collapsed = not self.collapsed
            return pyglet.event.EVENT_HANDLED

        SingleContainer.on_mouse_press(self, x, y, button, modifiers)
        return pyglet.event.EVENT_UNHANDLED

    def clip_rect(self):
        return Rect(self._gx, self._gy, self.w, self.h - 15)
示例#2
0
class Dialogue(SingleContainer):
    """Moveable window, optionally resizeable"""
    def __init__(self, title, **kwargs):
        '''Create a dialogue
		
		Keyword arguments:
		name -- unique widget identifier
		content -- child container
		'''
        SingleContainer.__init__(self, **kwargs)

        self.resizeable = kwargs.get('resizeable', False)

        self.shapes['background'] = Rectangle()
        self.shapes['title_bar'] = Rectangle()
        self.elements['title'] = BasicLabel(title, anchor_x='center')

        self.topbar = Rect(0, 0, 0, 15)

        self._in_drag = False

        self.content = kwargs.get('content', None)

    def _get_title(self):
        return self.elements['title'].text

    def _set_title(self, title):
        self.elements['title'].text = title

    title = property(_get_title, _set_title)

    def update_theme(self, theme):
        SingleContainer.update_theme(self, theme)

        if theme:
            background_patch = theme['window']['image_background']
            title_patch = theme['window']['image_title_bar']

            self.shapes['background'].patch = background_patch
            self.shapes['title_bar'].patch = title_patch

            self.elements['title'].font_name = theme['font']
            self.elements['title'].font_size = theme['font_size_small']
            self.elements['title'].color = theme['font_color']

            font = self.elements['title'].document.get_font()
            height = font.ascent - font.descent

            self._pref_size = Size(
                title_patch.padding_x + self.elements['title'].content_width,
                background_patch.padding_y + title_patch.padding_y + height)

    def update_elements(self):
        if self._dirty and self.theme:
            background = self.theme['window']['image_background']
            title_bar = self.theme['window']['image_title_bar']

            font = self.elements['title'].document.get_font()
            height = font.ascent - font.descent

            h = title_bar.padding_bottom + height + title_bar.padding_top

            self.shapes['background'].update(self._gx, self._gy, self.w,
                                             self.h)
            self.shapes['title_bar'].update_in(
                self._gx - background.padding_left, self._gy + self.h,
                self.w + background.padding_left + background.padding_right, h)

            self.elements['title'].x = self._gx + self.w / 2

            self.topbar = Rect(
                -background.padding_left, self.h,
                self.w + background.padding_left + background.padding_right, h)
            self.elements[
                'title'].y = self._gy + self.h + title_bar.padding_bottom - font.descent

        SingleContainer.update_elements(self)

    def reset_size(self, size):
        self._y += self._h - size.h
        SingleContainer.reset_size(self, size)

    def bounds(self):
        return Rect(self._gx, self._gy, self.w, self.h + self.topbar.h)

    def on_mouse_press(self, x, y, button, modifiers):
        if button == pyglet.window.mouse.LEFT and \
          self.topbar.hit_test(x - self.x, y - self.y):
            self._in_drag = True
            self._offset_x = x - self.x
            self._offset_y = y - self.y
            return pyglet.event.EVENT_HANDLED

        SingleContainer.on_mouse_press(self, x, y, button, modifiers)
        return pyglet.event.EVENT_UNHANDLED

    def on_mouse_drag(self, x, y, dx, dy, button, modifiers):
        if button == pyglet.window.mouse.LEFT and self._in_drag:
            self._x = x - self._offset_x
            self._y = y - self._offset_y
            self.find_root().update_layout()
            return pyglet.event.EVENT_HANDLED

        SingleContainer.on_mouse_drag(self, x, y, dx, dy, button, modifiers)
        return pyglet.event.EVENT_UNHANDLED

    def on_mouse_release(self, x, y, button, modifiers):
        if button == pyglet.window.mouse.LEFT and self._in_drag:
            self._in_drag = False
            return pyglet.event.EVENT_HANDLED

        SingleContainer.on_mouse_release(self, x, y, button, modifiers)
        return pyglet.event.EVENT_UNHANDLED
示例#3
0
class Button(Widget):
    """Clickable button"""
    def __init__(self, text, **kwargs):
        '''Create a button control
		
		Keyword arguments:
		action -- callback to be invoked when the button is clicked
		'''
        Widget.__init__(self, **kwargs)

        self.elements['label'] = BasicLabel(text,
                                            font_size=8,
                                            color=(0, 0, 0, 255),
                                            anchor_x='left',
                                            anchor_y='bottom')
        self.shapes['frame'] = Rectangle()
        self.active_region = Rect(0, 0, 0, 0)

        self.action = kwargs.get('action', None)
        self._down = False

    def _get_text(self):
        return self.elements['label'].text

    def _set_text(self, text):
        self.elements['label'].text = text

    text = property(_get_text, _set_text)

    def update_theme(self, theme):
        Widget.update_theme(self, theme)

        if theme:
            patch = theme['button'][('image_down'
                                     if self._down else 'image_up')]

            label = self.elements['label']
            label.font_name = self.theme['font']
            label.font_size = self.theme['font_size']
            label.color = theme['font_color']

            font = label.document.get_font()
            height = font.ascent - font.descent

            self._pref_size = Size(
                patch.padding_left + label.content_width + patch.padding_right,
                patch.padding_bottom + height + patch.padding_top)

            label.x = patch.padding_left + label.content_width / 2
            label.y = patch.padding_bottom + height / 2 - font.descent

            self.shapes['frame'].patch = patch

    def update_elements(self):
        if self._dirty and self.theme:
            patch = self.theme['button'][('image_down'
                                          if self._down else 'image_up')]

            label = self.elements['label']

            font = label.document.get_font()
            height = font.ascent - font.descent

            left = 0
            if self.halign == 'center':
                left = self.w / 2 - self._pref_size[0] / 2
            elif self.halign == 'right':
                left = self.w - self._pref_size[0]

            bottom = 0
            if self.valign == 'center':
                bottom = self.h / 2 - self._pref_size[1] / 2
            elif self.valign == 'top':
                bottom = self.h - self._pref_size[1]

            label.x = self._gx + left + patch.padding_left
            label.y = self._gy + bottom + patch.padding_bottom

            self.shapes['frame'].update(
                self._gx + left + patch.padding_left,
                self._gy + bottom + patch.padding_bottom, label.content_width,
                height)

            self.active_region = Rect(self._gx + left + patch.padding_left,
                                      self._gy + bottom + patch.padding_bottom,
                                      label.content_width, height)

        Widget.update_elements(self)

    def on_mouse_press(self, x, y, button, modifiers):
        if button == pyglet.window.mouse.LEFT and self.active_region.hit_test(
                x, y):
            self.shapes['frame'].patch = self.theme['button']['image_down']
            self._down = True
            return pyglet.event.EVENT_HANDLED

        Widget.on_mouse_press(self, x, y, button, modifiers)
        return pyglet.event.EVENT_UNHANDLED

    def on_mouse_drag(self, x, y, dx, dy, button, modifiers):
        if button == pyglet.window.mouse.LEFT and self._down:
            if self.active_region.hit_test(x, y):
                self.shapes['frame'].patch = self.theme['button']['image_down']
            else:
                self.shapes['frame'].patch = self.theme['button']['image_up']

            return pyglet.event.EVENT_HANDLED

        Widget.on_mouse_drag(self, x, y, dx, dy, button, modifiers)
        return pyglet.event.EVENT_UNHANDLED

    def on_mouse_release(self, x, y, button, modifiers):
        if button == pyglet.window.mouse.LEFT and self._down:
            self.shapes['frame'].patch = self.theme['button']['image_up']
            self._down = False
            if self.active_region.hit_test(x, y):
                if self.action:
                    self.action(self)
                return pyglet.event.EVENT_HANDLED

        Widget.on_mouse_press(self, x, y, button, modifiers)
        return pyglet.event.EVENT_UNHANDLED
示例#4
0
class Dialogue(SingleContainer):
	"""Moveable window, optionally resizeable"""
	def __init__(self, title, **kwargs):
		'''Create a dialogue
		
		Keyword arguments:
		name -- unique widget identifier
		content -- child container
		'''
		SingleContainer.__init__(self, **kwargs)
		
		self.resizeable = kwargs.get('resizeable', False)
		
		self.shapes['background'] = Rectangle()
		self.shapes['title_bar'] = Rectangle()
		self.elements['title'] = BasicLabel(title, anchor_x='center')
		
		self.topbar = Rect(0, 0, 0, 15)
		
		self._in_drag = False
		
		self.content = kwargs.get('content', None)
	
	def _get_title(self):
		return self.elements['title'].text
	def _set_title(self, title):
		self.elements['title'].text = title
	title = property(_get_title, _set_title)	
	
	def update_theme(self, theme):
		SingleContainer.update_theme(self, theme)
		
		if theme:
			background_patch = theme['window']['image_background']
			title_patch = theme['window']['image_title_bar']
			
			self.shapes['background'].patch = background_patch
			self.shapes['title_bar'].patch = title_patch
			
			self.elements['title'].font_name = theme['font']
			self.elements['title'].font_size = theme['font_size_small']
			self.elements['title'].color = theme['font_color']
			
			font = self.elements['title'].document.get_font()
			height = font.ascent - font.descent
			
			self._pref_size = Size(title_patch.padding_x + self.elements['title'].content_width, background_patch.padding_y + title_patch.padding_y + height)
	
	def update_elements(self):
		if self._dirty and self.theme:
			background = self.theme['window']['image_background']
			title_bar = self.theme['window']['image_title_bar']
			
			font = self.elements['title'].document.get_font()
			height = font.ascent - font.descent
			
			h = title_bar.padding_bottom + height + title_bar.padding_top
			
			self.shapes['background'].update(self._gx, self._gy, self.w, self.h)
			self.shapes['title_bar'].update_in(self._gx - background.padding_left, self._gy + self.h, self.w + background.padding_left + background.padding_right, h)
			
			self.elements['title'].x = self._gx + self.w/2
			
			self.topbar = Rect(-background.padding_left, self.h, self.w + background.padding_left + background.padding_right, h)
			self.elements['title'].y = self._gy + self.h + title_bar.padding_bottom - font.descent
		
		SingleContainer.update_elements(self)
	
	def reset_size(self, size):
		self._y += self._h - size.h
		SingleContainer.reset_size(self, size)
	
	def bounds(self):
		return Rect(self._gx, self._gy, self.w, self.h + self.topbar.h)
	
	def on_mouse_press(self, x, y, button, modifiers):
		if button == pyglet.window.mouse.LEFT and \
				self.topbar.hit_test(x - self.x, y - self.y):
			self._in_drag = True
			self._offset_x = x - self.x
			self._offset_y = y - self.y
			return pyglet.event.EVENT_HANDLED
		
		SingleContainer.on_mouse_press(self, x, y, button, modifiers)
		return pyglet.event.EVENT_UNHANDLED
	
	def on_mouse_drag(self, x, y, dx, dy, button, modifiers):
		if button == pyglet.window.mouse.LEFT and self._in_drag:
			self._x = x - self._offset_x
			self._y = y - self._offset_y
			self.find_root().update_layout()
			return pyglet.event.EVENT_HANDLED
		
		SingleContainer.on_mouse_drag(self, x, y, dx, dy, button, modifiers)
		return pyglet.event.EVENT_UNHANDLED
	
	def on_mouse_release(self, x, y, button, modifiers):
		if button == pyglet.window.mouse.LEFT and self._in_drag:
			self._in_drag = False
			return pyglet.event.EVENT_HANDLED
		
		SingleContainer.on_mouse_release(self, x, y, button, modifiers)
		return pyglet.event.EVENT_UNHANDLED
示例#5
0
文件: button.py 项目: arokem/Fos
class Button(Widget):
	"""Clickable button"""
	def __init__(self, text, **kwargs):
		'''Create a button control
		
		Keyword arguments:
		action -- callback to be invoked when the button is clicked
		'''
		Widget.__init__(self, **kwargs)
		
		self.elements['label'] = BasicLabel(text, font_size=8, color=(0,0,0,255), anchor_x='left', anchor_y='bottom')
		self.shapes['frame'] = Rectangle()
		self.active_region = Rect(0, 0, 0, 0)
		
		self.action = kwargs.get('action', None)
		self._down = False
	
	def _get_text(self):
		return self.elements['label'].text
	def _set_text(self, text):
		self.elements['label'].text = text
	text = property(_get_text, _set_text)
	
	def update_theme(self, theme):
		Widget.update_theme(self, theme)
		
		if theme:
			patch = theme['button'][('image_down' if self._down else 'image_up')]
			
			label = self.elements['label']
			label.font_name = self.theme['font']
			label.font_size = self.theme['font_size']
			label.color = theme['font_color']
			
			font = label.document.get_font()
			height = font.ascent - font.descent
			
			self._pref_size = Size(patch.padding_left + label.content_width + patch.padding_right, patch.padding_bottom + height + patch.padding_top)
			
			label.x = patch.padding_left + label.content_width/2
			label.y = patch.padding_bottom + height/2 - font.descent
			
			self.shapes['frame'].patch = patch
	
	def update_elements(self):
		if self._dirty and self.theme:
			patch = self.theme['button'][('image_down' if self._down else 'image_up')]
						
			label = self.elements['label']
			
			font = label.document.get_font()
			height = font.ascent - font.descent
			
			left = 0
			if self.halign == 'center':
				left = self.w/2 - self._pref_size[0]/2
			elif self.halign == 'right':
				left = self.w - self._pref_size[0]
			
			bottom = 0
			if self.valign == 'center':
				bottom = self.h/2 - self._pref_size[1]/2
			elif self.valign == 'top':
				bottom = self.h - self._pref_size[1]
			
			label.x = self._gx + left + patch.padding_left
			label.y = self._gy + bottom + patch.padding_bottom
			
			self.shapes['frame'].update(self._gx + left + patch.padding_left, self._gy + bottom + patch.padding_bottom, label.content_width, height)
			
			self.active_region = Rect(self._gx + left + patch.padding_left, self._gy + bottom + patch.padding_bottom, label.content_width, height)
		
		Widget.update_elements(self)
	
	def on_mouse_press(self, x, y, button, modifiers):
		if button == pyglet.window.mouse.LEFT and self.active_region.hit_test(x, y):
			self.shapes['frame'].patch = self.theme['button']['image_down']
			self._down = True
			return pyglet.event.EVENT_HANDLED
		
		Widget.on_mouse_press(self, x, y, button, modifiers)
		return pyglet.event.EVENT_UNHANDLED
	
	def on_mouse_drag(self, x, y, dx, dy, button, modifiers):
		if button == pyglet.window.mouse.LEFT and self._down:
			if self.active_region.hit_test(x, y):
				self.shapes['frame'].patch = self.theme['button']['image_down']
			else:
				self.shapes['frame'].patch = self.theme['button']['image_up']
			
			return pyglet.event.EVENT_HANDLED
				
		Widget.on_mouse_drag(self, x, y, dx, dy, button, modifiers)
		return pyglet.event.EVENT_UNHANDLED
	
	def on_mouse_release(self, x, y, button, modifiers):
		if button == pyglet.window.mouse.LEFT and self._down:
			self.shapes['frame'].patch = self.theme['button']['image_up']
			self._down = False
			if self.active_region.hit_test(x, y):
				if self.action:
					self.action(self)
				return pyglet.event.EVENT_HANDLED
		
		Widget.on_mouse_press(self, x, y, button, modifiers)
		return pyglet.event.EVENT_UNHANDLED
示例#6
0
class FoldingBox(SingleContainer):
	"""Collapsible container"""
	def __init__(self, title, **kwargs):
		'''Create a folding box
		
		Keyword arguments:
		name -- unique widget identifier
		content -- child container
		collapsed -- if true, container folded initially
		'''
		SingleContainer.__init__(self, **kwargs)
		
		self.shapes['topbar'] = Rectangle()
		self.elements['title'] = BasicLabel(title, font_size=8, color=(0,0,0,255), anchor_x='left', anchor_y='center')
		
		self.content = kwargs.get('content', None)
		
		self._last_h = 15
		self._collapsed = False
		
		self._top_h = 0
		
		self.collapsed = kwargs.get('collapsed', False)
	
	def _get_title(self):
		return self.elements['title'].text
	def _set_title(self, title):
		self.elements['title'].text = title
	title = property(_get_title, _set_title)
	
	def _get_collapsed(self):
		return self._collapsed
	def _set_collapsed(self, collapsed):
		if collapsed != self._collapsed:
			self._collapsed = collapsed
			self._h, self._last_h = self._last_h, self._h
			for c in self.children:
				c.visible = not collapsed
			if self.theme:
				self.shapes['topbar'].patch = self.theme['folding_box'][('image_closed' if collapsed else 'image')]
			self.find_root().update_layout()
	collapsed = property(_get_collapsed, _set_collapsed)
	
	def update_theme(self, theme):		
		SingleContainer.update_theme(self, theme)
		
		if theme:
			patch = theme['folding_box'][('image_closed' if self._collapsed else 'image')]
			
			self.shapes['topbar'].patch = patch
			self.elements['title'].font_name = theme['font']
			self.elements['title'].font_size = theme['font_size_small']
			self.elements['title'].color = theme['font_color']
			
			if self._collapsed:
				self._h = patch.padding_top
			else:
				self._last_h = patch.padding_top
			
			self._top_h = patch.padding_top
	
	def update_elements(self):		
		if self.theme:
			patch = self.theme['folding_box'][('image_closed' if self._collapsed else 'image')]
			
			self.shapes['topbar'].update(self._gx + patch.padding_left, self._gy + self.h - patch.padding_top, self.w - patch.padding_left - patch.padding_right, 1)
			self.elements['title'].x = self._gx + patch.padding_left
			self.elements['title'].y = self._gy + self.h - patch.padding_top/2 + 1
			
			self.topbar = Rect(0, self.h-patch.padding_top, self.w, patch.padding_top)
		
		SingleContainer.update_elements(self)
	
	def determine_size(self):
		self._content.determine_size()
		size = self._content._pref_size
		
		if self.collapsed:
			self._pref_size = Size(size[0], self._top_h)
		else:
			self._pref_size = Size(size[0], size[1] + self._top_h)
	
	def reset_size(self, size):
		Widget.reset_size(self, size)
		
		if not self.collapsed:
			self._content.reset_size(Size(size.w, size.h - self._top_h))
	
	def on_mouse_press(self, x, y, button, modifiers):
		if button == pyglet.window.mouse.LEFT and \
				self.topbar.hit_test(x - self._gx, y - self._gy):
			self.collapsed = not self.collapsed
			return pyglet.event.EVENT_HANDLED
		
		SingleContainer.on_mouse_press(self, x, y, button, modifiers)
		return pyglet.event.EVENT_UNHANDLED
	
	def clip_rect(self):
		return Rect(self._gx, self._gy, self.w, self.h-15)