Difference between revisions of "Slicer3:Interface Design and Usability"

From NAMIC Wiki
Jump to: navigation, search
m (Text replacement - "http://www.slicer.org/slicerWiki/index.php/" to "https://www.slicer.org/wiki/")
 
(44 intermediate revisions by 2 users not shown)
Line 1: Line 1:
'''[[Slicer3|<< Back to Slicer3 main page]]'''
+
<big>'''Note:''' We are migrating this content to the slicer.org domain - <font color="orange">The newer page is [https://www.slicer.org/wiki/Slicer3:Interface_Design_and_Usability here]</font></big>
 
 
[[Slicer3:Developers |Go to Slicer3 Developer Info >> ]]
 
 
 
 
 
<br />
 
 
 
= Project goals =
 
 
 
Design and engineer Slicer3 UI. Employ a user-centered approach and establish usability guidelines.
 
 
 
= Project reporting =
 
 
 
The scope of this effort is sorted into four categories: Engineering, UI design, Usability and Slicer3 branding. The subtasks of each category are itemized below and specific information about each category is located on the linked pages.
 
 
 
=== [[Slicer3:UIEngineering|UI Architecture & Engineering]] ===
 
 
 
Tasks: (more detailed UI Architecture & Engineering information can be found [[Slicer3:UIEngineering|here]]).
 
 
 
* design thin GUI layer, separate from the control logic and data model;
 
* design a model for representing the UI and managing local events;
 
* extend the model for handling remote events;
 
* design means of mapping KWWidgets onto that model;
 
* set priorities with Kitware involving extensions & modifications to KWWidgets;
 
* determine the api to application logic, used by GUI and by scripts;
 
* design set of base classes that give module developers an easy pattern to follow;
 
* develop guidelines for slicer base developers and module developers;
 
* design mechanism for centrally specifying look & feel (and permitting overrides);
 
 
 
=== [[Slicer3:UIDesign|UI Design & Prototypes]] ===
 
 
 
Tasks: (more detailed UI Design & Prototype information can be found [[Slicer3:UIDesign|here ]]).
 
 
 
* design overall look to Slicer3 application in keeping with core values;
 
* design look & feel applied to developer modules;
 
* design KWWidgets class to specify custom widgets for Slicer main app & modules;
 
* implement Slicer3 Application GUI
 
* design conventions for specifying global and module-specific keyboard accelerators;
 
* specify and document global keyboard accelerators;
 
* iterate on prototype(s) and present them for comments and suggestions;
 
 
 
=== [[Slicer3:Usability|Usability]] ===
 
 
 
Tasks: (more detailed Usability information can be found [[Slicer3:Usability|here ]]).
 
 
 
* develop and publish a user-centered design practice that support usability and software consistency.
 
* use this process to design and implement main application interface, and some core functionality.
 
 
 
=== [[Slicer3:Slicer3Brand|3DSlicer Brand]] ===
 
 
 
Tasks: (Slicer3 brand sketches can be found[[Slicer3:Slicer3Brand| here ]]).
 
 
 
* fully express new 3DSlicer brand: design logo, splash screen, style sheets for web presence;
 
 
 
 
 
 
 
= First steps: How to build a Slicer3 Module GUI =
 
 
 
== Virtual Methods ==
 
 
 
At the slicer-developers tcon 2007-02-13, we discussed some adjustments to the virtual methods in vtkSlicerModuleGUI for better consistency and utility. The following list defines the methods that a module needs to implement so the main application (Slicer3.cxx) can operate on all modules generically:
 
 
 
<div style="width: 40%; float: left; padding-right: 3%;">
 
The following methods are defined by the vtkSlicerModuleGUI and typically won't be overriden:
 
 
 
* '''Enter'''
 
** ''called when module is raised''
 
** ''calls CreateGUI if needed (instance variable tracks create state)''
 
** ''calls AddGUIObservers''
 
** ''calls UpdateGUI''
 
* '''Exit'''
 
** ''called when module is replaced by another''
 
** ''calls RemoveMRMLObservers''
 
</div>
 
 
 
<div style="width: 40%; float: left; padding-right: 3%;">
 
 
 
The following methods should be defined by the Module to implement the specific behavior:
 
 
 
* '''CreateGUI'''
 
** ''instances and packs widgets''
 
* '''DestroyGUI'''
 
** ''typically called only by destructor''
 
** ''breaks any reference cycles''
 
** ''Deletes widgets''
 
* '''ProcessGUIEvents'''
 
** ''responds to events from widgets or slicer GUI classes''
 
** ''propagates data from GUI into MRML nodes''
 
* '''ProcessMRMLEvents'''
 
** ''responds to updates to MRML nodes''
 
** ''propagates data from MRML to widgets''
 
* '''AddGUIObservers'''
 
** ''set observers on widgets and GUI classes (use GUICallbackCommand local instance -- it will call ProcessGUIEvents)''
 
* '''AddMRMLObservers'''
 
** ''set observers on MRML nodes and scene (use MRMLCallbackCommand local instance -- it will call ProcessMRMLEvents)''
 
* '''RemoveGUIObservers'''
 
* '''RemoveMRMLObservers'''
 
* '''UpdateGUI'''
 
** ''copy state from MRML nodes to GUI/Widgets''
 
** ''if needed for efficiency, check the MTime for the MRML Node and the corresponding GUI and only update if needed (e.g. for a MultiColumnList or other widget the holds a lot of data)''
 
* '''UpdateMRML'''
 
** ''copy state from GUI/Widgets to MRML''
 
</div>
 
 
 
<br style="clear: both;" />
 
 
 
== Usage ==
 
 
 
'''NOTE: this description will change due to current ongoing changes to the module GUI base classes.'''
 
The figure below shows a current overview of the three classes a new module (called MyModule for example) will need to define (vtkSlicerMyModuleGUI, vtkSlicerMyModuleLogic and vtkMRMLMyModuleNode) and some of the methods those classes should include to utilize the Slicer3 infrastructure. These classes should reside in the slicer3/Modules/MyModule/ directory.
 
 
 
[[Image:Slicer3MyModule.png|[[Image:Slicer3MyModule.png| Base classes for GUI, Logic and MRML ]]]]
 
 
 
'''Deriving your GUI class:''' To create a Module GUI that expresses its interface in Slicer's shared UIpanel, derive your class (vtkSlicerMyModuleGUI) from vtkSlicerModuleGUI. For a Module GUI that expresses its interface in a different panel of the Main Slicer Window, or in a toplevel widget, derive vtkSlicerMyModuleGUI from vtkSlicerComponentGUI instead. Your GUI class will inherit application logic and MRML pointers, an API for setting and observing them, and a framework for defining MRML, Logic and GUI callbacks from its parent class. Specific mediator methods, other logic and MRML node pointers can be added to the module's class definition. Importantly, keep logic and MRML classes independent of the GUI to facilitate testing and command-line execution possible *without* instantiating the Slicer3 GUI.
 
 
 
'''Example:''' An early example to work from is the GradientAnisotropicDiffusionFilter Module; define all the widgets you need within the class and create Get Macros for each of them. Define the methods you need from vtkSlicerModuleGUI and its parent class vtkSlicerComponentGUI, including BuildGUI(); in this method, you'll first add a page to the class's UIPanel (for now, only create one page).
 
 
 
=== Two GUI styles ===
 
'''Two styles:''' Depending on whether you want a notebook-style GUI for your module (similar to the style used in Slicer2) or a set of stacked collapsible frames to contain different logical sections of your interface like "help" and "display", your BuildGUI() method can be written in one of two ways. The '''notebook style''' may be appropriate for modules with long logical sections within their GUI, to minimize the amount of scrolling required of a user. The '''collapsing style''' may be appropriate for modules that have numerous logical sections, since the amount of horizontal space across which a notebook would array them is limited. The way these two styles are expressed in Slicer3's GUI panel is shown below.
 
 
 
[[Image:S3ModuleStyles.png]]
 
 
 
'''''Collapsing style:''''' The GradientAnisotropicDiffusionFilter Module example implements the collapsible style, first adding a single new Page in its UIPanel:
 
 
 
  this->UIPanel->AddPage ( "MyModule", "MyModule", NULL );
 
 
 
then creating a vtkSlicerModuleCollapsibleFrame widget for each logical section in the GUI, parenting each to the UIPanel's single PageWidget, then creating, configuring and packing them from top to bottom in the UIPanel's PageWidget. Each logical section's widgets can be organized inside each of the vtkSlicerModuleCollapsibleFrames. The superclass has some helper methods to construct consisten Help&About Frames across modules.
 
 
 
  //--- help and about frame
 
  const char *help = "MyModule does the following...";
 
  const char *about = "This work was supported by...";
 
  vtkKWWidget *page = this->UIPanel->GetPageWidget ("MyModule");
 
  this->BuildHelpAndAboutFrame ( page, help, about );
 
 
 
  //--- rest of the frames
 
  vtkSlicerModuleCollapsibleFrame *firstFrame = vtkSlicerModuleCollapsibleFrame::New ( );
 
  vtkSlicerModuleCollapsibleFrame *secondFrame = vtkSlicerModuleCollapsibleFrame::New ( );
 
  vtkSlicerModuleCollapsibleFrame *thirdFrame = vtkSlicerModuleCollapsibleFrame::New ( );
 
  vtkSlicerModuleCollapsibleFrame *forthFrame = vtkSlicerModuleCollapsibleFrame::New ( );
 
  ...
 
  //--- parenting the frames to the same UIpanel page
 
  firstFrame->SetParent ( page );
 
  secondFrame->SetParent ( page );
 
  ...
 
  //--- parenting widgets to the various frames
 
  this->widget2->SetParent ( firstFrame->GetFrame () );
 
  this->widget3->SetParent ( secondFrame->GetFrame () );
 
 
 
'''''Notebook style:''''' To create a notebook style GUI (as there is no example yet, a little code will be included here), a new Page must be added to the UIPanel for every tab in the notebook:
 
 
 
  //--- get a pointer to the KWUserInterfaceManagerNotebook
 
  vtkKWUserInterfaceManagerNotebook *nbm = vtkKWUserInterfaceManagerNotebook::SafeDownCast ( this->UIPanel->GetUserInterfaceManager());
 
  //--- help and about frame
 
  this->UIPanel->AddPage ( "Help&About", "Information about using this module", NULL );
 
  const char *help = "MyModule does the following...";
 
  const char *about = "This work was supported by...";
 
  vtkKWWidget *page = this->UIPanel->GetPageWidget ("Help");
 
  this->BuildHelpAndAboutFrame ( page, help, about );
 
 
 
  //--- pages for other frames
 
  int page1ID = this->UIPanel->AddPage ( "First", "Functionality for some logical piece of module", NULL );
 
  int page2ID = this->UIPanel->AddPage ( "Second", "Functionality for another logical piece of module", NULL );
 
 
 
  //--- enabling or disabling notebook tabs
 
  nbm->GetNotebook()->SetPageEnabled ( page1ID, 1 );
 
  nbm->GetNotebook()->SetPageEnabled ( page2ID, 0 );
 
 
 
Widgets to be packed within each notebook page are parented to the PageWidget:
 
 
 
  this->widget2->SetParent ( this->UIPanel->GetPageWidget ( "First" ) );
 
  this->widget3->SetParent ( this->UIPanel->GetPageWidget ( "Second" ) );
 
 
 
or can be parented to a widget already parented to the PageWidget. Then they themselves can be created, configured, and packed in the same manner as they are in the GradientAnisotropicDiffusionFilter Module.
 
 
 
=== Defining methods ===
 
'''Methods to define:''' Define the methods you require from vtkSlicerComponentGUI base class, like: AddGUIObservers(), RemoveGUIObservers(), ProcessLogicEvents(), ProcessGUIEevents(), ProcessMRMLEvents(), Enter() and Exit(); and whatever else your module needs. (Eventually, available modules will be automatically detected, but this is not yet implemented; then, the Enter() method will probably be made to call the BuildGUI() method. For now, instantiate your class in Slicer3.cxx and call its BuildGUI() and other methods, following the pattern for other modules established there.)
 
 
 
=== Adding and removing observers ===
 
'''Adding observers:''' In AddGUIObservers, add an observer on each widget whose events you want to process. When an event is observed, the ProcessGUIEvents() method is called via the GUICallbackCommand; define this class to propagate information from the GUI to logic and MRML. Though it is tempting, try not to use ProcessGUIEvents() to update the GUI state directly -- just modify the Logic state, and allow observers on the logic and subsequent processing in ProcessLogicEvents() and ProcessMRMLEvents() to bring that state change BACK into the GUI.
 
 
 
'''Removing observers:''' In RemoveGUIObservers, make sure you remove every observer you've added to widgets in the GUI before calling Delete() on your widget. Make sure you call SetAndObserveMRML() and SetAndObserveLogic( ) with NULL pointers in your GUI class destructor to remove all observers on MRML and Logic that you have created.
 
 
 
=== Adding and removing references ===
 
For convenience, you may want to define pointers to Slicer's MainViewer, or to the SliceViewers, etc. Before Delete() can be called on anything you are referencing, you'll need to release the references. (Failure to release references can result in vtkDebugLeak reports on Application exit). The virtual method TearDownGUI() (inherited from vtkSlicerComponentGUI) can be defined for this purpose. References may be released in this method, and you can also use this method to call RemoveGUIObservers() if you don't want to explicitly call that method.
 
 
 
=== Defining new widgets ===
 
'''Defining your own widgets:''' The framework for doing this is still evolving. Currently there are two types of new widgets, those defined as extensions to vtkKW (like vtkKWWindowLevelThresholdEditor.h/cxx) and those defined as Slicer-specific widgets, (like vtkSlicerSliceControlWidget.h/cxx, derived from the vtkSlicerWidget.h/cxx base class). The Slicer widgets have methods for putting observers on their widget components, Logic and MRML, and processing events as well. Thus GUI classes that instance them do not have to manage events for them if the widgets' methods are used instead.
 
 
 
=== Using Undo and Redo ===
 
'''Undo:''' Make sure you process those events that mark junctures at which MRML state should be saved for Undo/Redo (using MRML's SaveStateForUndo() method. For instance, when an entry widget's value has changed, before changing a parameter in the appropriate MRML node, make a call to the MRMLScene's SaveStateForUndo() method with that node as a parameter. Save MRML state at reasonable junctures: for instance, for scale widgets, save MRML state when the scale starts changing, rather than continuously as the scale changes. For an example of they way SaveStateForUndo() is called, see slicer3/Base/GUI/vtkSlicerSliceControllerWidget.cxx. A detailed description of how undo/redo works, and how to use it in your module is available [[Slicer3:Data_Model#Undo.2FRedo_Mechanism | here]].
 
 
 
=== Adding the module to the rest of Slicer3 ===
 
'''Other files you will have to touch:''' For now, to add your module to Slicer3, create a new instance of vtkSlicerMyModuleLogic and vtkSlicerMyModuleGUI in Applications/GUI/Slicer3.cxx, and follow the pattern used by the GradientAnisotropicDiffusionFilter module for now, until the framework is developed for Slicer3 to autodetect your module and do the right things. Then:
 
 
 
* create your own CMakeLists.txt file and your own vtkMyModuleWin32Header.h file following the pattern set by other Modules.
 
* add your module SUBDIR to the CMakeLists.txt file in the Slicer3/Modules directory above.
 
* to add your module to Slicer3, create a new instance of vtkSlicerMyModuleLogic and vtkSlicerMyModuleGUI in Slicer3/Applications/GUI/Slicer3.cxx, and follow the pattern used by other modules, like the GradientAnisotropicDiffusionFilter module.
 
* include relevant .h files in Slicer3/Applications/GUI/Slicer3.cxx, and
 
* specify your module's source and binary Include directories in Slicer3/Application/GUI/CMakeLists.txt
 
* and include your module in the CMakeLists.txt target link libraries
 
 
 
===Add a module-switch in CMake===
 
You can add an automatic on/off switch to the ccmake configuration GUI, which will make compilation and development for the user easier.
 
To do this add the following to two CMakeLists.txt und the Slicer3.cxx files:
 
 
 
* add the following lines to your Slicer3/Module/MyModule/CMakeLists.txt
 
PROJECT(MyModule)
 
 
OPTION(MYMODULE "Do you want to build the MyModule?")
 
IF(MYMODULE)
 
... (Rest of the file)
 
ENDIF(MYMODULE)
 
 
 
* after this you have MYMODULE as a variable which says if your module is build or not
 
* but we want also to exclude the module library and our source in the Slicer3.cxx file if the module is not build
 
* in /Slicer3/Applications/GUI/CMakeLists.txt add the following directly above TARGET_LINK_LIBRARIES(...
 
IF(MYMODULE)
 
  SET(MYMODULE_LINK_LIB MyModule)
 
ELSE(MYMODULE)
 
  ADD_DEFINITIONS(-DMYMODULE_DEBUG)
 
ENDIF(MYMODULE)
 
* then add to the TARGET_LINK_LIBRARIES(...${MYMODULE_LINK_LIB}) instead of your previous entry
 
* the ''ADD_DEFINITIONS'' declaration adds a preprocessor symbol to the compile which we use to exclude our code from the /Slicer3/Applications/GUI/Slicer3.cxx
 
* just border your code in /Slicer3/Applications/GUI/Slicer3.cxx with the following:
 
#ifndef MYMODULE_DEBUG
 
...(your code/includes)
 
  #endif
 
 
 
=== Miscellaneous ===
 
'''Helpful tips:'''
 
* Make the vtkModuleCollapsibleFrames which contain the major logical sections of your module members of your module GUI class and expose them through your API. Doing so helps other developers, who may want to offer a jump to your module's functionality, to programmatically raise your UIpanel and expand the frame they're interested in. This paradigm will help to promote fluid navigation of slicer's interface and the reuse of existing functionality.
 
 
 
= Human Interface and Style Guide for Developers (STILL UNDER DEVELOPMENT) =
 
 
 
=== Introduction ===
 
 
 
These following sections (work in progress) describe how to create 3DSlicer modules that conform to the application's look and feel and behave in a manner consistent with the rest of 3DSlicer. Provided is  information on basic interface elements, advice on the effective GUI construction with the available widget set, and some recommended design principles that will help your module integrate well with the rest of 3DSlicer. These guidelines are also intended to enhance 3DSlicer's usability. Following the simple design philosophy outlined here will support the following important goals:
 
 
 
 
 
* Users will learn to use your module faster, because interface elements will look and behave in an expected manner across the application.
 
* Your module will have a nice look & feel that fits within the 3DSlicer environment.
 
* Your module will be accessible to users at all levels (novice, intermediate and expert).
 
 
 
 
 
=== Look and Feel ===
 
 
 
'''GUI Style:''' Try not to add style elements (like foreground and background color, font, relief, etc.) to the interface you create; let the options database (as set up by the vtkSlicerTheme class) specify the style for the widgets in your module so that all modules appear consistent within the Slicer3 application.
 
 
 
=== Module style ===
 
 
 
=== Pop-up windows ===
 
 
 
=== Confirm on Delete ===
 
 
 
Check vtkSlicerApplication::ConfirmDelete setting; if a user has requested to be presented with a confirm on delete, then give them that option.
 
 
 
=== [[Event Bindings]] ===
 
 
 
With respect to the specification of keyboard accelerators, please follow these three recommendations;
 
 
 
* Before assigning "hot-keys" to functionality, either in the main Slicer application or in a new module, please consult the table (and design plan) linked below to make sure the key is not already assigned.
 
* Across Slicer modules, try to use similar "hot-key" assignments for similar functionality; this consistency makes Slicer easier to learn.
 
* Once you assign "hot-keys" in your module, please add those mappings to the table for others to reference.
 
 
 
=== Application Font ===
 
Verdana is the font chosen for the 3DSlicer brand.
 
 
 
Maintaining consistency of type is an important component of maintaining a coherent look and feel for 3DSlicer and any related or derived visual communications. Verdana was designed specifically to be read on a digital display; it is recommended that we use Verdana (or Geneva) wherever possible in 3DSlicer's web presence and online tutorial materials, and wherever reasonable and appropriate in formal printed materials.
 
 
 
Within the software, since it can't be guaranteed that these fonts will be widely available on all platforms, Helvetica or Arial should be used as a substitute. Slicer's theme sets the application font to be Helvetica 8 normal. Please avoid typefaces with serifs.
 
 
 
=== Icons ===
 
 
 
Icons can be a powerful way to represent complicated information within a small footprint on the GUI panel. They associate a visual image with data, state, or a particular operation.
 
 
 
* They should be easy to parse, convey a strong metaphor, and not require significant time for a user to interpret.
 
* They should be memorable so that a user can recognize them quickly in future sessions with your module.
 
* If an icon already exists within 3DSlicer to represent the data, state or operation you want to indicate, then re-use that icon (indicate visibility with the open/shutting eye, for example.)
 
* Note: if the concept is too difficult to represent with a picture, then a text label can always be used instead!
 
 
 
When designing icons, do bear in mind that it's possible to offend users with images that have cultural or polictal connotations. Even colors can have connotations for users in different parts of the world that may be surprising and unintended for the designer and developer. Generally speaking, it's useful to avoid images that contain:
 
 
 
* icons that depict only hands or feet
 
* images of animals
 
* maps containing disputed boundaries or region names.
 
* lists of countries that are not in alphabetical order.
 
* pictures of flags
 
* pictures of money
 
 
 
====Slicer icon conventions====
 
3DSlicer icons should all be of dimension 21x21 pixels.
 
 
 
'''Enabled''' or '''Enabled + Selected''' icons should have:
 
 
 
* a white background (r=255, g=255, b=255, or #FF FF FF)
 
* a black hairline along the perimeter (r=0,g=0,b=0, or #00 00 00).
 
 
 
'''Disabled''' or '''Enabled + Deselected''' icons should have:
 
* a grey background, value (r=230, g=230, b=230, or hex value #E6 E6 E6)
 
* a grey hairline perimeter of value (r=178, g=178, b=178, hex value #B2 B2 B2).
 
 
 
====Downloadable blank icons:====
 
These icon blanks are provided for download and use:
 
 
 
* Enabled or Enabled+Selected: [[image:IconBlank.png | conventional Slicer icon ]]
 
* Disabled or Enabled+Deselected: [[image:IconBlankLow.png | "deselected" Slicer icon]]
 
* Enabled Menubutton: [[image:MenuButtonIconBlank.png | conventional Slicer menubutton icon]]
 
* Disabled Menubutton: [[image:MenuButtonIconBlankDisabled.png | "disabled" Slicer menubutton icon]]
 
 
 
====Icons currently used in Slicer's Base====
 
Below is a figure of icons currently in use in 3DSlicer. If the icon you need is already used in Slicer, we encourage its re-use in your own module (the visibility icon is a good example). However, if an icon is re-used, make sure you are using it to convey the same meaning/function -- icons shouldn't have different meanings in different places. Finally, make sure any new icons designed for a module don't duplicate ones already in use elsewhere in Slicer.
 
 
 
[[Image:SlicerToolbarIcons2.png | Slicer icons ]]
 
 
 
=== Widget-specific patterns to follow ===
 
 
 
=== Providing help ===
 
 
 
=== Popup messages (dialog, warning, error, confirm, etc.) ===
 
 
 
=== Language ===
 
 
 
=== Credit and Logos ===
 
 
 
 
 
 
 
=== Controls and Layout ===
 
 
 
=== Progress Feedback ===
 
 
 
=== Colors: application palette ===
 
 
 
The draft slicer color palette is shown below (this palette will still evolve as the UI design evolves -- in particular to accommodate colors used in the final Slicer3 logo). Developers of code, web content and training materials are encouraged to make color choices for GUI components according to this palette, bearing in mind that some of the colors are linked with special meaning, such as error (red), warning (bright yellow), and system (mediumBlue) messages, and unsaved data in drop-down menus and selection boxes (warmMediumGrey).
 
 
 
[[Image:Slicer3Palette.jpg|[[Image:Slicer3Palette.jpg| Slicer GUI color palette (not applicable to visualization)]]]]
 
 
 
<br />
 
 
 
{| border="1"
 
|- bgcolor="#ffffff"
 
!
 
! color
 
! R
 
! G
 
! B
 
! hex
 
! use in slicer
 
|-
 
| black
 
| bgcolor="#000000" |
 
| align="center" | 0
 
| align="center" | 0
 
| align="center" | 0
 
| #000000
 
|
 
|-
 
| white
 
| bgcolor="#ffffff" |
 
| align="center" | 255
 
| align="center" | 255
 
| align="center" | 255
 
| #ffffff
 
| GUI background
 
|-
 
| darkWarmGrey
 
| bgcolor="#605e53" |
 
| align="center" | 96
 
| align="center" | 94
 
| align="center" | 83
 
| #605e53
 
|
 
|-
 
| mediumWarmGrey
 
| bgcolor="#8b8878" |
 
| align="center" | 139
 
| align="center" | 136
 
| align="center" | 120
 
| #8b8878
 
| unsaved data ?
 
|-
 
| lightWarmGrey
 
| bgcolor="#cdc8b1" |
 
| align="center" | 205
 
| align="center" | 200
 
| align="center" | 177
 
| #cdc8b1
 
|
 
|-
 
| warmGreyTint
 
| bgcolor="#eee8dc" |
 
| align="center" | 238
 
| align="center" | 232
 
| 220
 
| #eee8dc
 
|
 
|-
 
| darkOrange
 
| bgcolor="#c44a1a" |
 
| align="center" | 196
 
| align="center" | 74
 
| align="center" | 26
 
| #c44a1a
 
|
 
|-
 
| brightOrange
 
| bgcolor="#e06f13" |
 
| align="center" | 224
 
| align="center" | 111
 
| align="center" | 19
 
| #e06f13
 
|
 
|-
 
| brightYellow
 
| bgcolor="#e7d13e" |
 
| align="center" | 231
 
| align="center" | 209
 
| align="center" | 62
 
| #e7d13e
 
| warning message code
 
|-
 
| yellowTint
 
| bgcolor="#eed680" |
 
| align="center" | 238
 
| align="center" | 214
 
| align="center" | 128
 
| #eed680
 
| sag slice
 
|-
 
| darkCocoa
 
| bgcolor="#826647" |
 
| align="center" | 130
 
| align="center" | 102
 
| align="center" | 71
 
| #826647
 
|
 
|-
 
| lightCocoa
 
| bgcolor="#b39169" |
 
| align="center" | 179
 
| align="center" | 145
 
| align="center" | 105
 
| #b39169
 
|
 
|-
 
| stone
 
| bgcolor="#e0c39e" |
 
| align="center" | 224
 
| align="center" | 195
 
| align="center" | 158
 
| #e0c39e
 
|
 
|-
 
| stoneTint
 
| bgcolor="#efe0cd" |
 
| align="center" | 239
 
| align="center" | 224
 
| align="center" | 205
 
| #efe0cd
 
|
 
|-
 
| red
 
| bgcolor="#c32e10" |
 
| align="center" | 195
 
| align="center" | 46
 
| align="center" | 15
 
| #c32e10
 
| error message code
 
|-
 
| brick
 
| bgcolor="#ba462b" |
 
| align="center" | 186
 
| align="center" | 70
 
| align="center" | 43
 
| #ba462b
 
|
 
|-
 
| lightBrick
 
| bgcolor="#c17350" |
 
| align="center" | 193
 
| align="center" | 115
 
| align="center" | 80
 
| #c17350
 
| axi slice
 
|-
 
| redTint
 
| bgcolor="#e0b6af" |
 
| align="center" | 224
 
| align="center" | 182
 
| align="center" | 175
 
| #e0b6af
 
|
 
|-
 
| darkGreen
 
| bgcolor="#445632" |
 
| align="center" | 68
 
| align="center" | 86
 
| align="center" | 50
 
| #445632
 
|
 
|-
 
| brightGreen
 
| bgcolor="#688f42" |
 
| align="center" | 104
 
| align="center" | 143
 
| align="center" | 66
 
| #688f42
 
|
 
|-
 
| dustyGreen
 
| bgcolor="#8aa56f" |
 
| align="center" | 138
 
| align="center" | 165
 
| align="center" | 111
 
| #8aa56f
 
| cor slice
 
|-
 
| greenTint
 
| bgcolor="#ccf4a6" |
 
| 204
 
| 244
 
| 166
 
| #ccf4a6
 
|
 
|-
 
| darkBlue
 
| bgcolor="#494066" |
 
| align="center" | 73
 
| align="center" | 64
 
| align="center" | 102
 
| #494066
 
|
 
|-
 
| mediumBlue
 
| bgcolor="#625b81" |
 
| align="center" | 98
 
| align="center" | 91
 
| align="center" | 129
 
| #625b81
 
| system message code
 
|-
 
| lightBlue
 
| bgcolor="#887fa3" |
 
| align="center" | 136
 
| align="center" | 127
 
| align="center" | 163
 
| #887fa3
 
| unsaved data?
 
|-
 
| slicerBlue
 
| bgcolor="#b3b3e6" |
 
| align="center" | 179
 
| align="center" | 179
 
| align="center" | 230
 
| #b3b3e6
 
|
 
|}
 
 
 
<br />
 
 
 
= Feature Requests, Resource Requests and Emerging Conventions =
 
 
 
We are collecting '''[[Slicer3:FeatureRequests|feature, conventions and resource requests]]''' from users and developers. Appropriate entries from [http://www.na-mic.org/Bug Slicer2's bug tracker] will be periodically added to this repository also.
 
 
 
<br />
 
 
 
= Working questions =
 
 
 
* Getting correct render window size information from vtkKWRenderWidget (answer: yes, vtkKWRenderWidget::GetWidth() is actually its superclass' vtkKWFrame::GetWidth(), which is misleading, it's more a "requested width" kind of option. What you did by calling Tk is OK).
 
* First pack/unpack of Nav/Zoom widget interacting with scrollbar, making display flash (answer: fixed, update KWWidgets, in vtkSlicerViewControlGUI::PackZoom/NavWidget replace "-fill x -fill y" by "-fill none" if it is still flashing)
 
* Registry and window size (answer: investigating)
 
* Progress feedback (answer: vtkKWWindowBase::GetProgressGauge()::SetValue())
 
* Using registry (what application and module state is reasonable to save?) (answer: I would recommend: the last selected module, the collapsed state of "Manipulate Slice Views", "Manipulate 3D View", the layout (i.e. 1 over 3, or 2x2,etc), if the slice controls are collapsed or not).
 
* In the toolbar, the indicator should be off, and we could use a different image for the selected and unselected state of a button. Sadly, doing so still seems to make the button recess/shift when it is selected (answer: investigated this one thoroughly, there is sadly no work around that, it's a Tk problem unfortunately).
 
 
 
[[Slicer3:Interface_Design | Return to Slicer3 Interface Design and Usability ]]
 
 
 
[[Slicer3 | Return to Slicer3 main page ]]
 

Latest revision as of 18:07, 10 July 2017

Home < Slicer3:Interface Design and Usability

Note: We are migrating this content to the slicer.org domain - The newer page is here