def __init__(self, batch, position=(0, 0), size=(100, 20), font_size=12, group=None, visible=True): default_style = { ControlState.DEFAULT: { "border_thickness": 1, "border_color": Basic.WHITE1, "background_color": Basic.WHITE_TINGE1, }, ControlState.FOCUS: { "border_color": Basic.NEARWHITE, }, ControlState.HOVER: { "border_color": Basic.NEARWHITE, }, ControlState.DISABLED: {}, ControlState.PRESSED: {} # Unused in textbox } self._font_size = font_size self._original_height = size[1] self._prev_caret_mark = 0 self._prev_caret_position = 0 self._group_back = pyglet.graphics.OrderedGroup(0, group) self._group_front = pyglet.graphics.OrderedGroup(1, group) self.background = Rectangle(batch, position, size, group=self._group_back) self.border = [ Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front) ] # Formatted document stores the formatting and text self._document = pyglet.text.document.FormattedDocument(' ') self._document.set_style(0, 1, dict(color=(0xCC, 0xCC, 0xCC, 0xff), font_name="Arimo", font_size=font_size)) self._document.text = '' # IncrementalLayout handles displaying the document self._layout = pyglet.text.layout.IncrementalTextLayout(self._document, size[0] - 20, size[1], wrap_lines=True, group=self._group_front, multiline=True, batch=batch) self._layout.selection_color = Basic.NEARWHITE self._layout.selection_background_color = Basic.PRIMARY # Caret provides basic text entry functionality self._caret = pyglet.text.caret.Caret(self._layout, color=Basic.NEARWHITE[:3]) self._caret.position = 0 self._caret.mark = None self._caret.visible = False # Keep track of modifiers for text input blocking self._modifiers = 0 # Base class establishes style ControlElement.__init__(self, batch, default_style, group, position, size, visible) self._render()
def __init__(self, batch, text="badge", click_event=None, position=(0, 0), group=None, visible=True): default_style = { ControlState.DEFAULT: { "border_thickness": 1, "border_color": Basic.PRIMARY, "font_color": Basic.OFFWHITE, "background_color": Basic.WHITE_TINGE1, }, ControlState.HOVER: { "font_color": Basic.NEARWHITE, "background_color": Basic.PRIMARY_BRIGHT_TINGE }, ControlState.DISABLED: {}, ControlState.FOCUS: {}, ControlState.PRESSED: {} } if click_event: self.push_handlers(on_click=click_event) self._group_back = pyglet.graphics.OrderedGroup(0, group) self._group_front = pyglet.graphics.OrderedGroup(1, group) self.label = Label(batch, text=text, group=self._group_front, font_color=Basic.OFFWHITE, font_size=10) size = self.label.get_size( )[0] + Badge.PADDING_WIDTH, self.label.get_size( )[1] + Badge.PADDING_HEIGHT self.background = Rectangle(batch, position, size, group=self._group_back) self.border = [ Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front) ] ControlElement.__init__(self, batch, default_style, group, position, size, visible, False) self._render()
def __init__(self): super().__init__(WINDOW_WIDTH, WINDOW_HEIGHT, caption=WINDOW_CAPTION) self.ctype = CodebitType.CHILL self.topics = [] self.topic_badges = [] self.chunks = [] # Use a single batch with foreground / background groups to draw everything for now self.batch = pyglet.graphics.Batch() self.group_bkgr = pyglet.graphics.OrderedGroup(0) self.group_back = pyglet.graphics.OrderedGroup(1) self.group_front = pyglet.graphics.OrderedGroup(2) self.background = Image(self.batch, 'assets/pexels-photo-242236.jpeg', group=self.group_bkgr) self.background_shadow = Rectangle(self.batch, size=(WINDOW_WIDTH, WINDOW_HEIGHT), color=WINDOW_SHADOW_COLOR, group=self.group_back) self.add_children(self.background, self.background_shadow) # Title self.title = Label(self.batch, text='codebits', font_name="Arimo", font_size=18, font_color=Basic.OFFWHITE, group=self.group_front) self.title.center(WINDOW_WIDTH // 2, 50) self.add_children(self.title) # Textbox self.textbox = Textbox(self.batch, size=(500, 34), font_size=12, group=self.group_front) self.textbox.center(WINDOW_WIDTH // 2, 130) self.textbox.push_handlers( on_text_change=self.on_textbox_change, on_caret_change=self.on_textbox_caret_change ) self.add_children(self.textbox) # Mode Button self.search_button = Button(self.batch, 'assets/search2-purple.png', (self.textbox.get_position()[0] - 34, self.textbox.get_position()[1]), (34, 34), lambda: print('clicked search'), self.group_front) # Enter button self.enter_button = Button(self.batch, 'assets/login2-teal.png', (self.textbox.get_position()[0] + self.textbox.get_size()[0], self.textbox.get_position()[1]), (34, 34), group=self.group_front) self.add_children(self.search_button, self.enter_button) # Status strings self.ctype_label = Label(self.batch, position=(15, 15), text="type: CHILL", group=self.group_front, font_size=10) self.chunk_count_label = Label(self.batch, position=(15, 35), text="chunks: 0", group=self.group_front, font_size=10) self.char_count_label = Label(self.batch, position=(15, 55), text="chars: 0", group=self.group_front, font_size=10) self.add_children(self.ctype_label, self.chunk_count_label, self.char_count_label) self.order_controls() self.entry_master = EntryMaster(self.textbox) self.entry_master.push_handlers( on_add_chunk=self.on_chunk_add, on_add_topic=self.on_topic_add, on_codebit_type_change=self.on_codebit_type_change ) self.engine = DataEngine()
def __init__(self, batch, image_path, position=(0, 0), size=(20, 20), click_event=None, group=None, visible=True): default_style = { ControlState.DEFAULT: { "border_thickness": 1, "border_color": Basic.WHITE1, "background_color": Basic.WHITE_TINGE1, }, ControlState.FOCUS: { "border_color": Basic.NEARWHITE, "background_color": Basic.WHITE_TINGE1 }, ControlState.HOVER: { "border_color": Basic.NEARWHITE, "background_color": Basic.WHITE_TINGE2 }, ControlState.DISABLED: {}, ControlState.PRESSED: { "background_color": Basic.WHITE_TINGE3 } } if click_event: self.push_handlers(on_click=click_event) self._group_back = pyglet.graphics.OrderedGroup(0, group) self._group_front = pyglet.graphics.OrderedGroup(1, group) self.background = Rectangle(batch, position, size, group=self._group_back) self.border = [ Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front) ] self._image_path = image_path self.icon = Image(batch, image_path, position, size, self._group_front, visible) # Base class establishes style ControlElement.__init__(self, batch, default_style, group, position, size, visible) self._render()
class Textbox(ControlElement, pyglet.event.EventDispatcher): BOX_LINE_HEIGHT = 19 def __init__(self, batch, position=(0, 0), size=(100, 20), font_size=12, group=None, visible=True): default_style = { ControlState.DEFAULT: { "border_thickness": 1, "border_color": Basic.WHITE1, "background_color": Basic.WHITE_TINGE1, }, ControlState.FOCUS: { "border_color": Basic.NEARWHITE, }, ControlState.HOVER: { "border_color": Basic.NEARWHITE, }, ControlState.DISABLED: {}, ControlState.PRESSED: {} # Unused in textbox } self._font_size = font_size self._original_height = size[1] self._prev_caret_mark = 0 self._prev_caret_position = 0 self._group_back = pyglet.graphics.OrderedGroup(0, group) self._group_front = pyglet.graphics.OrderedGroup(1, group) self.background = Rectangle(batch, position, size, group=self._group_back) self.border = [ Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front) ] # Formatted document stores the formatting and text self._document = pyglet.text.document.FormattedDocument(' ') self._document.set_style(0, 1, dict(color=(0xCC, 0xCC, 0xCC, 0xff), font_name="Arimo", font_size=font_size)) self._document.text = '' # IncrementalLayout handles displaying the document self._layout = pyglet.text.layout.IncrementalTextLayout(self._document, size[0] - 20, size[1], wrap_lines=True, group=self._group_front, multiline=True, batch=batch) self._layout.selection_color = Basic.NEARWHITE self._layout.selection_background_color = Basic.PRIMARY # Caret provides basic text entry functionality self._caret = pyglet.text.caret.Caret(self._layout, color=Basic.NEARWHITE[:3]) self._caret.position = 0 self._caret.mark = None self._caret.visible = False # Keep track of modifiers for text input blocking self._modifiers = 0 # Base class establishes style ControlElement.__init__(self, batch, default_style, group, position, size, visible) self._render() def get_text(self): return self._document.text def set_text(self, new_text): self._document.text = new_text self._render() def delete(self): self.background.delete() for line in self.border: line.delete() self._layout.delete() def _render(self): # Alter height based on line count line_count = self._layout.get_line_count() # lines = self._document.text.split('\n') self._size = self._size[0], self._original_height + (line_count - 1) * Textbox.BOX_LINE_HEIGHT self._layout.height = self._size[1] self._layout.x = self._position[0] + 10 self._layout.y = UIElement.SCREEN_HEIGHT - self._position[1] - 8 - self._size[1] self.background.set_size(self._size) self.background.set_position(self._position) pos = self._position size = self._size self.border[0].set_points(pos, (pos[0] + size[0], pos[1])) self.border[1].set_points((pos[0] + 1, pos[1]), (pos[0] + 1, pos[1] + size[1])) self.border[2].set_points((pos[0] + size[0], pos[1]), (pos[0] + size[0], pos[1] + size[1])) self.border[3].set_points((pos[0], pos[1] + size[1]), (pos[0] + size[0], pos[1] + size[1])) def alter_focus(self, flag): super().alter_focus(flag) self._caret.visible = flag def set_text_style(self, start, end, new_style: dict): self._document.set_style(start, end, new_style) def get_text_style(self, attr, start, end): return self._document.get_style_range(attr, start, end) def _update_caret(self): if self._prev_caret_mark != self._caret.mark or self._prev_caret_position != self._caret.position: self.dispatch_event('on_caret_change', self._caret.mark, self._caret.position) self._prev_caret_position = self._caret.position self._prev_caret_mark = self._caret.mark def handle_mouse_press(self, x, y, button, modifiers): if not self.is_point_within((x, y)): return if self._state != ControlState.FOCUS: self._caret.position = len(self._document.text) else: self._caret.on_mouse_press(x, y, button, modifiers) self._update_caret() def handle_key_release(self, symbol, modifiers): self._modifiers = modifiers def handle_key_press(self, symbol, modifiers): self._modifiers = modifiers self.dispatch_event('on_key_press', symbol, modifiers) if symbol == key.A and modifiers & key.MOD_CTRL: self._caret.position = 0 self._caret.mark = len(self._document.text) self._update_caret() def handle_mouse_drag(self, x, y, dx, dy, button, modifiers): self._caret.on_mouse_drag(x, y, dx, dy, button, modifiers) self._update_caret() def handle_text(self, text): if text[len(text) -1] in ['\r', '\n'] and (self._modifiers & key.MOD_SHIFT or self._modifiers & key.MOD_CTRL): return True before = self._document.text self._caret.on_text(text) self._update_caret() self._render() if before != self._document.text: self.dispatch_event('on_text_change', self._document.text) def handle_text_motion(self, motion): before = self._document.text self._caret.on_text_motion(motion) self._update_caret() self._render() if before != self._document.text: self.dispatch_event('on_text_change', self._document.text) def handle_text_motion_select(self, motion): before = self._document.text self._caret.on_text_motion_select(motion) self._update_caret() self._render() if before != self._document.text: self.dispatch_event('on_text_change', self._document.text) def _apply_style(self): style = self._style state = self._state # Background if "background_color" in style[state]: self.background.set_color(self.get_style(state, "background_color")) # Border for line in self.border: if "border_thickness" in style[state]: line.set_thickness(self.get_style(state, "border_thickness")) if "border_color" in style[state]: line.set_color(self.get_style(state, "border_color"))
class Button(ControlElement, pyglet.event.EventDispatcher): def __init__(self, batch, image_path, position=(0, 0), size=(20, 20), click_event=None, group=None, visible=True): default_style = { ControlState.DEFAULT: { "border_thickness": 1, "border_color": Basic.WHITE1, "background_color": Basic.WHITE_TINGE1, }, ControlState.FOCUS: { "border_color": Basic.NEARWHITE, "background_color": Basic.WHITE_TINGE1 }, ControlState.HOVER: { "border_color": Basic.NEARWHITE, "background_color": Basic.WHITE_TINGE2 }, ControlState.DISABLED: {}, ControlState.PRESSED: { "background_color": Basic.WHITE_TINGE3 } } if click_event: self.push_handlers(on_click=click_event) self._group_back = pyglet.graphics.OrderedGroup(0, group) self._group_front = pyglet.graphics.OrderedGroup(1, group) self.background = Rectangle(batch, position, size, group=self._group_back) self.border = [ Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front) ] self._image_path = image_path self.icon = Image(batch, image_path, position, size, self._group_front, visible) # Base class establishes style ControlElement.__init__(self, batch, default_style, group, position, size, visible) self._render() def delete(self): self.background.delete() for line in self.border: line.delete() self.icon.delete() def handle_mouse_press(self, x, y, button, modifiers): if self.is_point_within((x, y)): self._update_state(ControlState.PRESSED) def handle_mouse_release(self, x, y, button, modifiers): if self._state == ControlState.PRESSED: if self.is_point_within((x, y)): self._update_state(ControlState.HOVER) else: self._update_state(ControlState.FOCUS if self._has_focus else ControlState.DEFAULT) self.dispatch_event('on_click') def alter_focus(self, flag): # Cannot focus disabled or pressed controls if self._state == ControlState.DISABLED or self._state == ControlState.PRESSED: return if flag: if self._state != ControlState.FOCUS: self._update_state(ControlState.FOCUS) self._has_focus = True else: if self._state == ControlState.FOCUS: self._update_state(ControlState.DEFAULT) self._has_focus = False def get_image_path(self): return self._image_path def set_image_path(self, path): self._image_path = path self.icon.delete() self.icon = Image(self.batch, path, self._position, self._size, self._group_front, self._visible) def _render(self): self.background.set_size(self._size) self.background.set_position(self._position) pos = self._position size = self._size self.border[0].set_points(pos, (pos[0] + size[0], pos[1])) self.border[1].set_points((pos[0] + 1, pos[1]), (pos[0] + 1, pos[1] + size[1])) self.border[2].set_points((pos[0] + size[0], pos[1]), (pos[0] + size[0], pos[1] + size[1])) self.border[3].set_points((pos[0], pos[1] + size[1]), (pos[0] + size[0], pos[1] + size[1])) self.icon.set_position(self._position) self.icon.set_size(self._size) def _apply_style(self): style = self._style state = self._state # Background if "background_color" in style[state]: self.background.set_color(self.get_style(state, "background_color")) # Border for line in self.border: if "border_thickness" in style[state]: line.set_thickness(self.get_style(state, "border_thickness")) if "border_color" in style[state]: line.set_color(self.get_style(state, "border_color"))
class Badge(ControlElement, pyglet.event.EventDispatcher): PADDING_WIDTH = 14 PADDING_HEIGHT = 2 def __init__(self, batch, text="badge", click_event=None, position=(0, 0), group=None, visible=True): default_style = { ControlState.DEFAULT: { "border_thickness": 1, "border_color": Basic.PRIMARY, "font_color": Basic.OFFWHITE, "background_color": Basic.WHITE_TINGE1, }, ControlState.HOVER: { "font_color": Basic.NEARWHITE, "background_color": Basic.PRIMARY_BRIGHT_TINGE }, ControlState.DISABLED: {}, ControlState.FOCUS: {}, ControlState.PRESSED: {} } if click_event: self.push_handlers(on_click=click_event) self._group_back = pyglet.graphics.OrderedGroup(0, group) self._group_front = pyglet.graphics.OrderedGroup(1, group) self.label = Label(batch, text=text, group=self._group_front, font_color=Basic.OFFWHITE, font_size=10) size = self.label.get_size( )[0] + Badge.PADDING_WIDTH, self.label.get_size( )[1] + Badge.PADDING_HEIGHT self.background = Rectangle(batch, position, size, group=self._group_back) self.border = [ Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front), Line(batch, group=self._group_front) ] ControlElement.__init__(self, batch, default_style, group, position, size, visible, False) self._render() def handle_mouse_press(self, x, y, button, modifiers): if self.is_point_within((x, y)): self.dispatch_event('on_click') def delete(self): self.background.delete() self.label.delete() for line in self.border: line.delete() def _render(self): self.background.set_size(self._size) self.background.set_position(self._position) pos = self._position size = self._size self.border[0].set_points(pos, (pos[0] + size[0], pos[1])) self.border[1].set_points((pos[0] + 1, pos[1]), (pos[0] + 1, pos[1] + size[1])) self.border[2].set_points((pos[0] + size[0], pos[1]), (pos[0] + size[0], pos[1] + size[1])) self.border[3].set_points((pos[0], pos[1] + size[1]), (pos[0] + size[0], pos[1] + size[1])) self.label.center(pos[0] + size[0] // 2, pos[1] + size[1] // 2) def _apply_style(self): style = self._style state = self._state # Background if "background_color" in style[state]: self.background.set_color(self.get_style(state, "background_color")) # Border for line in self.border: if "border_thickness" in style[state]: line.set_thickness(self.get_style(state, "border_thickness")) if "border_color" in style[state]: line.set_color(self.get_style(state, "border_color")) # Label if "font_color" in style[state]: self.label.set_style( 0, len(self.label.get_text()), dict(color=self.get_style(state, "font_color")))
from swidget import UIElement, Rectangle, Line, Label, Image win = window.Window(width=640, height=480, caption="Test Window") batch = pyglet.graphics.Batch() UIElement.SCREEN_HEIGHT = win.height # Allow transparency calculations gl.glEnable(gl.GL_BLEND) gl.glBlendFunc(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA) group_bkgr = pyglet.graphics.OrderedGroup(0) group_front = pyglet.graphics.OrderedGroup(1) back = Rectangle(batch, group=group_front, position=(50, 50), size=(20, 20), color=(255, 0, 0, 255)) front = Rectangle(batch, group=group_bkgr, position=(60, 60), size=(20, 20), color=(0, 255, 0, 255)) line1 = Line(batch, group=group_front, start=(300, 100), finish=(500, 100), color=(255, 0, 0, 255)) line2 = Line(batch, group=group_front,