Skip to content

Commit

Permalink
Fixes for wx
Browse files Browse the repository at this point in the history
  • Loading branch information
almarklein committed Nov 8, 2024
1 parent 9d9400c commit ffabdbb
Show file tree
Hide file tree
Showing 3 changed files with 39 additions and 26 deletions.
33 changes: 20 additions & 13 deletions examples/wx_app.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
An example demonstrating a wx app with a wgpu viz inside.
"""

import time

import wx
from rendercanvas.wx import RenderWidget

Expand All @@ -13,30 +15,35 @@ def __init__(self):
super().__init__(None, title="wgpu triangle embedded in a wx app")
self.SetSize(640, 480)

splitter = wx.SplitterWindow(self)

# Using present_method 'image' because it reports "The surface texture is suboptimal"
self.canvas = RenderWidget(
self, update_mode="continuous", present_method="image"
)
self.button = wx.Button(self, -1, "Hello world")
self.canvas1 = RenderWidget(splitter)
self.canvas2 = RenderWidget(splitter)

splitter.SplitVertically(self.canvas1, self.canvas2)
splitter.SetSashGravity(0.5)
self.output = wx.StaticText(self)

sizer = wx.BoxSizer(wx.HORIZONTAL)
sizer.Add(self.button, 0, wx.EXPAND)
sizer.Add(splitter, 1, wx.EXPAND)
sizer.Add(self.canvas, 1, wx.EXPAND)
sizer.Add(self.output, 1, wx.EXPAND)
self.SetSizer(sizer)

self.button.Bind(wx.EVT_BUTTON, self.OnClicked)

# Force the canvas to be shown, so that it gets a valid handle.
# Otherwise GetHandle() is initially 0, and getting a surface will fail.
self.Show()

def OnClicked(self, event): # noqa: N802
t = self.output.GetLabel()
t += f"\nClicked at {time.time():0.1f}"
self.output.SetLabel(t)


app = wx.App()
example = Example()

draw_frame1 = setup_drawing_sync(example.canvas1)
draw_frame2 = setup_drawing_sync(example.canvas2)

example.canvas1.request_draw(draw_frame1)
example.canvas2.request_draw(draw_frame2)
draw_frame = setup_drawing_sync(example.canvas)
example.canvas.request_draw(draw_frame)

app.MainLoop()
5 changes: 4 additions & 1 deletion rendercanvas/base.py
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,10 @@ def is_closed(self):

def set_logical_size(self, width, height):
"""Set the window size (in logical pixels)."""
self._rc_set_logical_size(float(width), float(height))
width, height = float(width), float(height)
if width < 0 or height < 0:
raise ValueError("Canvas width and height must not be negative")
self._rc_set_logical_size(width, height)

def set_title(self, title):
"""Set the window title."""
Expand Down
27 changes: 15 additions & 12 deletions rendercanvas/wx.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ def _rc_init(self, present_method=None, **_):
self.Bind(wx.EVT_MOUSE_EVENTS, self._on_mouse_events)
self.Bind(wx.EVT_MOTION, self._on_mouse_move)

self.Show()

def _on_resize_done(self, *args):
self._draw_lock = False
self.Refresh()
Expand Down Expand Up @@ -200,6 +202,11 @@ def _rc_get_loop(self):

def _rc_get_present_info(self):
if self._surface_ids is None:
# On wx it can take a little while for the handle to be available,
# causing GetHandle() to be initially 0, so getting a surface will fail.
etime = time.perf_counter() + 1
while self.GetHandle() == 0 and time.perf_counter() < etime:
loop.process_wx_events()
self._surface_ids = self._get_surface_ids()
global _show_image_method_warning
if self._present_to_screen and self._surface_ids:
Expand Down Expand Up @@ -251,8 +258,7 @@ def _rc_get_pixel_ratio(self):
return self.GetContentScaleFactor()

def _rc_set_logical_size(self, width, height):
if width < 0 or height < 0:
raise ValueError("Window width and height must not be negative")
width, height = int(width), int(height)
parent = self.Parent
if isinstance(parent, WxRenderCanvas):
parent.SetSize(width, height)
Expand All @@ -261,7 +267,11 @@ def _rc_set_logical_size(self, width, height):

def _rc_close(self):
self._is_closed = True
self.Hide()
parent = self.Parent
if isinstance(parent, WxRenderCanvas):
parent.Hide()
else:
self.Hide()

def _rc_is_closed(self):
return self._is_closed
Expand Down Expand Up @@ -415,21 +425,14 @@ class WxRenderCanvas(WrapperRenderCanvas, wx.Frame):

# Most of this is proxying stuff to the inner widget.

def __init__(*args, **kwargs):
def __init__(self, *, parent=None, **kwargs):
loop.init_wx()
super().__init__(*args, **kwargs)
super().__init__(parent, **kwargs)

def _rc_init(self, **canvas_kwargs):
self._subwidget = WxRenderWidget(parent=self, **canvas_kwargs)

self.Bind(wx.EVT_CLOSE, lambda e: self.Destroy())

# Force the canvas to be shown, so that it gets a valid handle.
# Otherwise GetHandle() is initially 0, and getting a surface will fail.
self.Show()
etime = time.perf_counter() + 1
while self._subwidget.GetHandle() == 0 and time.perf_counter() < etime:
loop.process_wx_events()

# wx methods

Expand Down

0 comments on commit ffabdbb

Please sign in to comment.