Commit b2b44bbce25c29014365a92693b5eead20f29975
Committed by
GitHub
1 parent
535a568f
Exists in
master
Mac M1 HighDPI display (#421)
* Doing some tests * Drawing texts on canvas scaled by GetContentScaleFactor * Created a method to get mouse position * Using GetMousePosition() on slice editor * Using GetMousePosition() on watershed style * Using GetMousePosition() on image reorientation * Using GetMousePosition() on mask filling * Using GetMousePosition() on mask crop * Using GetMousePosition() on cross * Using GetMousePosition() on WW&WL * Using GetMousePosition() on mouse scroll * Using GetMousePosition() on region growing * Using GetMousePosition() on editor * created a method to get vtk mouse position on viewer slice * using get_vtk_mouse_position on canvas renderer * using get_vtk_mouse_position on slice styles * Removed unneed prints * Using WX to get Mouse position on vtk renderer * Using get_vtk_mouse_position on viewer_volume * Added a comment to explain the problem with highdpi display on mac * Scalling WW&WL text on ViewerVolume
Showing
6 changed files
with
123 additions
and
67 deletions
Show diff stats
invesalius/data/styles.py
... | ... | @@ -77,6 +77,8 @@ WATERSHED_OPERATIONS = {_("Erase"): BRUSH_ERASE, |
77 | 77 | |
78 | 78 | class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage): |
79 | 79 | def __init__(self, viewer): |
80 | + self.viewer = viewer | |
81 | + | |
80 | 82 | self.right_pressed = False |
81 | 83 | self.left_pressed = False |
82 | 84 | self.middle_pressed = False |
... | ... | @@ -110,6 +112,22 @@ class BaseImageInteractorStyle(vtk.vtkInteractorStyleImage): |
110 | 112 | def OnMiddleButtonReleaseEvent(self, evt, obj): |
111 | 113 | self.middle_pressed = False |
112 | 114 | |
115 | + def GetMousePosition(self): | |
116 | + mx, my = self.viewer.get_vtk_mouse_position() | |
117 | + return mx, my | |
118 | + | |
119 | + def GetPickPosition(self, mouse_position=None): | |
120 | + if mouse_position is None: | |
121 | + mx, my = self.GetMousePosition() | |
122 | + else: | |
123 | + mx, my = mouse_position | |
124 | + iren = self.viewer.interactor | |
125 | + render = iren.FindPokedRenderer(mx, my) | |
126 | + self.picker.Pick(mx, my, 0, render) | |
127 | + x, y, z = self.picker.GetPickPosition() | |
128 | + return (x, y, z) | |
129 | + | |
130 | + | |
113 | 131 | |
114 | 132 | class DefaultInteractorStyle(BaseImageInteractorStyle): |
115 | 133 | """ |
... | ... | @@ -277,7 +295,7 @@ class BaseImageEditionInteractorStyle(DefaultInteractorStyle): |
277 | 295 | |
278 | 296 | viewer._set_editor_cursor_visibility(1) |
279 | 297 | |
280 | - mouse_x, mouse_y = iren.GetEventPosition() | |
298 | + mouse_x, mouse_y = self.GetMousePosition() | |
281 | 299 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
282 | 300 | slice_data = viewer.get_slice_data(render) |
283 | 301 | |
... | ... | @@ -316,7 +334,7 @@ class BaseImageEditionInteractorStyle(DefaultInteractorStyle): |
316 | 334 | |
317 | 335 | viewer._set_editor_cursor_visibility(1) |
318 | 336 | |
319 | - mouse_x, mouse_y = iren.GetEventPosition() | |
337 | + mouse_x, mouse_y = self.GetMousePosition() | |
320 | 338 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
321 | 339 | slice_data = viewer.get_slice_data(render) |
322 | 340 | operation = self.config.operation |
... | ... | @@ -486,7 +504,7 @@ class CrossInteractorStyle(DefaultInteractorStyle): |
486 | 504 | self.ChangeCrossPosition(iren) |
487 | 505 | |
488 | 506 | def ChangeCrossPosition(self, iren): |
489 | - mouse_x, mouse_y = iren.GetEventPosition() | |
507 | + mouse_x, mouse_y = self.GetMousePosition() | |
490 | 508 | x, y, z = self.viewer.get_coordinate_cursor(mouse_x, mouse_y, self.picker) |
491 | 509 | self.viewer.UpdateSlicesPosition([x, y, z]) |
492 | 510 | # This "Set cross" message is needed to update the cross in the other slices |
... | ... | @@ -626,7 +644,7 @@ class WWWLInteractorStyle(DefaultInteractorStyle): |
626 | 644 | def OnWindowLevelMove(self, obj, evt): |
627 | 645 | if (self.left_pressed): |
628 | 646 | iren = obj.GetInteractor() |
629 | - mouse_x, mouse_y = iren.GetEventPosition() | |
647 | + mouse_x, mouse_y = self.GetMousePosition() | |
630 | 648 | self.acum_achange_window += mouse_x - self.last_x |
631 | 649 | self.acum_achange_level += mouse_y - self.last_y |
632 | 650 | self.last_x, self.last_y = mouse_x, mouse_y |
... | ... | @@ -713,7 +731,7 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): |
713 | 731 | def OnInsertMeasurePoint(self, obj, evt): |
714 | 732 | slice_number = self.slice_data.number |
715 | 733 | x, y, z = self._get_pos_clicked() |
716 | - mx, my = self.viewer.interactor.GetEventPosition() | |
734 | + mx, my = self.GetMousePosition() | |
717 | 735 | |
718 | 736 | if self.selected: |
719 | 737 | self.selected = None |
... | ... | @@ -784,7 +802,7 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): |
784 | 802 | self.viewer.UpdateCanvas() |
785 | 803 | |
786 | 804 | else: |
787 | - mx, my = self.viewer.interactor.GetEventPosition() | |
805 | + mx, my = self.GetMousePosition() | |
788 | 806 | if self._verify_clicked_display(mx, my): |
789 | 807 | self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_HAND)) |
790 | 808 | else: |
... | ... | @@ -801,12 +819,8 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): |
801 | 819 | self.viewer.scroll_enabled = True |
802 | 820 | |
803 | 821 | def _get_pos_clicked(self): |
804 | - iren = self.viewer.interactor | |
805 | - mx,my = iren.GetEventPosition() | |
806 | - render = iren.FindPokedRenderer(mx, my) | |
807 | 822 | self.picker.AddPickList(self.slice_data.actor) |
808 | - self.picker.Pick(mx, my, 0, render) | |
809 | - x, y, z = self.picker.GetPickPosition() | |
823 | + x, y, z = self.GetPickPosition() | |
810 | 824 | self.picker.DeletePickList(self.slice_data.actor) |
811 | 825 | return (x, y, z) |
812 | 826 | |
... | ... | @@ -919,11 +933,11 @@ class DensityMeasureStyle(DefaultInteractorStyle): |
919 | 933 | |
920 | 934 | def _pick_position(self): |
921 | 935 | iren = self.viewer.interactor |
922 | - mx, my = iren.GetEventPosition() | |
936 | + mx, my = self.GetMousePosition() | |
923 | 937 | return (mx, my) |
924 | 938 | |
925 | 939 | def _get_pos_clicked(self): |
926 | - mouse_x, mouse_y = self._pick_position() | |
940 | + mouse_x, mouse_y = self.GetMousePosition() | |
927 | 941 | position = self.viewer.get_coordinate_cursor(mouse_x, mouse_y, self.picker) |
928 | 942 | return position |
929 | 943 | |
... | ... | @@ -1232,15 +1246,14 @@ class EditorInteractorStyle(DefaultInteractorStyle): |
1232 | 1246 | self.viewer.slice_data.cursor.Show(0) |
1233 | 1247 | |
1234 | 1248 | def SetUp(self): |
1235 | - | |
1236 | 1249 | x, y = self.viewer.interactor.ScreenToClient(wx.GetMousePosition()) |
1237 | 1250 | if self.viewer.interactor.HitTest((x, y)) == wx.HT_WINDOW_INSIDE: |
1238 | 1251 | self.viewer.slice_data.cursor.Show() |
1239 | - | |
1252 | + | |
1240 | 1253 | y = self.viewer.interactor.GetSize()[1] - y |
1241 | 1254 | w_x, w_y, w_z = self.viewer.get_coordinate_cursor(x, y, self.picker) |
1242 | 1255 | self.viewer.slice_data.cursor.SetPosition((w_x, w_y, w_z)) |
1243 | - | |
1256 | + | |
1244 | 1257 | self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_BLANK)) |
1245 | 1258 | self.viewer.interactor.Render() |
1246 | 1259 | |
... | ... | @@ -1319,7 +1332,7 @@ class EditorInteractorStyle(DefaultInteractorStyle): |
1319 | 1332 | |
1320 | 1333 | viewer._set_editor_cursor_visibility(1) |
1321 | 1334 | |
1322 | - mouse_x, mouse_y = iren.GetEventPosition() | |
1335 | + mouse_x, mouse_y = self.GetMousePosition() | |
1323 | 1336 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
1324 | 1337 | slice_data = viewer.get_slice_data(render) |
1325 | 1338 | |
... | ... | @@ -1351,7 +1364,7 @@ class EditorInteractorStyle(DefaultInteractorStyle): |
1351 | 1364 | |
1352 | 1365 | viewer._set_editor_cursor_visibility(1) |
1353 | 1366 | |
1354 | - mouse_x, mouse_y = iren.GetEventPosition() | |
1367 | + mouse_x, mouse_y = self.GetMousePosition() | |
1355 | 1368 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
1356 | 1369 | slice_data = viewer.get_slice_data(render) |
1357 | 1370 | |
... | ... | @@ -1402,7 +1415,7 @@ class EditorInteractorStyle(DefaultInteractorStyle): |
1402 | 1415 | iren = self.viewer.interactor |
1403 | 1416 | viewer = self.viewer |
1404 | 1417 | if iren.GetControlKey(): |
1405 | - mouse_x, mouse_y = iren.GetEventPosition() | |
1418 | + mouse_x, mouse_y = self.GetMousePosition() | |
1406 | 1419 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
1407 | 1420 | slice_data = self.viewer.get_slice_data(render) |
1408 | 1421 | cursor = slice_data.cursor |
... | ... | @@ -1420,7 +1433,7 @@ class EditorInteractorStyle(DefaultInteractorStyle): |
1420 | 1433 | iren = self.viewer.interactor |
1421 | 1434 | viewer = self.viewer |
1422 | 1435 | if iren.GetControlKey(): |
1423 | - mouse_x, mouse_y = iren.GetEventPosition() | |
1436 | + mouse_x, mouse_y = self.GetMousePosition() | |
1424 | 1437 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
1425 | 1438 | slice_data = self.viewer.get_slice_data(render) |
1426 | 1439 | cursor = slice_data.cursor |
... | ... | @@ -1545,11 +1558,11 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
1545 | 1558 | x, y = self.viewer.interactor.ScreenToClient(wx.GetMousePosition()) |
1546 | 1559 | if self.viewer.interactor.HitTest((x, y)) == wx.HT_WINDOW_INSIDE: |
1547 | 1560 | self.viewer.slice_data.cursor.Show() |
1548 | - | |
1561 | + | |
1549 | 1562 | y = self.viewer.interactor.GetSize()[1] - y |
1550 | 1563 | w_x, w_y, w_z = self.viewer.get_coordinate_cursor(x, y, self.picker) |
1551 | 1564 | self.viewer.slice_data.cursor.SetPosition((w_x, w_y, w_z)) |
1552 | - | |
1565 | + | |
1553 | 1566 | self.viewer.interactor.SetCursor(wx.Cursor(wx.CURSOR_BLANK)) |
1554 | 1567 | self.viewer.interactor.Render() |
1555 | 1568 | |
... | ... | @@ -1622,7 +1635,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
1622 | 1635 | iren = self.viewer.interactor |
1623 | 1636 | viewer = self.viewer |
1624 | 1637 | if iren.GetControlKey(): |
1625 | - mouse_x, mouse_y = iren.GetEventPosition() | |
1638 | + mouse_x, mouse_y = self.GetMousePosition() | |
1626 | 1639 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
1627 | 1640 | slice_data = self.viewer.get_slice_data(render) |
1628 | 1641 | cursor = slice_data.cursor |
... | ... | @@ -1640,7 +1653,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
1640 | 1653 | iren = self.viewer.interactor |
1641 | 1654 | viewer = self.viewer |
1642 | 1655 | if iren.GetControlKey(): |
1643 | - mouse_x, mouse_y = iren.GetEventPosition() | |
1656 | + mouse_x, mouse_y = self.GetMousePosition() | |
1644 | 1657 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
1645 | 1658 | slice_data = self.viewer.get_slice_data(render) |
1646 | 1659 | cursor = slice_data.cursor |
... | ... | @@ -1663,7 +1676,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
1663 | 1676 | |
1664 | 1677 | viewer._set_editor_cursor_visibility(1) |
1665 | 1678 | |
1666 | - mouse_x, mouse_y = iren.GetEventPosition() | |
1679 | + mouse_x, mouse_y = self.GetMousePosition() | |
1667 | 1680 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
1668 | 1681 | slice_data = viewer.get_slice_data(render) |
1669 | 1682 | |
... | ... | @@ -1710,7 +1723,7 @@ class WaterShedInteractorStyle(DefaultInteractorStyle): |
1710 | 1723 | |
1711 | 1724 | viewer._set_editor_cursor_visibility(1) |
1712 | 1725 | |
1713 | - mouse_x, mouse_y = iren.GetEventPosition() | |
1726 | + mouse_x, mouse_y = self.GetMousePosition() | |
1714 | 1727 | render = iren.FindPokedRenderer(mouse_x, mouse_y) |
1715 | 1728 | slice_data = viewer.get_slice_data(render) |
1716 | 1729 | |
... | ... | @@ -2033,7 +2046,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): |
2033 | 2046 | if self._over_center: |
2034 | 2047 | self.dragging = True |
2035 | 2048 | else: |
2036 | - x, y = self.viewer.interactor.GetEventPosition() | |
2049 | + x, y = self.GetMousePosition() | |
2037 | 2050 | w, h = self.viewer.interactor.GetSize() |
2038 | 2051 | |
2039 | 2052 | self.picker.Pick(h/2.0, w/2.0, 0, self.viewer.slice_data.renderer) |
... | ... | @@ -2063,7 +2076,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): |
2063 | 2076 | else: |
2064 | 2077 | # Getting mouse position |
2065 | 2078 | iren = self.viewer.interactor |
2066 | - mx, my = iren.GetEventPosition() | |
2079 | + mx, my = self.GetMousePosition() | |
2067 | 2080 | |
2068 | 2081 | # Getting center value |
2069 | 2082 | center = self.viewer.slice_.center |
... | ... | @@ -2109,7 +2122,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): |
2109 | 2122 | |
2110 | 2123 | def _move_center_rot(self): |
2111 | 2124 | iren = self.viewer.interactor |
2112 | - mx, my = iren.GetEventPosition() | |
2125 | + mx, my = self.GetMousePosition() | |
2113 | 2126 | |
2114 | 2127 | icx, icy, icz = self.viewer.slice_.center |
2115 | 2128 | |
... | ... | @@ -2131,7 +2144,7 @@ class ReorientImageInteractorStyle(DefaultInteractorStyle): |
2131 | 2144 | def _rotate(self): |
2132 | 2145 | # Getting mouse position |
2133 | 2146 | iren = self.viewer.interactor |
2134 | - mx, my = iren.GetEventPosition() | |
2147 | + mx, my = self.GetMousePosition() | |
2135 | 2148 | |
2136 | 2149 | cx, cy, cz = self.viewer.slice_.center |
2137 | 2150 | |
... | ... | @@ -2294,7 +2307,7 @@ class FloodFillMaskInteractorStyle(DefaultInteractorStyle): |
2294 | 2307 | |
2295 | 2308 | viewer = self.viewer |
2296 | 2309 | iren = viewer.interactor |
2297 | - mouse_x, mouse_y = iren.GetEventPosition() | |
2310 | + mouse_x, mouse_y = self.GetMousePosition() | |
2298 | 2311 | x, y, z = self.viewer.get_voxel_coord_by_screen_pos(mouse_x, mouse_y, self.picker) |
2299 | 2312 | |
2300 | 2313 | mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:] |
... | ... | @@ -2401,14 +2414,12 @@ class CropMaskInteractorStyle(DefaultInteractorStyle): |
2401 | 2414 | Publisher.subscribe(self.CropMask, "Crop mask") |
2402 | 2415 | |
2403 | 2416 | def OnMove(self, obj, evt): |
2404 | - iren = self.viewer.interactor | |
2405 | - x, y = iren.GetEventPosition() | |
2417 | + x, y = self.GetMousePosition() | |
2406 | 2418 | self.draw_retangle.MouseMove(x,y) |
2407 | 2419 | |
2408 | 2420 | def OnLeftPressed(self, obj, evt): |
2409 | 2421 | self.draw_retangle.mouse_pressed = True |
2410 | - iren = self.viewer.interactor | |
2411 | - x, y = iren.GetEventPosition() | |
2422 | + x, y = self.GetMousePosition() | |
2412 | 2423 | self.draw_retangle.LeftPressed(x,y) |
2413 | 2424 | |
2414 | 2425 | def OnReleaseLeftButton(self, obj, evt): |
... | ... | @@ -2416,13 +2427,12 @@ class CropMaskInteractorStyle(DefaultInteractorStyle): |
2416 | 2427 | self.draw_retangle.ReleaseLeft() |
2417 | 2428 | |
2418 | 2429 | def SetUp(self): |
2419 | - | |
2420 | 2430 | self.draw_retangle = geom.DrawCrop2DRetangle() |
2421 | 2431 | self.draw_retangle.SetViewer(self.viewer) |
2422 | 2432 | |
2423 | 2433 | self.viewer.canvas.draw_list.append(self.draw_retangle) |
2424 | 2434 | self.viewer.UpdateCanvas() |
2425 | - | |
2435 | + | |
2426 | 2436 | if not(self.config.dlg_visible): |
2427 | 2437 | self.config.dlg_visible = True |
2428 | 2438 | |
... | ... | @@ -2550,7 +2560,7 @@ class SelectMaskPartsInteractorStyle(DefaultInteractorStyle): |
2550 | 2560 | return |
2551 | 2561 | |
2552 | 2562 | iren = self.viewer.interactor |
2553 | - mouse_x, mouse_y = iren.GetEventPosition() | |
2563 | + mouse_x, mouse_y = self.GetMousePosition() | |
2554 | 2564 | x, y, z = self.viewer.get_voxel_coord_by_screen_pos(mouse_x, mouse_y, self.picker) |
2555 | 2565 | |
2556 | 2566 | mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:] |
... | ... | @@ -2670,7 +2680,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): |
2670 | 2680 | def do_2d_seg(self): |
2671 | 2681 | viewer = self.viewer |
2672 | 2682 | iren = viewer.interactor |
2673 | - mouse_x, mouse_y = iren.GetEventPosition() | |
2683 | + mouse_x, mouse_y = self.GetMousePosition() | |
2674 | 2684 | x, y = self.viewer.get_slice_pixel_coord_by_screen_pos(mouse_x, mouse_y, self.picker) |
2675 | 2685 | |
2676 | 2686 | mask = self.viewer.slice_.buffer_slices[self.orientation].mask.copy() |
... | ... | @@ -2736,7 +2746,7 @@ class FloodFillSegmentInteractorStyle(DefaultInteractorStyle): |
2736 | 2746 | def do_3d_seg(self): |
2737 | 2747 | viewer = self.viewer |
2738 | 2748 | iren = viewer.interactor |
2739 | - mouse_x, mouse_y = iren.GetEventPosition() | |
2749 | + mouse_x, mouse_y = self.GetMousePosition() | |
2740 | 2750 | x, y, z = self.viewer.get_voxel_coord_by_screen_pos(mouse_x, mouse_y, self.picker) |
2741 | 2751 | |
2742 | 2752 | mask = self.viewer.slice_.current_mask.matrix[1:, 1:, 1:] | ... | ... |
invesalius/data/styles_3d.py
... | ... | @@ -300,8 +300,7 @@ class WWWLInteractorStyle(DefaultInteractorStyle): |
300 | 300 | |
301 | 301 | def OnWindowLevelMove(self, obj, evt): |
302 | 302 | if self.changing_wwwl: |
303 | - iren = obj.GetInteractor() | |
304 | - mouse_x, mouse_y = iren.GetEventPosition() | |
303 | + mouse_x, mouse_y = self.viewer.get_vtk_mouse_position() | |
305 | 304 | diff_x = mouse_x - self.last_x |
306 | 305 | diff_y = mouse_y - self.last_y |
307 | 306 | self.last_x, self.last_y = mouse_x, mouse_y |
... | ... | @@ -311,8 +310,7 @@ class WWWLInteractorStyle(DefaultInteractorStyle): |
311 | 310 | Publisher.sendMessage('Render volume viewer') |
312 | 311 | |
313 | 312 | def OnWindowLevelClick(self, obj, evt): |
314 | - iren = obj.GetInteractor() | |
315 | - self.last_x, self.last_y = iren.GetLastEventPosition() | |
313 | + self.last_x, self.last_y = self.viewer.get_vtk_mouse_position() | |
316 | 314 | self.changing_wwwl = True |
317 | 315 | |
318 | 316 | def OnWindowLevelRelease(self, obj, evt): |
... | ... | @@ -345,7 +343,7 @@ class LinearMeasureInteractorStyle(DefaultInteractorStyle): |
345 | 343 | Publisher.sendMessage("Remove incomplete measurements") |
346 | 344 | |
347 | 345 | def OnInsertLinearMeasurePoint(self, obj, evt): |
348 | - x,y = self.viewer.interactor.GetEventPosition() | |
346 | + x,y = self.viewer.get_vtk_mouse_position() | |
349 | 347 | self.measure_picker.Pick(x, y, 0, self.viewer.ren) |
350 | 348 | x, y, z = self.measure_picker.GetPickPosition() |
351 | 349 | if self.measure_picker.GetActor(): |
... | ... | @@ -384,7 +382,7 @@ class AngularMeasureInteractorStyle(DefaultInteractorStyle): |
384 | 382 | Publisher.sendMessage("Remove incomplete measurements") |
385 | 383 | |
386 | 384 | def OnInsertAngularMeasurePoint(self, obj, evt): |
387 | - x,y = self.viewer.interactor.GetEventPosition() | |
385 | + x,y = self.viewer.get_vtk_mouse_position() | |
388 | 386 | self.measure_picker.Pick(x, y, 0, self.viewer.ren) |
389 | 387 | x, y, z = self.measure_picker.GetPickPosition() |
390 | 388 | if self.measure_picker.GetActor(): |
... | ... | @@ -412,7 +410,7 @@ class SeedInteractorStyle(DefaultInteractorStyle): |
412 | 410 | self.AddObserver("LeftButtonPressEvent", self.OnInsertSeed) |
413 | 411 | |
414 | 412 | def OnInsertSeed(self, obj, evt): |
415 | - x,y = self.viewer.interactor.GetEventPosition() | |
413 | + x,y = self.viewer.get_vtk_mouse_position() | |
416 | 414 | self.picker.Pick(x, y, 0, self.viewer.ren) |
417 | 415 | point_id = self.picker.GetPointId() |
418 | 416 | if point_id > -1: | ... | ... |
invesalius/data/viewer_slice.py
... | ... | @@ -650,6 +650,27 @@ class Viewer(wx.Panel): |
650 | 650 | my = round((z - zi)/self.slice_.spacing[2], 0) |
651 | 651 | return int(mx), int(my) |
652 | 652 | |
653 | + def get_vtk_mouse_position(self): | |
654 | + """ | |
655 | + Get Mouse position inside a wxVTKRenderWindowInteractorself. Return a | |
656 | + tuple with X and Y position. | |
657 | + Please use this instead of using iren.GetEventPosition because it's | |
658 | + not returning the correct values on Mac with HighDPI display, maybe | |
659 | + the same is happing with Windows and Linux, we need to test. | |
660 | + """ | |
661 | + mposx, mposy = wx.GetMousePosition() | |
662 | + cposx, cposy = self.interactor.ScreenToClient((mposx, mposy)) | |
663 | + mx, my = cposx, self.interactor.GetSize()[1] - cposy | |
664 | + if sys.platform == 'darwin': | |
665 | + # It's needed to mutiple by scale factor in HighDPI because of | |
666 | + # https://docs.wxpython.org/wx.glcanvas.GLCanvas.html | |
667 | + # For now we are doing this only on Mac but it may be needed on | |
668 | + # Windows and Linux too. | |
669 | + scale = self.interactor.GetContentScaleFactor() | |
670 | + mx *= scale | |
671 | + my *= scale | |
672 | + return int(mx), int(my) | |
673 | + | |
653 | 674 | def get_coordinate_cursor(self, mx, my, picker=None): |
654 | 675 | """ |
655 | 676 | Given the mx, my screen position returns the x, y, z position in world |
... | ... | @@ -1028,7 +1049,7 @@ class Viewer(wx.Panel): |
1028 | 1049 | #self.scroll.Bind(wx.EVT_SCROLL_ENDSCROLL, self.OnScrollBarRelease) |
1029 | 1050 | self.interactor.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) |
1030 | 1051 | self.interactor.Bind(wx.EVT_RIGHT_UP, self.OnContextMenu) |
1031 | - # self.interactor.Bind(wx.EVT_SIZE, self.OnSize) | |
1052 | + self.interactor.Bind(wx.EVT_SIZE, self.OnSize) | |
1032 | 1053 | |
1033 | 1054 | def LoadImagedata(self, mask_dict): |
1034 | 1055 | self.SetInput(mask_dict) |
... | ... | @@ -1413,12 +1434,13 @@ class Viewer(wx.Panel): |
1413 | 1434 | self.OnScrollBar() |
1414 | 1435 | |
1415 | 1436 | def OnSize(self, evt): |
1416 | - w, h = evt.GetSize() | |
1417 | - w = float(w) | |
1418 | - h = float(h) | |
1419 | - if self.slice_data: | |
1420 | - self.slice_data.SetSize((w, h)) | |
1421 | - evt.Skip() | |
1437 | + print("OnSize") | |
1438 | + w, h = self.GetSize() | |
1439 | + rwin = self.interactor.GetRenderWindow() | |
1440 | + rwin.SetSize(w, h) | |
1441 | + # if self.slice_data: | |
1442 | + # self.slice_data.SetSize((w, h)) | |
1443 | + # evt.Skip() | |
1422 | 1444 | |
1423 | 1445 | def OnSetMIPSize(self, number_slices): |
1424 | 1446 | self.number_slices = number_slices | ... | ... |
invesalius/data/viewer_volume.py
... | ... | @@ -116,6 +116,9 @@ class Viewer(wx.Panel): |
116 | 116 | self.text = vtku.TextZero() |
117 | 117 | self.text.SetValue("") |
118 | 118 | self.text.SetPosition(const.TEXT_POS_LEFT_UP) |
119 | + if sys.platform == 'darwin': | |
120 | + font_size = const.TEXT_SIZE_LARGE * self.GetContentScaleFactor() | |
121 | + self.text.SetSize(int(round(font_size, 0))) | |
119 | 122 | self.ren.AddActor(self.text.actor) |
120 | 123 | |
121 | 124 | # self.polygon = Polygon(None, is_3d=False) |
... | ... | @@ -318,6 +321,27 @@ class Viewer(wx.Panel): |
318 | 321 | Publisher.subscribe(self.ActivateRobotMode, 'Robot navigation mode') |
319 | 322 | Publisher.subscribe(self.OnUpdateRobotStatus, 'Update robot status') |
320 | 323 | |
324 | + def get_vtk_mouse_position(self): | |
325 | + """ | |
326 | + Get Mouse position inside a wxVTKRenderWindowInteractorself. Return a | |
327 | + tuple with X and Y position. | |
328 | + Please use this instead of using iren.GetEventPosition because it's | |
329 | + not returning the correct values on Mac with HighDPI display, maybe | |
330 | + the same is happing with Windows and Linux, we need to test. | |
331 | + """ | |
332 | + mposx, mposy = wx.GetMousePosition() | |
333 | + cposx, cposy = self.interactor.ScreenToClient((mposx, mposy)) | |
334 | + mx, my = cposx, self.interactor.GetSize()[1] - cposy | |
335 | + if sys.platform == 'darwin': | |
336 | + # It's needed to mutiple by scale factor in HighDPI because of | |
337 | + # https://docs.wxpython.org/wx.glcanvas.GLCanvas.html | |
338 | + # For now we are doing this only on Mac but it may be needed on | |
339 | + # Windows and Linux too. | |
340 | + scale = self.interactor.GetContentScaleFactor() | |
341 | + mx *= scale | |
342 | + my *= scale | |
343 | + return int(mx), int(my) | |
344 | + | |
321 | 345 | def SetStereoMode(self, mode): |
322 | 346 | ren_win = self.interactor.GetRenderWindow() |
323 | 347 | ... | ... |
invesalius/data/vtk_utils.py
... | ... | @@ -233,6 +233,7 @@ class TextZero(object): |
233 | 233 | |
234 | 234 | def SetSize(self, size): |
235 | 235 | self.property.SetFontSize(size) |
236 | + self.actor.GetTextProperty().ShallowCopy(self.property) | |
236 | 237 | |
237 | 238 | def SetSymbolicSize(self, size): |
238 | 239 | self.symbolic_syze = size |
... | ... | @@ -288,8 +289,8 @@ class TextZero(object): |
288 | 289 | coord.SetValue(*self.position) |
289 | 290 | x, y = coord.GetComputedDisplayValue(canvas.evt_renderer) |
290 | 291 | font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) |
291 | - # font.SetWeight(wx.FONTWEIGHT_BOLD) | |
292 | 292 | font.SetSymbolicSize(self.symbolic_syze) |
293 | + font.Scale(canvas.viewer.GetContentScaleFactor()) | |
293 | 294 | if self.bottom_pos or self.right_pos: |
294 | 295 | w, h = canvas.calc_text_size(self.text, font) |
295 | 296 | if self.right_pos: | ... | ... |
invesalius/gui/widgets/canvas_renderer.py
... | ... | @@ -180,13 +180,11 @@ class CanvasRendererCTX: |
180 | 180 | return False |
181 | 181 | |
182 | 182 | def Refresh(self): |
183 | - print('Refresh') | |
184 | 183 | self.modified = True |
185 | 184 | self.viewer.interactor.Render() |
186 | 185 | |
187 | 186 | def OnMouseMove(self, evt): |
188 | - x, y = evt.GetPosition() | |
189 | - y = self.viewer.interactor.GetSize()[1] - y | |
187 | + x, y = self.viewer.get_vtk_mouse_position() | |
190 | 188 | redraw = False |
191 | 189 | |
192 | 190 | if self._drag_obj: |
... | ... | @@ -230,8 +228,7 @@ class CanvasRendererCTX: |
230 | 228 | evt.Skip() |
231 | 229 | |
232 | 230 | def OnLeftButtonPress(self, evt): |
233 | - x, y = evt.GetPosition() | |
234 | - y = self.viewer.interactor.GetSize()[1] - y | |
231 | + x, y = self.viewer.get_vtk_mouse_position() | |
235 | 232 | if self._over_obj and hasattr(self._over_obj, 'on_mouse_move'): |
236 | 233 | if hasattr(self._over_obj, 'on_select'): |
237 | 234 | try: |
... | ... | @@ -286,8 +283,7 @@ class CanvasRendererCTX: |
286 | 283 | evt.Skip() |
287 | 284 | |
288 | 285 | def OnDoubleClick(self, evt): |
289 | - x, y = evt.GetPosition() | |
290 | - y = self.viewer.interactor.GetSize()[1] - y | |
286 | + x, y = self.viewer.get_vtk_mouse_position() | |
291 | 287 | evt_obj = CanvasEvent('double_left_click', None, (x, y), self.viewer, self.evt_renderer, |
292 | 288 | control_down=evt.ControlDown(), |
293 | 289 | alt_down=evt.AltDown(), |
... | ... | @@ -301,6 +297,7 @@ class CanvasRendererCTX: |
301 | 297 | def OnPaint(self, evt, obj): |
302 | 298 | size = self.canvas_renderer.GetSize() |
303 | 299 | w, h = size |
300 | + ew, eh = self.evt_renderer.GetSize() | |
304 | 301 | if self._size != size: |
305 | 302 | self._size = size |
306 | 303 | self._resize_canvas(w, h) |
... | ... | @@ -628,17 +625,18 @@ class CanvasRendererCTX: |
628 | 625 | |
629 | 626 | if font is None: |
630 | 627 | font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) |
628 | + font.Scale(self.viewer.GetContentScaleFactor()) | |
631 | 629 | |
632 | - font = gc.CreateFont(font, txt_colour) | |
630 | + _font = gc.CreateFont(font, txt_colour) | |
633 | 631 | px, py = pos |
634 | 632 | for t in text.split('\n'): |
635 | 633 | t = t.strip() |
636 | 634 | _py = -py |
637 | 635 | _px = px |
638 | - gc.SetFont(font) | |
636 | + gc.SetFont(_font) | |
639 | 637 | gc.DrawText(t, _px, _py) |
640 | 638 | |
641 | - w, h = self.calc_text_size(t) | |
639 | + w, h = self.calc_text_size(t, font) | |
642 | 640 | py -= h |
643 | 641 | |
644 | 642 | self._drawn = True |
... | ... | @@ -661,10 +659,11 @@ class CanvasRendererCTX: |
661 | 659 | |
662 | 660 | if font is None: |
663 | 661 | font = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT) |
662 | + font.Scale(self.viewer.GetContentScaleFactor()) | |
664 | 663 | |
665 | 664 | _font = gc.CreateFont(font, txt_colour) |
666 | 665 | gc.SetFont(_font) |
667 | - w, h = self.calc_text_size(text) | |
666 | + w, h = self.calc_text_size(text, font) | |
668 | 667 | |
669 | 668 | px, py = pos |
670 | 669 | |
... | ... | @@ -880,11 +879,13 @@ class CircleHandler(CanvasHandlerBase): |
880 | 879 | |
881 | 880 | def draw_to_canvas(self, gc, canvas): |
882 | 881 | if self.visible: |
882 | + viewer = canvas.viewer | |
883 | + scale = viewer.GetContentScaleFactor() | |
883 | 884 | if self.is_3d: |
884 | 885 | px, py = self._3d_to_2d(canvas.evt_renderer, self.position) |
885 | 886 | else: |
886 | 887 | px, py = self.position |
887 | - x, y, w, h = canvas.draw_circle((px, py), self.radius, | |
888 | + x, y, w, h = canvas.draw_circle((px, py), self.radius * scale, | |
888 | 889 | line_colour=self.line_colour, |
889 | 890 | fill_colour=self.fill_colour) |
890 | 891 | self.bbox = (x - w/2, y - h/2, x + w/2, y + h/2) | ... | ... |