Commit e2b58c402586e365ff41bc533a49e3100039f9e1
1 parent
1384e482
Exists in
master
and in
68 other branches
DOC: Comments / style
Showing
1 changed file
with
132 additions
and
74 deletions
Show diff stats
invesalius/gui/frame.py
| ... | ... | @@ -36,7 +36,8 @@ import session as ses |
| 36 | 36 | import utils |
| 37 | 37 | |
| 38 | 38 | |
| 39 | -# Layout toolbar | |
| 39 | +# Layout tools' IDs - this is used only locally, therefore doesn't need | |
| 40 | +# to be defined in constants.py | |
| 40 | 41 | VIEW_TOOLS = [ID_LAYOUT, ID_TEXT] = [wx.NewId() for number in range(2)] |
| 41 | 42 | |
| 42 | 43 | class Frame(wx.Frame): |
| ... | ... | @@ -60,9 +61,11 @@ class Frame(wx.Frame): |
| 60 | 61 | self.SetMenuBar(MenuBar(self)) |
| 61 | 62 | self.SetStatusBar(StatusBar(self)) |
| 62 | 63 | |
| 63 | - # win32: Show icon on "Notification Area" at "Task Bar" | |
| 64 | - # darwin: Show icon on Dock | |
| 65 | - # linux2: ? - TODO: find what it does | |
| 64 | + # TaskBarIcon has different behaviours according to the | |
| 65 | + # platform: | |
| 66 | + # - win32: Show icon on "Notification Area" at "Task Bar" | |
| 67 | + # - darwin: Show icon on Dock | |
| 68 | + # - linux2: ? - TODO: find what it does | |
| 66 | 69 | TaskBarIcon(self) |
| 67 | 70 | |
| 68 | 71 | # Create aui manager and insert content in it |
| ... | ... | @@ -131,7 +134,6 @@ class Frame(wx.Frame): |
| 131 | 134 | Caption(_("Preview medical data to be reconstructed")). |
| 132 | 135 | CaptionVisible(True)) |
| 133 | 136 | |
| 134 | - | |
| 135 | 137 | # Add toolbars to manager |
| 136 | 138 | # This is pretty tricky -- order on win32 is inverted when |
| 137 | 139 | # compared to linux2 & darwin |
| ... | ... | @@ -167,12 +169,11 @@ class Frame(wx.Frame): |
| 167 | 169 | LeftDockable(False).RightDockable(False)) |
| 168 | 170 | |
| 169 | 171 | aui_manager.Update() |
| 172 | + self.aui_manager = aui_manager | |
| 170 | 173 | |
| 171 | 174 | # TODO: Allow saving and restoring perspectives |
| 172 | 175 | self.perspective_all = aui_manager.SavePerspective() |
| 173 | 176 | |
| 174 | - self.aui_manager = aui_manager | |
| 175 | - | |
| 176 | 177 | def _BeginBusyCursor(self, pubsub_evt): |
| 177 | 178 | """ |
| 178 | 179 | Start busy cursor. |
| ... | ... | @@ -216,7 +217,6 @@ class Frame(wx.Frame): |
| 216 | 217 | aui_manager.GetPane("Tasks").Show(1) |
| 217 | 218 | aui_manager.Update() |
| 218 | 219 | |
| 219 | - | |
| 220 | 220 | def _HideTask(self, pubsub_evt): |
| 221 | 221 | """ |
| 222 | 222 | Hide task panel. |
| ... | ... | @@ -264,14 +264,12 @@ class Frame(wx.Frame): |
| 264 | 264 | self.aui_manager.GetPane("Tasks").Show() |
| 265 | 265 | self.aui_manager.Update() |
| 266 | 266 | |
| 267 | - | |
| 268 | 267 | def _UpdateAUI(self, pubsub_evt): |
| 269 | 268 | """ |
| 270 | 269 | Refresh AUI panels/data. |
| 271 | 270 | """ |
| 272 | 271 | self.aui_manager.Update() |
| 273 | 272 | |
| 274 | - | |
| 275 | 273 | def CloseProject(self): |
| 276 | 274 | ps.Publisher().sendMessage('Close Project') |
| 277 | 275 | |
| ... | ... | @@ -353,38 +351,58 @@ class Frame(wx.Frame): |
| 353 | 351 | """ |
| 354 | 352 | ps.Publisher().sendMessage('Show save dialog', True) |
| 355 | 353 | |
| 356 | - | |
| 357 | - | |
| 358 | -# ------------------------------------------------------------------------------ | |
| 359 | -# ------------------------------------------------------------------------------ | |
| 360 | -# TODO: what will appear on ivMenuBar? | |
| 361 | -# Menu items ID's, necessary to bind events on them | |
| 362 | - | |
| 354 | +# ------------------------------------------------------------------ | |
| 355 | +# ------------------------------------------------------------------ | |
| 356 | +# ------------------------------------------------------------------ | |
| 363 | 357 | |
| 364 | 358 | class MenuBar(wx.MenuBar): |
| 365 | - def __init__(self, parent=None): | |
| 359 | + """ | |
| 360 | + MenuBar which contains menus used to control project, tools and help. | |
| 361 | + """ | |
| 362 | + def __init__(self, parent): | |
| 366 | 363 | wx.MenuBar.__init__(self) |
| 367 | 364 | |
| 368 | 365 | self.parent = parent |
| 369 | 366 | |
| 367 | + # Used to enable/disable menu items if project is opened or | |
| 368 | + # not. Eg. save should only be available if a project is open | |
| 369 | + self.enable_items = [const.ID_PROJECT_SAVE, | |
| 370 | + const.ID_PROJECT_SAVE_AS, | |
| 371 | + const.ID_PROJECT_CLOSE] | |
| 370 | 372 | self.__init_items() |
| 371 | 373 | self.__bind_events() |
| 372 | 374 | |
| 375 | + self.SetStateProjectClose() | |
| 376 | + | |
| 377 | + def __bind_events(self): | |
| 378 | + """ | |
| 379 | + Bind events related to pubsub. | |
| 380 | + """ | |
| 381 | + # TODO: in future, possibly when wxPython 2.9 is available, | |
| 382 | + # events should be binded directly from wx.Menu / wx.MenuBar | |
| 383 | + # message "Binding events of wx.MenuBar" on [wxpython-users] | |
| 384 | + # mail list in Oct 20 2008 | |
| 385 | + ps.Publisher().subscribe(self.OnEnableState, "Enable state project") | |
| 386 | + | |
| 373 | 387 | def __init_items(self): |
| 388 | + """ | |
| 389 | + Create all menu and submenus, and add them to self. | |
| 390 | + """ | |
| 391 | + # TODO: This definetely needs improvements... ;) | |
| 374 | 392 | |
| 375 | 393 | # FILE |
| 376 | 394 | file_menu = wx.Menu() |
| 377 | - #file_menu.Append(const.ID_DICOM_LOAD_NET, "Import DICOM from Internet...") | |
| 378 | 395 | file_menu.Append(const.ID_DICOM_IMPORT, _("Import DICOM...\tCtrl+I")) |
| 396 | + #file_menu.Append(const.ID_DICOM_LOAD_NET, _("Import DICOM from PACS...")) | |
| 379 | 397 | file_menu.Append(const.ID_PROJECT_OPEN, _("Open Project...\tCtrl+O")) |
| 380 | 398 | file_menu.Append(const.ID_PROJECT_SAVE, _("Save Project\tCtrl+S")) |
| 381 | 399 | file_menu.Append(const.ID_PROJECT_SAVE_AS, _("Save Project As...")) |
| 382 | 400 | file_menu.Append(const.ID_PROJECT_CLOSE, _("Close Project")) |
| 383 | 401 | file_menu.AppendSeparator() |
| 384 | - #file_menu.Append(const.ID_PROJECT_INFO, "Project Information...") | |
| 402 | + #file_menu.Append(const.ID_PROJECT_INFO, _("Project Information...")) | |
| 385 | 403 | #file_menu.AppendSeparator() |
| 386 | - #file_menu.Append(const.ID_SAVE_SCREENSHOT, "Save Screenshot") | |
| 387 | - #file_menu.Append(const.ID_PRINT_SCREENSHOT, "Print Screenshot") | |
| 404 | + #file_menu.Append(const.ID_SAVE_SCREENSHOT, _("Save Screenshot")) | |
| 405 | + #file_menu.Append(const.ID_PRINT_SCREENSHOT, _("Print Screenshot")) | |
| 388 | 406 | #file_menu.AppendSeparator() |
| 389 | 407 | #file_menu.Append(1, "C:\InvData\sample.inv") |
| 390 | 408 | #file_menu.AppendSeparator() |
| ... | ... | @@ -407,7 +425,6 @@ class MenuBar(wx.MenuBar): |
| 407 | 425 | #view_layout_menu.Append(const.ID_TASK_BAR, "Task Bar") |
| 408 | 426 | #view_layout_menu.Append(const.ID_VIEW_FOUR, "Four View") |
| 409 | 427 | |
| 410 | - | |
| 411 | 428 | #view_menu = wx.Menu() |
| 412 | 429 | #view_menu.AppendMenu(-1, "Toolbars",view_tool_menu) |
| 413 | 430 | #view_menu.AppendMenu(-1, "Layout", view_layout_menu) |
| ... | ... | @@ -433,12 +450,13 @@ class MenuBar(wx.MenuBar): |
| 433 | 450 | help_menu.Append(const.ID_ABOUT, _("About...")) |
| 434 | 451 | #help_menu.Append(107, "Check For Updates Now...") |
| 435 | 452 | |
| 436 | - # TODO: Check what is necessary under MacOS to show Groo and not Python | |
| 453 | + # TODO: Check what is necessary under MacOS to show | |
| 454 | + # InVesalius and not Python | |
| 437 | 455 | # first menu item... Didn't manage to solve it up to now, the 3 lines |
| 438 | 456 | # bellow are a frustated test, based on wxPython Demo |
| 439 | 457 | # TODO: Google about this |
| 440 | 458 | #test_menu = wx.Menu() |
| 441 | - #test_item = test_menu.Append(-1, '&About Groo', 'Groo RULES!!!') | |
| 459 | + #test_item = test_menu.Append(-1, '&About InVesalius','InVesalius') | |
| 442 | 460 | #wx.App.SetMacAboutMenuItemId(test_item.GetId()) |
| 443 | 461 | |
| 444 | 462 | self.Append(file_menu, _("File")) |
| ... | ... | @@ -449,104 +467,136 @@ class MenuBar(wx.MenuBar): |
| 449 | 467 | self.Append(help_menu, _("Help")) |
| 450 | 468 | |
| 451 | 469 | |
| 452 | - self.enable_items = [const.ID_PROJECT_SAVE, const.ID_PROJECT_SAVE_AS, | |
| 453 | - const.ID_PROJECT_CLOSE] | |
| 454 | - | |
| 455 | - self.SetStateProjectClose() | |
| 456 | - | |
| 457 | 470 | def OnEnableState(self, pubsub_evt): |
| 471 | + """ | |
| 472 | + Based on given state, enables or disables menu items which | |
| 473 | + depend if project is open or not. | |
| 474 | + """ | |
| 458 | 475 | state = pubsub_evt.data |
| 459 | 476 | if state: |
| 460 | 477 | self.SetStateProjectOpen() |
| 461 | 478 | else: |
| 462 | 479 | self.SetStateProjectClose() |
| 463 | 480 | |
| 481 | + def SetStateProjectClose(self): | |
| 482 | + """ | |
| 483 | + Disable menu items (e.g. save) when project is closed. | |
| 484 | + """ | |
| 485 | + for item in self.enable_items: | |
| 486 | + self.Enable(item, False) | |
| 464 | 487 | |
| 465 | 488 | def SetStateProjectOpen(self): |
| 489 | + """ | |
| 490 | + Enable menu items (e.g. save) when project is opened. | |
| 491 | + """ | |
| 466 | 492 | for item in self.enable_items: |
| 467 | 493 | self.Enable(item, True) |
| 468 | 494 | |
| 469 | - def SetStateProjectClose(self): | |
| 470 | - for item in self.enable_items: | |
| 471 | - self.Enable(item, False) | |
| 472 | - | |
| 473 | - def __bind_events(self): | |
| 474 | - # TODO: in future, possibly when wxPython 2.9 is available, | |
| 475 | - # events should be binded directly from wx.Menu / wx.MenuBar | |
| 476 | - # message "Binding events of wx.MenuBar" on [wxpython-users] | |
| 477 | - # mail list in Oct 20 2008 | |
| 478 | - ps.Publisher().subscribe(self.OnEnableState, "Enable state project") | |
| 495 | +# ------------------------------------------------------------------ | |
| 496 | +# ------------------------------------------------------------------ | |
| 497 | +# ------------------------------------------------------------------ | |
| 479 | 498 | |
| 480 | 499 | |
| 481 | -# ------------------------------------------------------------------ | |
| 482 | 500 | class ProgressBar(wx.Gauge): |
| 501 | + """ | |
| 502 | + Progress bar / gauge. | |
| 503 | + """ | |
| 504 | + | |
| 505 | + def __init__(self, parent): | |
| 506 | + wx.Gauge.__init__(self, parent, -1, 100) | |
| 507 | + self.parent = parent | |
| 508 | + self._Layout() | |
| 483 | 509 | |
| 484 | - def __init__(self, parent): | |
| 485 | - wx.Gauge.__init__(self, parent, -1, 100) | |
| 486 | - self.parent = parent | |
| 487 | - self.Reposition() | |
| 488 | - self.__bind_events() | |
| 510 | + self.__bind_events() | |
| 489 | 511 | |
| 490 | - def __bind_events(self): | |
| 491 | - ps.Publisher().subscribe(self.Reposition, | |
| 512 | + def __bind_events(self): | |
| 513 | + """ | |
| 514 | + Bind events related to pubsub. | |
| 515 | + """ | |
| 516 | + ps.Publisher().subscribe(self._Layout, | |
| 492 | 517 | 'ProgressBar Reposition') |
| 493 | 518 | |
| 494 | - def UpdateValue(self, value): | |
| 495 | - #value = int(math.ceil(evt_pubsub.data[0])) | |
| 496 | - self.SetValue(int(value)) | |
| 519 | + def _Layout(self, evt_pubsub=None): | |
| 520 | + """ | |
| 521 | + Compute new size and position, according to parent resize | |
| 522 | + """ | |
| 523 | + rect = self.parent.GetFieldRect(2) | |
| 524 | + self.SetPosition((rect.x + 2, rect.y + 2)) | |
| 525 | + self.SetSize((rect.width - 4, rect.height - 4)) | |
| 497 | 526 | |
| 498 | - if (value >= 99): | |
| 499 | - self.SetValue(0) | |
| 527 | + def SetPercentage(self, value): | |
| 528 | + """ | |
| 529 | + Set value [0;100] into gauge, moving "status" percentage. | |
| 530 | + """ | |
| 531 | + self.SetValue(int(value)) | |
| 532 | + if (value >= 99): | |
| 533 | + self.SetValue(0) | |
| 534 | + self.Refresh() | |
| 535 | + self.Update() | |
| 500 | 536 | |
| 501 | - self.Refresh() | |
| 502 | - self.Update() | |
| 537 | +# ------------------------------------------------------------------ | |
| 538 | +# ------------------------------------------------------------------ | |
| 539 | +# ------------------------------------------------------------------ | |
| 503 | 540 | |
| 504 | - def Reposition(self, evt_pubsub = None): | |
| 505 | - rect = self.Parent.GetFieldRect(2) | |
| 506 | - self.SetPosition((rect.x + 2, rect.y + 2)) | |
| 507 | - self.SetSize((rect.width - 4, rect.height - 4)) | |
| 508 | 541 | |
| 509 | -# ------------------------------------------------------------------ | |
| 510 | 542 | class StatusBar(wx.StatusBar): |
| 543 | + """ | |
| 544 | + Control general status (both text and gauge) | |
| 545 | + """ | |
| 511 | 546 | def __init__(self, parent): |
| 512 | 547 | wx.StatusBar.__init__(self, parent, -1) |
| 548 | + | |
| 549 | + # General status configurations | |
| 513 | 550 | self.SetFieldsCount(3) |
| 514 | 551 | self.SetStatusWidths([-2,-2,-1]) |
| 515 | 552 | self.SetStatusText(_("Ready"), 0) |
| 516 | 553 | self.SetStatusText("", 1) |
| 517 | 554 | self.SetStatusText("", 2) |
| 518 | 555 | |
| 556 | + # Add gaugee | |
| 519 | 557 | self.progress_bar = ProgressBar(self) |
| 520 | 558 | |
| 521 | 559 | self.__bind_events() |
| 522 | 560 | |
| 523 | 561 | def __bind_events(self): |
| 524 | - ps.Publisher().subscribe(self.UpdateStatus, | |
| 562 | + """ | |
| 563 | + Bind events related to pubsub. | |
| 564 | + """ | |
| 565 | + ps.Publisher().subscribe(self._SetProgressValue, | |
| 525 | 566 | 'Update status in GUI') |
| 526 | - ps.Publisher().subscribe(self.UpdateStatusLabel, | |
| 567 | + ps.Publisher().subscribe(self._SetProgressLabel, | |
| 527 | 568 | 'Update status text in GUI') |
| 528 | 569 | |
| 529 | - def UpdateStatus(self, pubsub_evt): | |
| 570 | + def _SetProgressValue(self, pubsub_evt): | |
| 571 | + """ | |
| 572 | + Set both percentage value in gauge and text progress label in | |
| 573 | + status. | |
| 574 | + """ | |
| 530 | 575 | value, label = pubsub_evt.data |
| 531 | - self.progress_bar.UpdateValue(value) | |
| 576 | + self.progress_bar.SetPercentage(value) | |
| 532 | 577 | self.SetStatusText(label, 0) |
| 533 | 578 | if (int(value) >= 99): |
| 534 | 579 | self.SetStatusText("",0) |
| 535 | 580 | if sys.platform == 'win32': |
| 581 | + #TODO: temporary fix necessary in the Windows XP 64 Bits | |
| 582 | + #BUG in wxWidgets http://trac.wxwidgets.org/ticket/10896 | |
| 536 | 583 | try: |
| 537 | 584 | #wx.SafeYield() |
| 538 | 585 | wx.Yield() |
| 539 | - #TODO: temporary fix necessary in the Windows XP 64 Bits | |
| 540 | - #BUG in wxWidgets http://trac.wxwidgets.org/ticket/10896 | |
| 541 | 586 | except(wx._core.PyAssertionError): |
| 542 | 587 | utils.debug("wx._core.PyAssertionError") |
| 543 | 588 | |
| 544 | - def UpdateStatusLabel(self, pubsub_evt): | |
| 589 | + def _SetProgressLabel(self, pubsub_evt): | |
| 590 | + """ | |
| 591 | + Set text progress label. | |
| 592 | + """ | |
| 545 | 593 | label = pubsub_evt.data |
| 546 | 594 | self.SetStatusText(label, 0) |
| 547 | 595 | |
| 548 | 596 | |
| 549 | 597 | # ------------------------------------------------------------------ |
| 598 | +# ------------------------------------------------------------------ | |
| 599 | +# ------------------------------------------------------------------ | |
| 550 | 600 | |
| 551 | 601 | class TaskBarIcon(wx.TaskBarIcon): |
| 552 | 602 | def __init__(self, parent=None): |
| ... | ... | @@ -564,13 +614,16 @@ class TaskBarIcon(wx.TaskBarIcon): |
| 564 | 614 | def OnTaskBarActivate(self): |
| 565 | 615 | pass |
| 566 | 616 | |
| 617 | + | |
| 618 | +# ------------------------------------------------------------------ | |
| 619 | +# ------------------------------------------------------------------ | |
| 567 | 620 | # ------------------------------------------------------------------ |
| 568 | 621 | |
| 569 | 622 | class ProjectToolBar(wx.ToolBar): |
| 570 | 623 | def __init__(self, parent): |
| 571 | 624 | wx.ToolBar.__init__(self, parent, -1, wx.DefaultPosition, |
| 572 | 625 | wx.DefaultSize, |
| 573 | - wx.TB_FLAT|wx.TB_NODIVIDER | wx.TB_DOCKABLE) | |
| 626 | + wx.TB_FLAT|wx.TB_NODIVIDER| wx.TB_DOCKABLE) | |
| 574 | 627 | |
| 575 | 628 | self.SetToolBitmapSize(wx.Size(32,32)) |
| 576 | 629 | |
| ... | ... | @@ -686,9 +739,9 @@ class ProjectToolBar(wx.ToolBar): |
| 686 | 739 | event.Skip() |
| 687 | 740 | |
| 688 | 741 | |
| 689 | - | |
| 690 | - | |
| 691 | - # ------------------------------------------------------------------ | |
| 742 | +# ------------------------------------------------------------------ | |
| 743 | +# ------------------------------------------------------------------ | |
| 744 | +# ------------------------------------------------------------------ | |
| 692 | 745 | |
| 693 | 746 | class ObjectToolBar(wx.ToolBar): |
| 694 | 747 | def __init__(self, parent): |
| ... | ... | @@ -816,7 +869,10 @@ class ObjectToolBar(wx.ToolBar): |
| 816 | 869 | if state: |
| 817 | 870 | self.ToggleTool(id, False) |
| 818 | 871 | |
| 819 | -# ------------------------------------------------------------------- | |
| 872 | + | |
| 873 | +# ------------------------------------------------------------------ | |
| 874 | +# ------------------------------------------------------------------ | |
| 875 | +# ------------------------------------------------------------------ | |
| 820 | 876 | |
| 821 | 877 | class SliceToolBar(wx.ToolBar): |
| 822 | 878 | def __init__(self, parent): |
| ... | ... | @@ -905,10 +961,12 @@ class SliceToolBar(wx.ToolBar): |
| 905 | 961 | if id == const.SLICE_STATE_CROSS: |
| 906 | 962 | ps.Publisher().sendMessage('Set cross visibility', 0) |
| 907 | 963 | |
| 908 | -# --------------------------------------------------------------------- | |
| 964 | + | |
| 965 | +# ------------------------------------------------------------------ | |
| 966 | +# ------------------------------------------------------------------ | |
| 967 | +# ------------------------------------------------------------------ | |
| 909 | 968 | |
| 910 | 969 | class LayoutToolBar(wx.ToolBar): |
| 911 | - # TODO: what will appear in menubar? | |
| 912 | 970 | def __init__(self, parent): |
| 913 | 971 | wx.ToolBar.__init__(self, parent, -1, wx.DefaultPosition, |
| 914 | 972 | wx.DefaultSize, | ... | ... |