Commit 8baa329698ef9760118155b5ada5c834505402f8
1 parent
45f41b2a
Exists in
master
and in
6 other branches
ENH: Task surface layout (#73)
Showing
2 changed files
with
150 additions
and
12 deletions
Show diff stats
invesalius/gui/task_surface.py
| @@ -20,15 +20,16 @@ import sys | @@ -20,15 +20,16 @@ import sys | ||
| 20 | 20 | ||
| 21 | import wx | 21 | import wx |
| 22 | import wx.lib.hyperlink as hl | 22 | import wx.lib.hyperlink as hl |
| 23 | -import wx.lib.platebtn as pbtn | ||
| 24 | import wx.lib.pubsub as ps | 23 | import wx.lib.pubsub as ps |
| 25 | 24 | ||
| 26 | import gui.dialogs as dlg | 25 | import gui.dialogs as dlg |
| 27 | import gui.widgets.foldpanelbar as fpb | 26 | import gui.widgets.foldpanelbar as fpb |
| 28 | import gui.widgets.colourselect as csel | 27 | import gui.widgets.colourselect as csel |
| 28 | +import gui.widgets.platebtn as pbtn | ||
| 29 | import project as prj | 29 | import project as prj |
| 30 | import utils as utl | 30 | import utils as utl |
| 31 | 31 | ||
| 32 | + | ||
| 32 | #INTERPOLATION_MODE_LIST = ["Cubic", "Linear", "NearestNeighbor"] | 33 | #INTERPOLATION_MODE_LIST = ["Cubic", "Linear", "NearestNeighbor"] |
| 33 | MIN_TRANSPARENCY = 0 | 34 | MIN_TRANSPARENCY = 0 |
| 34 | MAX_TRANSPARENCY = 100 | 35 | MAX_TRANSPARENCY = 100 |
| @@ -159,7 +160,7 @@ class InnerTaskPanel(wx.Panel): | @@ -159,7 +160,7 @@ class InnerTaskPanel(wx.Panel): | ||
| 159 | 160 | ||
| 160 | class FoldPanel(wx.Panel): | 161 | class FoldPanel(wx.Panel): |
| 161 | def __init__(self, parent): | 162 | def __init__(self, parent): |
| 162 | - wx.Panel.__init__(self, parent, size=(50,50)) | 163 | + wx.Panel.__init__(self, parent, size=(50,700)) |
| 163 | self.SetBackgroundColour(wx.Colour(0,255,0)) | 164 | self.SetBackgroundColour(wx.Colour(0,255,0)) |
| 164 | 165 | ||
| 165 | inner_panel = InnerFoldPanel(self) | 166 | inner_panel = InnerFoldPanel(self) |
| @@ -185,7 +186,7 @@ class InnerFoldPanel(wx.Panel): | @@ -185,7 +186,7 @@ class InnerFoldPanel(wx.Panel): | ||
| 185 | # parent panel. Perhaps we need to insert the item into the sizer also... | 186 | # parent panel. Perhaps we need to insert the item into the sizer also... |
| 186 | # Study this. | 187 | # Study this. |
| 187 | fold_panel = fpb.FoldPanelBar(self, -1, wx.DefaultPosition, | 188 | fold_panel = fpb.FoldPanelBar(self, -1, wx.DefaultPosition, |
| 188 | - (10, 100), 0,fpb.FPB_SINGLE_FOLD) | 189 | + (10, 140), 0,fpb.FPB_SINGLE_FOLD) |
| 189 | 190 | ||
| 190 | # Fold panel style | 191 | # Fold panel style |
| 191 | style = fpb.CaptionBarStyle() | 192 | style = fpb.CaptionBarStyle() |
| @@ -195,15 +196,18 @@ class InnerFoldPanel(wx.Panel): | @@ -195,15 +196,18 @@ class InnerFoldPanel(wx.Panel): | ||
| 195 | 196 | ||
| 196 | # Fold 1 - Surface properties | 197 | # Fold 1 - Surface properties |
| 197 | item = fold_panel.AddFoldPanel(_("Surface properties"), collapsed=True) | 198 | item = fold_panel.AddFoldPanel(_("Surface properties"), collapsed=True) |
| 199 | + self.surface_properties = SurfaceProperties(item) | ||
| 198 | fold_panel.ApplyCaptionStyle(item, style) | 200 | fold_panel.ApplyCaptionStyle(item, style) |
| 199 | - fold_panel.AddFoldPanelWindow(item, SurfaceProperties(item), Spacing= 0, | 201 | + fold_panel.AddFoldPanelWindow(item, self.surface_properties, Spacing= 0, |
| 200 | leftSpacing=0, rightSpacing=0) | 202 | leftSpacing=0, rightSpacing=0) |
| 201 | fold_panel.Expand(fold_panel.GetFoldPanel(0)) | 203 | fold_panel.Expand(fold_panel.GetFoldPanel(0)) |
| 202 | 204 | ||
| 203 | # Fold 2 - Surface tools | 205 | # Fold 2 - Surface tools |
| 204 | item = fold_panel.AddFoldPanel(_("Advanced options"), collapsed=True) | 206 | item = fold_panel.AddFoldPanel(_("Advanced options"), collapsed=True) |
| 205 | fold_panel.ApplyCaptionStyle(item, style) | 207 | fold_panel.ApplyCaptionStyle(item, style) |
| 206 | - fold_panel.AddFoldPanelWindow(item, SurfaceTools(item), Spacing= 0, | 208 | + self.surface_tools = SurfaceTools(item) |
| 209 | + self.surface_tools.combo_surface_name = self.surface_properties.combo_surface_name | ||
| 210 | + fold_panel.AddFoldPanelWindow(item, self.surface_tools, Spacing= 0, | ||
| 207 | leftSpacing=0, rightSpacing=0) | 211 | leftSpacing=0, rightSpacing=0) |
| 208 | 212 | ||
| 209 | #fold_panel.AddFoldPanelWindow(item, QualityAdjustment(item), Spacing= 0, | 213 | #fold_panel.AddFoldPanelWindow(item, QualityAdjustment(item), Spacing= 0, |
| @@ -219,16 +223,142 @@ class InnerFoldPanel(wx.Panel): | @@ -219,16 +223,142 @@ class InnerFoldPanel(wx.Panel): | ||
| 219 | self.Update() | 223 | self.Update() |
| 220 | self.SetAutoLayout(1) | 224 | self.SetAutoLayout(1) |
| 221 | 225 | ||
| 222 | - | 226 | +BTN_LARGEST = wx.NewId() |
| 227 | +BTN_SPLIT = wx.NewId() | ||
| 228 | +BTN_SEEDS = wx.NewId() | ||
| 223 | class SurfaceTools(wx.Panel): | 229 | class SurfaceTools(wx.Panel): |
| 224 | def __init__(self, parent): | 230 | def __init__(self, parent): |
| 225 | - wx.Panel.__init__(self, parent, size=(50,240)) | 231 | + wx.Panel.__init__(self, parent, size=(50,400)) |
| 226 | default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) | 232 | default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) |
| 227 | self.SetBackgroundColour(default_colour) | 233 | self.SetBackgroundColour(default_colour) |
| 228 | 234 | ||
| 235 | + #self.SetBackgroundColour(wx.Colour(255,255,255)) | ||
| 236 | + self.SetAutoLayout(1) | ||
| 237 | + | ||
| 238 | + self.combo_surface_name = None | ||
| 239 | + | ||
| 240 | + # Fixed hyperlink items | ||
| 241 | + tooltip = wx.ToolTip(_("Automatically select largest disconnect surface")) | ||
| 242 | + link_largest = hl.HyperLinkCtrl(self, -1, _("Split largest surface")) | ||
| 243 | + link_largest.SetUnderlines(False, False, False) | ||
| 244 | + link_largest.SetColours("BLACK", "BLACK", "BLACK") | ||
| 245 | + link_largest.SetToolTip(tooltip) | ||
| 246 | + link_largest.AutoBrowse(False) | ||
| 247 | + link_largest.UpdateLink() | ||
| 248 | + link_largest.Bind(hl.EVT_HYPERLINK_LEFT, self.OnLinkLargest) | ||
| 249 | + | ||
| 250 | + tooltip = wx.ToolTip(_("Automatically split surfaces into new ones")) | ||
| 251 | + link_split_all = hl.HyperLinkCtrl(self, -1,"Split all disconnect surfaces") | ||
| 252 | + link_split_all.SetUnderlines(False, False, False) | ||
| 253 | + link_split_all.SetColours("BLACK", "BLACK", "BLACK") | ||
| 254 | + link_split_all.SetToolTip(tooltip) | ||
| 255 | + link_split_all.AutoBrowse(False) | ||
| 256 | + link_split_all.UpdateLink() | ||
| 257 | + link_split_all.Bind(hl.EVT_HYPERLINK_LEFT, self.OnLinkSplit) | ||
| 258 | + | ||
| 259 | + tooltip = wx.ToolTip(_("Manually insert seeds of surfaces of interest")) | ||
| 260 | + link_seeds = hl.HyperLinkCtrl(self,-1,_("Select surfaces of interest")) | ||
| 261 | + link_seeds.SetUnderlines(False, False, False) | ||
| 262 | + link_seeds.SetColours("BLACK", "BLACK", "BLACK") | ||
| 263 | + link_seeds.SetToolTip(tooltip) | ||
| 264 | + link_seeds.AutoBrowse(False) | ||
| 265 | + link_seeds.UpdateLink() | ||
| 266 | + link_seeds.Bind(hl.EVT_HYPERLINK_LEFT, self.OnLinkSeed) | ||
| 267 | + | ||
| 268 | + # Image(s) for buttons | ||
| 269 | + BMP_LARGEST = wx.Bitmap("../icons/connectivity_largest.png", wx.BITMAP_TYPE_PNG) | ||
| 270 | + BMP_SPLIT_ALL = wx.Bitmap("../icons/connectivity_split_all.png", wx.BITMAP_TYPE_PNG) | ||
| 271 | + BMP_SEEDS = wx.Bitmap("../icons/connectivity_manual.png", wx.BITMAP_TYPE_PNG) | ||
| 272 | + | ||
| 273 | + bmp_list = [BMP_LARGEST, BMP_SPLIT_ALL, BMP_SEEDS] | ||
| 274 | + for bmp in bmp_list: | ||
| 275 | + bmp.SetWidth(25) | ||
| 276 | + bmp.SetHeight(25) | ||
| 277 | + | ||
| 278 | + # Buttons related to hyperlinks | ||
| 279 | + button_style = pbtn.PB_STYLE_SQUARE | pbtn.PB_STYLE_DEFAULT | ||
| 280 | + button_style_plus = button_style|pbtn.PB_STYLE_TOGGLE | ||
| 281 | + | ||
| 282 | + button_split = pbtn.PlateButton(self, BTN_SPLIT, "", BMP_SPLIT_ALL, | ||
| 283 | + style=button_style) | ||
| 284 | + button_largest = pbtn.PlateButton(self, BTN_LARGEST, "", | ||
| 285 | + BMP_LARGEST, style=button_style) | ||
| 286 | + button_seeds = pbtn.PlateButton(self, BTN_SEEDS, "", | ||
| 287 | + BMP_SEEDS, style=button_style_plus) | ||
| 288 | + self.button_seeds = button_seeds | ||
| 289 | + | ||
| 290 | + # When using PlaneButton, it is necessary to bind events from parent win | ||
| 291 | + self.Bind(wx.EVT_BUTTON, self.OnButton) | ||
| 292 | + | ||
| 293 | + # Tags and grid sizer for fixed items | ||
| 294 | + flag_link = wx.EXPAND|wx.GROW|wx.LEFT|wx.TOP | ||
| 295 | + flag_button = wx.EXPAND | wx.GROW | ||
| 296 | + | ||
| 297 | + #fixed_sizer = wx.FlexGridSizer(rows=3, cols=2, hgap=2, vgap=0) | ||
| 298 | + fixed_sizer = wx.FlexGridSizer(rows=3, cols=2, hgap=2, vgap=0) | ||
| 299 | + fixed_sizer.AddGrowableCol(0, 1) | ||
| 300 | + fixed_sizer.AddMany([ (link_largest, 1, flag_link, 3), | ||
| 301 | + (button_largest, 0, flag_button), | ||
| 302 | + (link_seeds, 1, flag_link, 3), | ||
| 303 | + (button_seeds, 0, flag_button), | ||
| 304 | + (link_split_all, 1, flag_link, 3), | ||
| 305 | + (button_split, 0, flag_button) ]) | ||
| 306 | + | ||
| 307 | + | ||
| 308 | + # Add line sizers into main sizer | ||
| 309 | + main_sizer = wx.BoxSizer(wx.VERTICAL) | ||
| 310 | + main_sizer.Add(fixed_sizer, 0, wx.GROW|wx.EXPAND|wx.TOP, 5) | ||
| 311 | + | ||
| 312 | + # Update main sizer and panel layout | ||
| 313 | + self.SetSizer(main_sizer) | ||
| 314 | + self.Update() | ||
| 315 | + self.SetAutoLayout(1) | ||
| 316 | + self.sizer = main_sizer | ||
| 317 | + | ||
| 318 | + def OnLinkLargest(self, evt): | ||
| 319 | + self.SelectLargest() | ||
| 320 | + | ||
| 321 | + def OnLinkSplit(self, evt): | ||
| 322 | + self.SplitSurface() | ||
| 323 | + | ||
| 324 | + def OnLinkSeed(self, evt): | ||
| 325 | + self.button_seeds.Toggle() | ||
| 326 | + self.SelectSeed() | ||
| 327 | + | ||
| 328 | + def OnButton(self, evt): | ||
| 329 | + if id == BTN_LARGEST: | ||
| 330 | + self.SelectLargest() | ||
| 331 | + elif id == BTN_SPLIT: | ||
| 332 | + self.SplitSurface() | ||
| 333 | + else: | ||
| 334 | + self.SelectSeed() | ||
| 335 | + | ||
| 336 | + def SelectLargest(self): | ||
| 337 | + index = self.combo_surface_name.GetSelection() | ||
| 338 | + ps.Publisher().sendMessage('Split surface by largest region', index) | ||
| 339 | + | ||
| 340 | + def SplitSurface(self): | ||
| 341 | + index = self.combo_surface_name.GetSelection() | ||
| 342 | + ps.Publisher().sendMessage('Create surface by largest region', index) | ||
| 343 | + | ||
| 344 | + def SelectSeed(self): | ||
| 345 | + if self.button_seeds.IsPressed(): | ||
| 346 | + self.StartSeeding() | ||
| 347 | + else: | ||
| 348 | + self.EndSeeding() | ||
| 349 | + | ||
| 350 | + def StartSeeding(self): | ||
| 351 | + index = self.combo_surface_name.GetSelection() | ||
| 352 | + ps.Publisher().sendMessage('Create surface by seeding - start', index) | ||
| 353 | + | ||
| 354 | + def EndSeeding(self): | ||
| 355 | + ps.Publisher().sendMessage('Create surface by seeding - end') | ||
| 356 | + | ||
| 357 | + | ||
| 358 | + | ||
| 229 | class SurfaceProperties(wx.Panel): | 359 | class SurfaceProperties(wx.Panel): |
| 230 | def __init__(self, parent): | 360 | def __init__(self, parent): |
| 231 | - wx.Panel.__init__(self, parent, size=(50,240)) | 361 | + wx.Panel.__init__(self, parent, size=(50,400)) |
| 232 | default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) | 362 | default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) |
| 233 | self.SetBackgroundColour(default_colour) | 363 | self.SetBackgroundColour(default_colour) |
| 234 | 364 | ||
| @@ -252,8 +382,8 @@ class SurfaceProperties(wx.Panel): | @@ -252,8 +382,8 @@ class SurfaceProperties(wx.Panel): | ||
| 252 | 382 | ||
| 253 | # Sizer which represents the first line | 383 | # Sizer which represents the first line |
| 254 | line1 = wx.BoxSizer(wx.HORIZONTAL) | 384 | line1 = wx.BoxSizer(wx.HORIZONTAL) |
| 255 | - line1.Add(combo_surface_name, 1, wx.EXPAND|wx.GROW|wx.TOP|wx.RIGHT, 2) | ||
| 256 | - line1.Add(button_colour, 0, wx.TOP|wx.LEFT|wx.RIGHT, 2) | 385 | + line1.Add(combo_surface_name, 1, wx.LEFT|wx.EXPAND|wx.GROW|wx.TOP|wx.RIGHT, 7) |
| 386 | + line1.Add(button_colour, 0, wx.TOP|wx.RIGHT, 7) | ||
| 257 | 387 | ||
| 258 | 388 | ||
| 259 | ## LINE 2 | 389 | ## LINE 2 |
| @@ -283,8 +413,9 @@ class SurfaceProperties(wx.Panel): | @@ -283,8 +413,9 @@ class SurfaceProperties(wx.Panel): | ||
| 283 | 413 | ||
| 284 | # Add all lines into main sizer | 414 | # Add all lines into main sizer |
| 285 | sizer = wx.BoxSizer(wx.VERTICAL) | 415 | sizer = wx.BoxSizer(wx.VERTICAL) |
| 286 | - sizer.Add(line1, 1, wx.GROW|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5) | ||
| 287 | - sizer.Add(fixed_sizer, 0, wx.GROW|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP, 5) | 416 | + sizer.Add(line1, 1, wx.GROW|wx.EXPAND|wx.TOP, 10) |
| 417 | + sizer.Add(fixed_sizer, 0, | ||
| 418 | +wx.GROW|wx.EXPAND|wx.LEFT|wx.RIGHT|wx.TOP|wx.BOTTOM, 10) | ||
| 288 | #sizer.Add(cb, 0, wx.GROW|wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP|wx.BOTTOM, 5) | 419 | #sizer.Add(cb, 0, wx.GROW|wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP|wx.BOTTOM, 5) |
| 289 | sizer.Fit(self) | 420 | sizer.Fit(self) |
| 290 | 421 |
invesalius/gui/widgets/platebtn.py
| @@ -686,6 +686,13 @@ class PlateButton(wx.PyControl): | @@ -686,6 +686,13 @@ class PlateButton(wx.PyControl): | ||
| 686 | 686 | ||
| 687 | self.PopupMenu(self._menu, (xpos, size[1] + adj)) | 687 | self.PopupMenu(self._menu, (xpos, size[1] + adj)) |
| 688 | 688 | ||
| 689 | + def Toggle(self): | ||
| 690 | + self._pressed = not self._pressed | ||
| 691 | + if self._pressed: | ||
| 692 | + self.SetState(PLATE_PRESSED) | ||
| 693 | + else: | ||
| 694 | + self.SetState(PLATE_NORMAL) | ||
| 695 | + | ||
| 689 | def ToggleState(self): | 696 | def ToggleState(self): |
| 690 | """Toggle button state""" | 697 | """Toggle button state""" |
| 691 | if self._state['cur'] != PLATE_PRESSED: | 698 | if self._state['cur'] != PLATE_PRESSED: |