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 | 20 | |
| 21 | 21 | import wx |
| 22 | 22 | import wx.lib.hyperlink as hl |
| 23 | -import wx.lib.platebtn as pbtn | |
| 24 | 23 | import wx.lib.pubsub as ps |
| 25 | 24 | |
| 26 | 25 | import gui.dialogs as dlg |
| 27 | 26 | import gui.widgets.foldpanelbar as fpb |
| 28 | 27 | import gui.widgets.colourselect as csel |
| 28 | +import gui.widgets.platebtn as pbtn | |
| 29 | 29 | import project as prj |
| 30 | 30 | import utils as utl |
| 31 | 31 | |
| 32 | + | |
| 32 | 33 | #INTERPOLATION_MODE_LIST = ["Cubic", "Linear", "NearestNeighbor"] |
| 33 | 34 | MIN_TRANSPARENCY = 0 |
| 34 | 35 | MAX_TRANSPARENCY = 100 |
| ... | ... | @@ -159,7 +160,7 @@ class InnerTaskPanel(wx.Panel): |
| 159 | 160 | |
| 160 | 161 | class FoldPanel(wx.Panel): |
| 161 | 162 | def __init__(self, parent): |
| 162 | - wx.Panel.__init__(self, parent, size=(50,50)) | |
| 163 | + wx.Panel.__init__(self, parent, size=(50,700)) | |
| 163 | 164 | self.SetBackgroundColour(wx.Colour(0,255,0)) |
| 164 | 165 | |
| 165 | 166 | inner_panel = InnerFoldPanel(self) |
| ... | ... | @@ -185,7 +186,7 @@ class InnerFoldPanel(wx.Panel): |
| 185 | 186 | # parent panel. Perhaps we need to insert the item into the sizer also... |
| 186 | 187 | # Study this. |
| 187 | 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 | 191 | # Fold panel style |
| 191 | 192 | style = fpb.CaptionBarStyle() |
| ... | ... | @@ -195,15 +196,18 @@ class InnerFoldPanel(wx.Panel): |
| 195 | 196 | |
| 196 | 197 | # Fold 1 - Surface properties |
| 197 | 198 | item = fold_panel.AddFoldPanel(_("Surface properties"), collapsed=True) |
| 199 | + self.surface_properties = SurfaceProperties(item) | |
| 198 | 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 | 202 | leftSpacing=0, rightSpacing=0) |
| 201 | 203 | fold_panel.Expand(fold_panel.GetFoldPanel(0)) |
| 202 | 204 | |
| 203 | 205 | # Fold 2 - Surface tools |
| 204 | 206 | item = fold_panel.AddFoldPanel(_("Advanced options"), collapsed=True) |
| 205 | 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 | 211 | leftSpacing=0, rightSpacing=0) |
| 208 | 212 | |
| 209 | 213 | #fold_panel.AddFoldPanelWindow(item, QualityAdjustment(item), Spacing= 0, |
| ... | ... | @@ -219,16 +223,142 @@ class InnerFoldPanel(wx.Panel): |
| 219 | 223 | self.Update() |
| 220 | 224 | self.SetAutoLayout(1) |
| 221 | 225 | |
| 222 | - | |
| 226 | +BTN_LARGEST = wx.NewId() | |
| 227 | +BTN_SPLIT = wx.NewId() | |
| 228 | +BTN_SEEDS = wx.NewId() | |
| 223 | 229 | class SurfaceTools(wx.Panel): |
| 224 | 230 | def __init__(self, parent): |
| 225 | - wx.Panel.__init__(self, parent, size=(50,240)) | |
| 231 | + wx.Panel.__init__(self, parent, size=(50,400)) | |
| 226 | 232 | default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) |
| 227 | 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 | 359 | class SurfaceProperties(wx.Panel): |
| 230 | 360 | def __init__(self, parent): |
| 231 | - wx.Panel.__init__(self, parent, size=(50,240)) | |
| 361 | + wx.Panel.__init__(self, parent, size=(50,400)) | |
| 232 | 362 | default_colour = wx.SystemSettings_GetColour(wx.SYS_COLOUR_MENUBAR) |
| 233 | 363 | self.SetBackgroundColour(default_colour) |
| 234 | 364 | |
| ... | ... | @@ -252,8 +382,8 @@ class SurfaceProperties(wx.Panel): |
| 252 | 382 | |
| 253 | 383 | # Sizer which represents the first line |
| 254 | 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 | 389 | ## LINE 2 |
| ... | ... | @@ -283,8 +413,9 @@ class SurfaceProperties(wx.Panel): |
| 283 | 413 | |
| 284 | 414 | # Add all lines into main sizer |
| 285 | 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 | 419 | #sizer.Add(cb, 0, wx.GROW|wx.EXPAND|wx.RIGHT|wx.LEFT|wx.TOP|wx.BOTTOM, 5) |
| 289 | 420 | sizer.Fit(self) |
| 290 | 421 | ... | ... |
invesalius/gui/widgets/platebtn.py
| ... | ... | @@ -686,6 +686,13 @@ class PlateButton(wx.PyControl): |
| 686 | 686 | |
| 687 | 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 | 696 | def ToggleState(self): |
| 690 | 697 | """Toggle button state""" |
| 691 | 698 | if self._state['cur'] != PLATE_PRESSED: | ... | ... |