SCI Home Software Documentation Installation User's Guide Developer's Guide

CIBC:Seg3D Develop GUI

From SCIRun Documentation Wiki
Jump to: navigation, search

Seg3D GUI Development

The development of the user interface for Seg3D has undergone significant changes from the early versions to the current version.

Skinner

Initially the user interface was entirely wriiten in Skinner, which is built on top of OpenGL. That employs an xml scene description to extend the SCIRun scene graph.

The advantages of using an entirely OpenGL based GUI are:

1) The creation of a platform independent layout.

2) Flexible implementation.

3) The creation of a 3D user interface.

4) Objects created by the user interface such as text, glyphs etc to be displayed within the 3D viewing window.

However, the development of user interface using Skinner was time consuming, complex and required significant amount of time to debug and test.

The disadvantages of using Skinner are:

1) The xml (*.skin) files are verbose and a lot of the variables are defined within the xml files.

1.1) No error checking on data passed as strings from the xml files. The result of this is that misspelt variable go undetected, but cause run time bugs, which are difficult to track down.

1.2) Misspelt signal targets go undetected.

1.3) There is no compile time error checking. The result of this is that changes to the GUI have to be accurately incorporated into the xml files.

2) The event programming is not straightforward, because:

2.1) The events jump around the code, very little locality.

2.2) Event ordering problems.

3) Lack of documentation.

As a result of these issues we decided to replace Skinner with a different user interface API. However, we couldn't completely replace Skinner, because this would mean shelving development of functionality within Seg3D for a couple of months. This wasn't an option and we decided to replace certain sections of the user interface with wxWidgets while continuing to develope the functionality within Seg3D.

wxWidgets

Because of the issues that we encountered with Skinner. We decided to use wxWidgets for the user interface development.

The advantages of using wxWidgets for user interface development are:

1) Mature software that is known to work on several platforms.

2) Comes with GUI builder software, which contain a large number of widgets.

3) Automatically generates C++ files, which can be easily modified.

4) Creating a GUI prototype is relatively straightforward and quick.

Disadvantages of using wxWidgets are:

1) Very difficult for more than one developer to work on the GUI simultaneously. This can lead to differences in the code bases and is time consuming to fix.

2) The GUI is described by xml via a seg3d.xrc file, which must be be updated when changes have been made to the GUI. This is done by exporting the xrc file in the GUI builder, which then needs to be committed into the code repository.

3) To ensure that the GUI looks ok on the different platforms supported requires explicitly setting the GUI parameters and extensive testing.

wxWidget/Skinner Hybrid

To ensure that development of Seg3D wasn't halted for a couple of months it was decided to replace Skinner with wxWidgets gradually. Replacing components of the Skinner UI with wxWidgets. However, this wasn't a straightforwaward process and involved significant modification to the existing code to ensure that wxWidgets worked.

How to add a new GUI tool

prerequisites

1) C++ compiler

2) wxWidgets (http://www.wxwidgets.org/)

3) DialogBlocks by Anthemion (commercial version)

Building a simple tool GUI

1) Open the Seg3D DialogBlocks project file (x/src/StandAlone/Apps/Seg3D/GuiCode/Seg3d.pjd). (see image 1)


DialogBolcks copy.png

Image 1


2) In DialogBlocks select the Windows folder and go to the menu bar and select Element > Add Top-level Panel. Then give the new document a name, for example, test. Set the Font 10, wxSWISS, wxNORMAL, wxNORMAL, false, Arial , Width 200 and height -1 (see image 2).


Top level GUI copy.png

Image 2

3) With the mouse right click on the wxBoxSizerV icon and select replace element. A window will appear go to Sizers and select the element wxGridSizer. Right mouse click on the wxGridSizerProxy and select Add Element go to Sizers and select wxGridSizer. Then change the Columns and Rows values to 1 in the space provided (see image 3)


Gridsizer copy.png

Image 3


4) Adding widgets to the wx GUI panel. To add a text label to the panel select the desired wxGridSizerProxy and then click on the Static tab then select the Aa icon this creates a text label. (see image 4).


Textgui copy.png

Image 4

5) Add a spinner box next to the text label is accomplished in a similar manner as adding the text label. However instead of clicking on the Status tab click on the Range tab and select the spinner icon. Set the member variable name and the initial value in the spaces provided. (see image 5)


Spinnergui copy.png

Image 5


6) Adding buttons to a new pane is accomplished by repeating (3) and in a similar manner to (4) & (5) click on the Buttons tab then select the simple button icon this creates a button. Change the id name to something sensible, for example, START_BUTTON and change the label to start in the spaces provided. Repeat this step for the number of buttons you require in that panel (see image 6).


Start close button copy.png

Image 6

7) An alternative method would involve copying an existing tool GUI and modify the settings in DialogBlocks.

7.1) First select a tools GUI that is similar to the one you want to create. Using the mouse right click and select copy then press the the right muse button again and select either paste before document or paste after document

7.2) In the main window panel change the title and id name in the space provided to whatever you would like your new GUI tool to be called. (see image 7)

Copy GUI01 copy.png


Image 7


7.3) To rename the document use the right mouse button and select rename document. This will change the wxPanel name to the name you've choosen for the new tool GUI. Next change the class name to the name you've called the new tool GUI as shown in image 8.


Copy GUI02 copy.png


Image 8


7.4) Modifying the text labels and input widgets is relatively straightforward. For the text label it involves changing the label value in the space provided. To change an input widget type right mouse press on the widget in the tree view and select replace element then change the default value and member variable name. To add a new text input variable, select the wxGridSizerProxy icon above where you would like to insert the new input GUI widgets in the tree view. Right mouse press on the wxGridSizerProxy icon and select copy then paste below this document. This will create a new GUI widget, which you can modify to the desired layout as described above.

Connecting the GUI to the processing code


1) First, add GuiCode/test.cpp to x/src/StandAlone/Apps/Seg3D/CMakeLists.txt then save and reconfigure with cmake. This adds test.cpp to the make file or visual studio project.


2)In the header file test.h add the following lines

text in italics should be added by the developer the rest of the code is autogenerated.

void OnStartButtonClick( wxCommandEvent& event );

void OnCloseButtonClick( wxCommandEvent& event );

These are functions that are executed when the start and close button are activated.

3) In the source file test.cpp add the following lines.


#include <StandAlone/Apps/Seg3D/Painter.h>

#include "seg3devents.h"

#include <StandAlone/Apps/Seg3D/Seg3DwxGuiUtils.h>


BEGIN_EVENT_TABLE( test, wxPanel )

////@begin test event table entries ////@end test event table entries


// add button functions to the event table

 EVT_BUTTON( XRCID("START_BUTTON"), test::OnStartButtonClick )
 EVT_BUTTON( XRCID("CLOSE_BUTTON"), test::OnCloseButtonClick )


END_EVENT_TABLE()


void test::OnStartButtonClick( wxCommandEvent& event ) {

 SCIRun::ThrowSkinnerSignalEvent *tsse = new SCIRun::ThrowSkinnerSignalEvent("Painter::FinishTool");
 tsse->add_var("test::mSpinner",SCIRun::to_string(mSpinner->GetValue()));

}

void test::OnCloseButtonClick( wxCommandEvent& event ) {

 SCIRun::Painter::global_seg3dframe_pointer_->HideTool();

}


4) Modifying x/src/StandAlone/Apps/Seg3D/Seg3DFrame.h by adding the following lines.

class test

MENU_TOOL_TEST

void ToolTest( wxCommandEvent& WXUNUSED(event) );

test *testtoolpanel_;


5) Modifying x/src/StandAlone/Apps/Seg3D/Seg3DFrame.cc by adding the following lines.

#include <StandAlone/Apps/Seg3D/GuiCode/test.h>

EVT_MENU(MENU_TOOL_TEST, Seg3DFrame::ToolTest)

 testtoolpanel_ = new test(toolsPanel_);
 tools_sizer->Add(testttoolpanel_, 0, 0, 0);
 tools_sizer->Show(testtoolpanel_, false);
 tools_sizer->Layout();

winMenu->Append(MENU_TOOL_TEST, _T("Test Tool"));

void Seg3DFrame::ToolTest( wxCommandEvent& WXUNUSED(event) )

{

ShowTool(testttoolpanel_, "", "Test Tool");

SCIRun::Painter::ThrowSkinnerSignal("Painter::StartTestTool");

}


6) Modifying x/src/StandAlone/Apps/Seg3D/Painter.h by adding the following lines.

CatcherFunction_t StartTestTool;


7) Modifying x/src/StandAlone/Apps/Seg3D/PainterSignalTargets.cc by adding the following lines.

TestTool.h & TestTool.cc control event processing which need to implemented by the developer

#include <StandAlone/Apps/Seg3D/TestTool.h>

REGISTER_CATCHER_TARGET(Painter::StartTestTool);

BaseTool::propagation_state_e Painter::StartMeasurementTool(event_handle_t &event) {

 tm_.set_tool(new TestTool(this), 25);
 return CONTINUE_E;

}


8) The implementation source files TestTool.h and TestTool.cc to accomplish this check out the implementation code from a similar function and use that as a template.


9) Modify x/src/StandAlone/Apps/Seg3D/data/main.skin by adding the following line.

<var name="TestTool::mSpinner" type="int" propagate="yes">5</var>

Personal tools
Namespaces
Variants
Actions
Navigation
Toolbox