def __init__(self, content=None, window=None, batch=None, group=None, anchor=ANCHOR_CENTER, offset=(0, 0), parent=None, theme=None, movable=True, on_enter=None, on_escape=None): """ Creates a new dialog. @param content The Widget which we wrap @param window The window to which we belong; used to set the mouse cursor when appropriate. If set, we will add ourself to the window as a handler. @param batch Batch in which we are to place our graphic elements; may be None if we are to create our own Batch @param group Group in which we are to place our graphic elements; may be None @param anchor Anchor point of the window, relative to which we are positioned. If ANCHOR_TOP_LEFT is specified, our top left corner will be aligned to the window's top left corner; if ANCHOR_CENTER is specified, our center will be aligned to the window's center, and so forth. @param offset Offset from the anchor point. A positive X is always to the right, a positive Y to the upward direction. @param theme The Theme which we are to use to generate our graphical appearance. @param movable True if the dialog is able to be moved @param on_enter Callback for when user presses enter on the last input within this dialog, i.e. form submit @param on_escape Callback for when user presses escape """ assert isinstance(theme, dict) Wrapper.__init__(self, content=content) DialogEventManager.__init__(self) self.window = window self.anchor = anchor self.offset = offset self.theme = theme self.is_movable = movable self.on_enter = on_enter self.on_escape = on_escape if batch is None: self.batch = pyglet.graphics.Batch() self.own_batch = True else: self.batch = batch self.own_batch = False self.root_group = DialogGroup(parent=group) self.panel_group = pyglet.graphics.OrderedGroup(0, self.root_group) self.bg_group = pyglet.graphics.OrderedGroup(1, self.root_group) self.fg_group = pyglet.graphics.OrderedGroup(2, self.root_group) self.highlight_group = pyglet.graphics.OrderedGroup(3, self.root_group) self.needs_layout = True self.is_dragging = False if window is None: self.screen = Widget() else: width, height = window.get_size() self.screen = Widget(width=width, height=height) window.push_handlers(self)
def size(self, dialog): """ Recalculate the size of the Scrollable. @param dialog Dialog which contains us """ if dialog is None: return Widget.size(self, dialog) if self.is_fixed_size: self.width, self.height = self.max_width, self.max_height self.hscrollbar_height = dialog.theme["hscrollbar"]["left"]["image"].height self.vscrollbar_width = dialog.theme["vscrollbar"]["up"]["image"].width if self.root_group is None: # do we need to re-clone dialog groups? self.theme = dialog.theme self.batch = dialog.batch self.root_group = ScrollableGroup(0, 0, self.width, self.height, parent=dialog.fg_group) self.panel_group = pyglet.graphics.OrderedGroup(0, self.root_group) self.bg_group = pyglet.graphics.OrderedGroup(1, self.root_group) self.fg_group = pyglet.graphics.OrderedGroup(2, self.root_group) self.highlight_group = pyglet.graphics.OrderedGroup(3, self.root_group) Wrapper.delete(self) # force children to abandon old groups Wrapper.size(self, self) # all children are to use our groups if self.always_show_scrollbars or (self.max_width and self.width > self.max_width): if self.hscrollbar is None: self.hscrollbar = HScrollbar(self.max_width) else: if self.hscrollbar is not None: self.hscrollbar.delete() self.hscrollbar = None if self.always_show_scrollbars or (self.max_height and self.height > self.max_height): if self.vscrollbar is None: self.vscrollbar = VScrollbar(self.max_height) else: if self.vscrollbar is not None: self.vscrollbar.delete() self.vscrollbar = None self.width = min(self.max_width or self.width, self.width) self.content_width = self.width self.height = min(self.max_height or self.height, self.height) self.content_height = self.height if self.hscrollbar is not None: self.hscrollbar.size(dialog) self.hscrollbar.set(self.max_width, max(self.content.width, self.max_width)) self.height += self.hscrollbar.height if self.vscrollbar is not None: self.vscrollbar.size(dialog) self.vscrollbar.set(self.max_height, max(self.content.height, self.max_height)) self.width += self.vscrollbar.width
def delete(self): """ Delete all graphical elements associated with the Scrollable """ Wrapper.delete(self) if self.hscrollbar is not None: self.hscrollbar.delete() self.hscrollbar = None if self.vscrollbar is not None: self.vscrollbar.delete() self.vscrollbar = None self.root_group = None self.panel_group = None self.bg_group = None self.fg_group = None self.highlight_group = None
def __init__(self, content=None, width=None, height=None, is_fixed_size=False, always_show_scrollbars=False): """ Creates a new Scrollable. @param content The layout or Widget to be scrolled @param width Maximum width, or None @param height Maximum height, or None @param is_fixed_size True if we should always be at maximum size; otherwise we shrink to match our content @param always_show_scrollbars True if we should always show scrollbars """ if is_fixed_size: assert width is not None and height is not None Wrapper.__init__(self, content) self.max_width = width self.max_height = height self.is_fixed_size = is_fixed_size self.always_show_scrollbars = always_show_scrollbars self.hscrollbar = None self.vscrollbar = None self.content_width = 0 self.content_height = 0 self.content_x = 0 self.content_y = 0 self.hscrollbar_height = 0 self.vscrollbar_width = 0 # We emulate some aspects of Dialog here. We cannot just inherit # from Dialog because pyglet event handling won't allow keyword # arguments to be passed through. self.theme = None self.batch = None self.root_group = None self.panel_group = None self.bg_group = None self.fg_group = None self.highlight_group = None self.needs_layout = False
def _get_controls(self): """ We represent ourself as a Control to the Dialog, but we pass through the events we receive from Dialog. """ base_controls = Wrapper._get_controls(self) controls = [] our_left = self.content_x our_right = our_left + self.content_width our_bottom = self.content_y our_top = our_bottom + self.content_height for control, left, right, top, bottom in base_controls: controls.append((control, max(left, our_left), min(right, our_right), min(top, our_top), max(bottom, our_bottom))) if self.hscrollbar is not None: controls += self.hscrollbar._get_controls() if self.vscrollbar is not None: controls += self.vscrollbar._get_controls() return controls
def _get_controls(self): """ We represent ourself as a Control to the Dialog, but we pass through the events we receive from Dialog. """ base_controls = Wrapper._get_controls(self) controls = [] our_left = self.content_x our_right = our_left + self.content_width our_bottom = self.content_y our_top = our_bottom + self.content_height for control, left, right, top, bottom in base_controls: controls.append( (control, max(left, our_left), min(right, our_right), min(top, our_top), max(bottom, our_bottom)) ) if self.hscrollbar is not None: controls += self.hscrollbar._get_controls() if self.vscrollbar is not None: controls += self.vscrollbar._get_controls() return controls
def size(self, dialog): """ Recalculate the size of the Scrollable. @param dialog Dialog which contains us """ if dialog is None: return Widget.size(self, dialog) if self.is_fixed_size: self.width, self.height = self.max_width, self.max_height self.hscrollbar_height = \ dialog.theme['hscrollbar']['left']['image'].height self.vscrollbar_width = \ dialog.theme['vscrollbar']['up']['image'].width if self.root_group is None: # do we need to re-clone dialog groups? self.theme = dialog.theme self.batch = dialog.batch self.root_group = ScrollableGroup(0, 0, self.width, self.height, parent=dialog.fg_group) self.panel_group = pyglet.graphics.OrderedGroup(0, self.root_group) self.bg_group = pyglet.graphics.OrderedGroup(1, self.root_group) self.fg_group = pyglet.graphics.OrderedGroup(2, self.root_group) self.highlight_group = pyglet.graphics.OrderedGroup( 3, self.root_group) Wrapper.delete(self) # force children to abandon old groups Wrapper.size(self, self) # all children are to use our groups if self.always_show_scrollbars or \ (self.max_width and self.width > self.max_width): if self.hscrollbar is None: self.hscrollbar = HScrollbar(self.max_width) else: if self.hscrollbar is not None: self.hscrollbar.delete() self.hscrollbar = None if self.always_show_scrollbars or \ (self.max_height and self.height > self.max_height): if self.vscrollbar is None: self.vscrollbar = VScrollbar(self.max_height) else: if self.vscrollbar is not None: self.vscrollbar.delete() self.vscrollbar = None self.width = min(self.max_width or self.width, self.width) self.content_width = self.width self.height = min(self.max_height or self.height, self.height) self.content_height = self.height if self.hscrollbar is not None: self.hscrollbar.size(dialog) self.hscrollbar.set(self.max_width, max(self.content.width, self.max_width)) self.height += self.hscrollbar.height if self.vscrollbar is not None: self.vscrollbar.size(dialog) self.vscrollbar.set(self.max_height, max(self.content.height, self.max_height)) self.width += self.vscrollbar.width