Exemplo n.º 1
0
def bindHelpEvent(helpId: str, window: wx.Window):
	window.Unbind(wx.EVT_HELP)
	window.Bind(
		wx.EVT_HELP,
		lambda evt: _onEvtHelp(helpId, evt),
	)
	log.debug(f"Did context help binding for {window.__class__.__qualname__}")
Exemplo n.º 2
0
    def ScrollChildIntoView(self, child: wx.Window) -> None:
        """
		Overrides child.GetRect with `GetChildRectRelativeToSelf` before calling
		`super().ScrollChildIntoView`. `super().ScrollChildIntoView` incorrectly uses child.GetRect to
		navigate scrolling, which is relative to the parent, where it should instead be relative to this
		ScrolledPanel.
		"""
        oldChildGetRectFunction = child.GetRect
        child.GetRect = lambda: self.GetChildRectRelativeToSelf(child)
        try:
            super().ScrollChildIntoView(child)
        finally:
            # ensure child.GetRect is reset properly even if super().ScrollChildIntoView throws an exception
            child.GetRect = oldChildGetRectFunction
Exemplo n.º 3
0
def _set_dark_mode(window: wx.Window, enabled: bool) -> None:
    if enabled:
        bg = wx.Colour(40, 40, 40)
        fg = wx.Colour(255, 255, 255)
    else:
        bg = wx.NullColour
        fg = wx.NullColour
    window.SetBackgroundColour(bg)
    window.SetForegroundColour(fg)
    for child in window.Children:
        if isinstance(child, wx.stc.StyledTextCtrl):
            set_stc_dark_mode(child, enabled)
        else:
            _set_dark_mode(child, enabled)
    window.Refresh()
Exemplo n.º 4
0
    def __init__(self,
                 parent: Window,
                 displayText: str,
                 valueChangedCallback: Callable,
                 minValue: int = DEFAULT_MIN_VALUE,
                 maxValue: int = DEFAULT_MAX_VALUE):
        """

        Args:
            parent          The parent window
            displayText:    The text to display as the static box title
            valueChangedCallback:  The method to call when the value changes;  The method should expect the
                                   first parameter to be an object of type SpinnerValues
            minValue:       The minimum value for the width/height
            maxValue:       The maximum value for the width/height

        """
        self.logger: Logger = getLogger(__name__)
        self.__callback: Callable = valueChangedCallback

        box: StaticBox = StaticBox(parent, ID_ANY, displayText)

        super().__init__(box, HORIZONTAL)

        self._wxValue0SpinnerId: int = wxNewIdRef()
        self._wxValue1SpinnerId: int = wxNewIdRef()

        self._scValue0: SpinCtrl = SpinCtrl(parent, self._wxValue0SpinnerId,
                                            "",
                                            (SPINNER_WIDTH, SPINNER_HEIGHT))
        self._scValue1: SpinCtrl = SpinCtrl(parent, self._wxValue1SpinnerId,
                                            "",
                                            (SPINNER_WIDTH, SPINNER_HEIGHT))

        self.Add(self._scValue0, 0, ALL, DualSpinnerContainer.HORIZONTAL_GAP)
        self.Add(self._scValue1, 0, ALL, DualSpinnerContainer.HORIZONTAL_GAP)

        self._scValue0.SetRange(minValue, maxValue)
        self._scValue1.SetRange(minValue, maxValue)

        parent.Bind(EVT_SPINCTRL,
                    self.__onSpinnerValueChanged,
                    id=self._wxValue0SpinnerId)
        parent.Bind(EVT_SPINCTRL,
                    self.__onSpinnerValueChanged,
                    id=self._wxValue1SpinnerId)

        self._spinnerValues: SpinnerValues = SpinnerValues(minValue, minValue)
Exemplo n.º 5
0
    def __init__(self, parent: Window, labelText: str,
                 valueChangedCallback: Callable):
        """

        Args:
            parent:     The parent window
            labelText:  How to label the text input
            valueChangedCallback:  The method to call when the value changes;  The method should expect the
            first parameter to be a string argument that is the new value
        """

        super().__init__(HORIZONTAL)

        self._textId: int = wxNewIdRef()

        self._callback: Callable = valueChangedCallback

        textLabel: StaticText = StaticText(parent, ID_ANY, labelText)
        textControl: TextCtrl = TextCtrl(parent, self._textId)

        self.Add(textLabel, WX_SIZER_CHANGEABLE, ALL | ALIGN_CENTER_VERTICAL,
                 TextContainer.HORIZONTAL_GAP)
        self.Add(textControl, WX_SIZER_CHANGEABLE, ALL,
                 TextContainer.HORIZONTAL_GAP)

        self._textControl: TextCtrl = textControl
        self._textValue: str = ''

        parent.Bind(EVT_TEXT, self._onTextValueChanged, id=self._textId)
Exemplo n.º 6
0
def create_menu_item(
    parent: wx.Window,
    menu: wx.Menu,
    text: str,
    tooltip: str = '',
    icon_image: Optional[Image.Image] = None,
    id: int = wx.ID_ANY,
    callback: Optional[Callable] = None,
):
    """Create menu item

    The tooltip is actually not visible, menu items with tooltips are not
    supported by WxWidgets.
    """
    menu_item = wx.MenuItem(menu, id, text, helpString=tooltip)
    if icon_image:
        bitmap = image_to_bitmap(icon_image)
        menu_item.SetBitmap(bitmap)
    menu.Append(menu_item)
    if callback:
        parent.Bind(wx.EVT_MENU,
                    partial(on_menu_item, callback=callback),
                    id=id)
    else:
        menu_item.Enable(False)
    return menu_item
Exemplo n.º 7
0
    def __init__(self, parent: wx.Window):
        display_attributes = wx.glcanvas.GLAttributes()
        display_attributes.PlatformDefaults().MinRGBA(
            8, 8, 8, 8).DoubleBuffer().Depth(24).EndList()
        super().__init__(
            parent,
            display_attributes,
            size=parent.GetClientSize(),
            style=wx.WANTS_CHARS,
        )

        if sys.platform == "linux":
            # setup the OpenGL context. This apparently fixes #84
            self._context = glcanvas.GLContext(self)
        else:
            context_attributes = wx.glcanvas.GLContextAttrs()
            context_attributes.CoreProfile().OGLVersion(
                3, 3).Robust().ResetIsolation().EndList()
            self._context = glcanvas.GLContext(
                self, ctxAttrs=context_attributes)  # setup the OpenGL context
        self.SetCurrent(self._context)
        self._context_identifier = str(
            uuid.uuid4())  # create a UUID for the context. Used to get shaders
        self._gl_texture_atlas = glGenTextures(
            1)  # Create the atlas texture location
        self._setup_opengl()  # set some OpenGL states
Exemplo n.º 8
0
    def get_parameters_helper(self):
        """
        Helper method to launch get_parameters_from_script on a thread so that it isn't run on the GUI thread, since
        it may be slow (when initializing pyimagej).
        """
        # Reset previously parsed parameters
        self.clear_script_parameters()

        global stop_progress_thread
        stop_progress_thread = False

        progress_gauge = Gauge(Window.FindFocus(), -1, size=(100, -1))
        progress_gauge.Show(True)

        parse_param_thread = Thread(target=self.get_parameters_from_script, name="Parse Parameters Thread", daemon=True)
        parse_param_thread.start()

        while True:
            # Wait for get_parameters_from_script to finish
            progress_gauge.Pulse()
            time.sleep(0.025)
            if stop_progress_thread:
                progress_gauge.Show(False)
                break

        if not self.initialization_failed:
            self.parsed_params = True
Exemplo n.º 9
0
 def _enable_operation_ui(self, ui: wx.Window):
     self._hide_all()
     self._shown_ui = ui
     self.Show()
     ui.Show()
     self._canvas().select_mode = 1
     self.Fit()
Exemplo n.º 10
0
    def __init__(self, window: wx.Window, size: int) -> None:
        super().__init__()
        self._face = freetype.Face(_FONT_PATH)
        self._face.set_char_size(size * 64)
        self._glyphs = {}  # type: typing.Dict[str, _Glyph]

        window.Bind(wx.EVT_WINDOW_DESTROY, self._OnWindowDestroy)
Exemplo n.º 11
0
 def get_children(window: wx.Window):
     my_children = window.GetChildren()
     if my_children is not None:
         their_children = []
         for my_child in my_children:
             their_children += get_children(my_child)
         return list(my_children) + their_children
     else:
         return []
Exemplo n.º 12
0
 def __init__(self, canvas: wx.Window, text: str, header: str):
     self.text = text
     self.canvas = canvas
     self.font = canvas.GetFont()
     if header == "h1":
         self.font.SetPointSize(16)
     elif header == "h2":
         self.font.SetPointSize(12)
     else:
         raise KeyError("Unknown header type. Either h1 or h2")
     self.rect = wx.Rect(0, 0, 0, 0)
Exemplo n.º 13
0
    def GetChildRectRelativeToSelf(self, child: wx.Window) -> wx.Rect:
        """
		window.GetRect returns the size of a window, and its position relative to its parent.
		When calculating ScrollChildIntoView, the position relative to its parent is not relevant unless the
		parent is the ScrolledPanel itself. Instead, calculate the position relative to scrolledPanel
		"""
        childRectRelativeToScreen = child.GetScreenRect()
        scrolledPanelScreenPosition = self.GetScreenPosition()
        return wx.Rect(
            childRectRelativeToScreen.x - scrolledPanelScreenPosition.x,
            childRectRelativeToScreen.y - scrolledPanelScreenPosition.y,
            childRectRelativeToScreen.width, childRectRelativeToScreen.height)
Exemplo n.º 14
0
def populate_output_fields(parent: wx.Window, fields: dict) -> None:
    '''Find text fields by name and set their text to str(value).
    Fields must be derived from wx.TextEntry
    Arguments:
        parent: The parent window
        fields: { name: value }'''
    for name, value in fields.items():
        window = parent.FindWindowByName(name)
        if window and isinstance(window, wx.TextEntry):
            window.SetValue(str(value))
        else:
            raise Exception(f'Could not populate output field: {name}, {value}')
    def __init__(self, parent: wx.Window, open_world_callback: Callable[[str], None]):
        super().__init__(
            parent,
            title="World Select",
            pos=wx.Point(50, 50),
            size=wx.Size(*[int(s * 0.95) for s in parent.GetSize()]),
            style=wx.CAPTION | wx.CLOSE_BOX | wx.MAXIMIZE_BOX
            # | wx.MAXIMIZE
            | wx.SYSTEM_MENU | wx.TAB_TRAVERSAL | wx.CLIP_CHILDREN | wx.RESIZE_BORDER,
        )
        self.Bind(wx.EVT_CLOSE, self._hide_event)

        self._open_world_callback = open_world_callback
        self.world_select = WorldSelectAndRecentUI(self, self._run_callback)
Exemplo n.º 16
0
    def __init__(self, parent: wx.Window):
        attribs = (glcanvas.WX_GL_CORE_PROFILE, glcanvas.WX_GL_RGBA,
                   glcanvas.WX_GL_DOUBLEBUFFER, glcanvas.WX_GL_DEPTH_SIZE, 24)
        super().__init__(parent,
                         -1,
                         size=parent.GetClientSize(),
                         attribList=attribs)
        self._context = glcanvas.GLContext(self)  # setup the OpenGL context
        self.SetCurrent(self._context)
        self.context_identifier = str(
            uuid.uuid4())  # create a UUID for the context. Used to get shaders
        self._gl_texture_atlas = glGenTextures(
            1)  # Create the atlas texture location
        self._setup_opengl()  # set some OpenGL states

        self._transformation_matrix: Optional[numpy.ndarray] = None
Exemplo n.º 17
0
 def __init__(self, parent: wx.Window, installed: List[Plugin],
              plugin_dir: str):
     super().__init__(parent)
     self.plugin_dir = plugin_dir
     html = '<h2>{title}</h2>'.format(title="Browse Plugins")
     self.SetPage(html)
     installed_names = dict()
     for p in installed:
         installed_names.update({p.metadata.name: p})
     try:
         # for just displaying info
         r = requests.get(
             'https://raw.githubusercontent.com/samuels342/PyRKViewer-Plugins/main/metadata.json'
         )
         metadata = r.json()
         for m in metadata:
             item = '''
                     <div>
                     <h3>{name}</h3>
                     <br>{author}|v{version}
                     <p>{long_desc}</p>
                     '''.format(name=metadata[m]['name'],
                                author=metadata[m]['author'],
                                version=metadata[m]['version'],
                                long_desc=metadata[m]['long_desc'])
             if metadata[m]['name'] in installed_names:
                 prev_install = installed_names[metadata[m]['name']]
                 if not prev_install.metadata.version == metadata[m][
                         'version']:
                     item += '''
                             <div align="right">v{v} Installed<br>
                             <a href={file}>Update</a></div>
                             '''.format(v=prev_install.metadata.version,
                                        file=m)
                 else:
                     item += '''
                             <div align="right">v{v} Installed</div>
                             '''.format(v=prev_install.metadata.version)
             else:
                 item += '<div align="right"><a href={file}>Install</a></div>'.format(
                     file=m)
             item += '</div><hr>'
             self.AppendToPage(item)
     except:  # TODO define error, checking if there is internet connection
         html = '<h2>Browse Plugins</h2><p>Could not connect to server, please try again later!</p>'
         self.SetPage(html)
     self.SetBackgroundColour(parent.GetBackgroundColour())
Exemplo n.º 18
0
def parse_input_fields(parent: wx.Window, fields: list, convert: type = None) -> dict:
    '''Find text input fields by name and collect their values.
    Fields must be derived from wx.TextEntry
    Arguments:
        parent: The parent window
        fields: [{ name: window name}]
        type:   convert values to the provided type
    Return:
        result: { name: value (str) }'''
    result = {}
    for field in fields:
        window = parent.FindWindowByName(field['name'])
        if window and isinstance(window, wx.TextEntry):
            if convert:
                result[field['name']] = convert(window.GetValue())
            else:
                result[field['name']] = window.GetValue()
        else:
            raise Exception(f'Could not parse input field: {field["name"]}')
    return result
Exemplo n.º 19
0
    def __init__(self, parent: wx.Window, plugin: Plugin):
        super().__init__(parent)

        html = '''
        <h3>{name}</h3>
        <div>{author}|v{version}</div>
        <hr/>
        <div>
            {description}
        </div>
        '''.format(
            name=plugin.metadata.name,
            version=plugin.metadata.version,
            author=plugin.metadata.author,
            description=plugin.metadata.long_desc,
        )

        self.SetPage(html)
        # inherit parent background color for better look
        self.SetBackgroundColour(parent.GetBackgroundColour())
Exemplo n.º 20
0
    def __init__(self, parent: wx.Window):
        display_attributes = wx.glcanvas.GLAttributes()
        display_attributes.PlatformDefaults().MinRGBA(
            8, 8, 8, 8).DoubleBuffer().Depth(24).EndList()
        super().__init__(parent,
                         display_attributes,
                         size=parent.GetClientSize())
        self._projection = [70.0, 4 / 3, 0.1, 10000.0]
        context_attributes = wx.glcanvas.GLContextAttrs()
        context_attributes.CoreProfile().OGLVersion(
            3, 3).Robust().ResetIsolation().EndList()
        self._context = glcanvas.GLContext(
            self, ctxAttrs=context_attributes)  # setup the OpenGL context
        self.SetCurrent(self._context)
        self._context_identifier = str(
            uuid.uuid4())  # create a UUID for the context. Used to get shaders
        self._gl_texture_atlas = glGenTextures(
            1)  # Create the atlas texture location
        self._setup_opengl()  # set some OpenGL states

        self._transformation_matrix: Optional[numpy.ndarray] = None
Exemplo n.º 21
0
 def __init__(self, master: wx.Window):
     super().__init__(parent=master, size=master.GetSize())
     Browser.instance = self
     self.loadPackages()
Exemplo n.º 22
0
def autoThaw(control: wx.Window):
    control.Freeze()
    yield
    control.Thaw()
Exemplo n.º 23
0
 def listenForEnableChanged(self, _ctrl: wx.Window):
     self.Bind(wx.EVT_WINDOW_DESTROY, self._onDestroy)
     _ctrl.Bind(LabeledControlHelper.EVT_ENABLE_CHANGED,
                self._onEnableChanged)
     self.isListening = True
Exemplo n.º 24
0
def patch(dom: wx.Window, vdom):
    parent = dom.GetParent()
    try:
        # if parent:
        #     parent.Freeze()
        if not isclass(vdom['type']):
            # because stateless functions are just opaque wrappers
            # they have no relevant diffing logic -- there is no
            # associated top-level WX element produced from a SFC, only
            # their inner contents matter. As such, we evaluate it and
            # push the result back into `patch`
            return patch(dom, vdom['type'](vdom['props']))
        if isclass(vdom['type']) and issubclass(vdom['type'], Component):
            return Component.patch_component(dom, vdom)
        elif not isinstance(dom, vdom['type']):
            for child in dom.GetChildren():
                dom.RemoveChild(child)
                child.Destroy()
            dom.Destroy()
            newdom = render(vdom, parent)
        elif isinstance(dom, vdom['type']):
            update(vdom, dom)
            pool = {
                f'__index_{index}': child
                for index, child in enumerate(dom.GetChildren())
            }
            for index, child in enumerate(vdom['props'].get('children', [])):
                key = f'__index_{index}'
                if key in pool:
                    patch(pool[key], child)
                    del pool[key]
                else:
                    # TODO: this IS the addition case, right?
                    # why would I need this removeChild line..?
                    if key in pool:
                        # if we're adding something new to the
                        # tree, it won't be present in the pool
                        parent.RemoveChild(pool[key])
                    # TODO: need to understand this case more
                    # if we're not updating, we're adding
                    # in which case.. why doesn't this fall to the
                    # `dom` instance..?
                    inst = render(child, dom)
                    if dom.GetSizer():
                        dom.GetSizer().Add(inst,
                                           child['props'].get('proportion', 0),
                                           child['props'].get('flag', 0),
                                           child['props'].get('border', 0))
            # any keys which haven't been removed in the
            # above loop represent wx.Objects which are no longer
            # part of the virtualdom and should thus be removed.
            for key, orphan in pool.items():
                dom.RemoveChild(orphan)
                orphan.Destroy()

            newdom = dom
        else:
            raise Exception("unexpected case!")
        p = parent
        while p:
            p.Layout()
            p = p.GetParent()
        return newdom
    finally:
        # TODO: we sometimes call parent.Thaw() when
        # parent isn't frozen. I think this has something
        # to do with the child removal case. Not sure tho
        # if parent and parent.IsFrozen():
        #     parent.Thaw()
        pass
Exemplo n.º 25
0
def patch(dom: wx.Window, vdom):
    parent = dom.GetParent()
    try:
        # if parent:
        #     parent.Freeze()
        if not isclass(vdom['type']):
            # because stateless functions are just opaque wrappers
            # they have no relevant diffing logic -- there is no
            # associated top-level WX element produced from a SFC, only
            # their inner contents matter. As such, we evaluate it and
            # push the result back into `patch`
            return patch(dom, vdom['type'](vdom['props']))
        if isclass(vdom['type']) and issubclass(vdom['type'], Component):
            return Component.patch_component(dom, vdom)
        elif not isinstance(dom, vdom['type']):
            for child in dom.GetChildren():
                dom.RemoveChild(child)
                child.Destroy()
            dom.Destroy()
            newdom = render(vdom, parent)
        elif isinstance(dom, vdom['type']) and getattr(dom, 'self_managed', False):
            # self-managed components manage their children by hand rather than
            # automatically via the rewx dom. As such, we don't perform any child
            # diffing or reconciliation operations for them. The virtualdom will NOT
            # match the actual dom for these widgets.
            #
            # Background: These components are legacy/vanilla wx components the user created
            # which have been introduced into rewx land through custom mount/update handlers.
            # These are commonly used while porting over existing code or for wx components
            # which are sufficiently cranky about their child management.
            update(vdom, dom)
            newdom = dom
        elif isinstance(dom, vdom['type']):
            update(vdom, dom)
            pool = {f'__index_{index}': child for index, child in enumerate(dom.GetChildren())}
            for index, child in enumerate(vdom['props'].get('children', [])):
                key = f'__index_{index}'
                if key in pool:
                    patch(pool[key], child)
                    del pool[key]
                else:
                    # TODO: this IS the addition case, right?
                    # why would I need this removeChild line..?
                    if key in pool:
                        # if we're adding something new to the
                        # tree, it won't be present in the pool
                        parent.RemoveChild(pool[key])
                    # TODO: need to understand this case more
                    # if we're not updating, we're adding
                    # in which case.. why doesn't this fall to the
                    # `dom` instance..?
                    inst = render(child, dom)
                    if dom.GetSizer():
                        dom.GetSizer().Add(
                            inst,
                            child['props'].get('proportion', 0),
                            child['props'].get('flag', 0),
                            child['props'].get('border', 0)
                        )
            # any keys which haven't been removed in the
            # above loop represent wx.Objects which are no longer
            # part of the virtualdom and should thus be removed.
            for key, orphan in pool.items():
                # Debugging InspectionFrame gets lumped in with the
                # top-level hierarchy. We want to leave this alone as
                # it's there for debugging and not part of the actual
                # declared component tree
                if not isinstance(orphan, wx.lib.inspection.InspectionFrame):
                    dom.RemoveChild(orphan)
                    orphan.Destroy()

            newdom = dom
        else:
            raise Exception("unexpected case!")
        p = parent
        while p:
            p.Layout()
            p = p.GetParent()
        return newdom
    finally:
        # TODO: we sometimes call parent.Thaw() when
        # parent isn't frozen. I think this has something
        # to do with the child removal case. Not sure tho
        # if parent and parent.IsFrozen():
        #     parent.Thaw()
        pass