]> Creatis software - creaContours.git/blobdiff - lib/doxygen/bouml/buttons/new_button.html
*** empty log message ***
[creaContours.git] / lib / doxygen / bouml / buttons / new_button.html
index 10d857dd966d26efa4f2499e02456b2ad1640967..7eb3fc7d635a41fee30f0c23dbbd9c0b350fd9aa 100644 (file)
@@ -55,11 +55,11 @@ font-size: x-large;
 font-weight: bold;
 text-align: center;
 }
-</style>
-</head><body>
-<h2 style="text-align: left;" class="style4">Adding
-a new button to creaContours</h2>
-<span class="text">After taking a quick look at <a class="el" href="http://www.creatis.insa-lyon.fr/site/fr/CreatoolsCreaContours">creaContours'</a>
+</style></head>
+<body>
+<h2 style="text-align: left; font-family: Helvetica,Arial,sans-serif;" class="style4"><big>Adding
+a new button to creaContours</big></h2>
+<span style="font-family: Helvetica,Arial,sans-serif;" class="text"><big>After taking a quick look at <a class="el" href="http://www.creatis.insa-lyon.fr/site/fr/CreatoolsCreaContours">creaContours'</a>
 interface,
 it's easy to agree that buttons are a very important part of it!
 Adding, editing and deleting contours; extracting statistical data;
@@ -69,6 +69,173 @@ segmentation. All this is accomplished by pressing on the right button.
 For that purpose, a detailed how-to guide is included in this
 documentation alongside a sequence diagram that serves as an example of
 the process that takes place
-once a button is pressed.<br></span><hr style="width: 100%; height: 2px;"><br><span class="text">
+once a button is pressed.</big> <big>It
+also details the process of displaying a panel, often used alongside
+buttons to configure the different segmentation tools offered by
+creaContours. Finally, a short tutorial on adding a new contour-drawing
+button is included.<br><a name="beginning"></a><br></big></span><ol><li style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold;"><a href="#1._Finding_where_to_start">Finding where to star</a>t. </span>How to figure out where to start writing the code that will let you add a new button to creaContours.</li><li style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold;"><a href="#2._Adding_the_button_">Adding the button</a>. </span>As soon as we've found the right place to start, we have to add the actual button. Here such process is detailed.</li><li style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold;"><a href="#3._The_callback_function_">The callback function</a>. </span>It's
+not enough to add a new button; a functionality must be associated to
+it. Here we describe how to create the callback function, which does
+just that.</li><li style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold;"><a href="#4._The_callback_action_">The callback action</a>. </span>Once
+the callback function is called, something must happen. To explain how
+to assign a callback action to a button (and its respective function)
+is the objective of this section.</li><li style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold;"><a href="#5._Button-click_pipeline_sequence_">Button-click pipeline</a>. </span>The sequence diagram which shows the pipeline the program goes through when a button is clicked.</li><li><span style="font-weight: bold; font-family: Helvetica,Arial,sans-serif;"><a href="#6._Adding_a_panel_">Adding a panel</a>. </span><span style="font-family: Helvetica,Arial,sans-serif;">What
+if the functionality associated to a button requires the user to
+configure a few parameters? In that case, it could be useful to have a
+panel. Here we show how to create and display one.</span></li></ol><hr style="width: 100%; height: 2px; font-family: Helvetica,Arial,sans-serif;"><h3 style="font-family: Helvetica,Arial,sans-serif;"><big><a name="1._Finding_where_to_start"></a>1. Finding where to start</big></h3><span style="font-family: Helvetica,Arial,sans-serif;">Taking
+a cursory look at creaContours' buttons panel, one can easily see that
+its buttons are divided into categories: "New Contour" buttons, "I/O"
+buttons, etc. This division of the interface is not arbitrary and
+suggests that before creating a new button one has to decide into which
+category it'll fit! Will it let the user perform a new kind of
+segmentation? If yes, it must be added to the "Segmentation"
+categories. Or will it permit the serial lecture of many contour .roi
+files? Should it be that way, "I/O" is the place to go.</span><br style="font-family: Helvetica,Arial,sans-serif;"><br style="font-family: Helvetica,Arial,sans-serif;"><div style="text-align: center; font-family: Helvetica,Arial,sans-serif;"><img style="height: 771px; width: 305px;" alt="Image which shows creaContours' button panel, in which one can find all of the buttons that form the core of the application's functionality" title="creaContours' button interface" src="buttons.png"><br><h5>Figure [1]. Button panel (creaContours).</h5></div><span style="font-family: Helvetica,Arial,sans-serif;">As
+soon as the correct placement of the button has been decided, the next
+step is to write the necessary code so that it is correctly added to
+the interface. Remembering that creaContours'
+&lt;link&gt;architecture&lt;link&gt; is divided into three main
+components, this would mean first identifying in which one of these the
+modifcations have to be made. </span><br style="font-family: Helvetica,Arial,sans-serif;"><br style="font-family: Helvetica,Arial,sans-serif;"><span style="font-weight: bold; font-family: Helvetica,Arial,sans-serif;">kernel_ManagerContour_NDimensions_lib</span><span style="font-family: Helvetica,Arial,sans-serif;">
+is constituted by the building blocks of
+&lt;link&gt;creaContours&lt;link&gt;. This is the where the most basic
+classes of the application are and as such it's not the right place to
+look. </span><span style="font-weight: bold; font-family: Helvetica,Arial,sans-serif;">Interface_ManagerContour_NDimensions_lib</span><span style="font-family: Helvetica,Arial,sans-serif;">
+contains many visual elements and sembles to be a good choice to look
+in. But in reality, this library deals with the creation and edition of
+contours and the management of "main" interface. It is therefore a high
+level representation of the interface. This leaves only one option...</span><br style="font-family: Helvetica,Arial,sans-serif;"><br style="font-family: Helvetica,Arial,sans-serif;"><div style="text-align: center; font-family: Helvetica,Arial,sans-serif;"><img style="width: 253px; height: 244px;" alt="Image which graphically displays the classes that are within the Interface_Icons_NDimensions_lib library" title="Classes of Interface_Icons_NDimensions_lib" src="classes.png"><br><h5>Figure [2]. Interface_Icon_NDimensions_lib, where new buttons are added</h5></div><span style="font-family: Helvetica,Arial,sans-serif;">This
+is clearly the right place! Each of the button panel's categories is
+represented by a class, named accordingly: "interfIOMenu" is where the
+buttons corresponding to the "I/O" category are. Having finally found
+where to start, we must now choose which kind of button we want to
+create so that we modify the appropriate class. Since the process is
+similar for each category, we will choose an arbitrary one to
+illustrate the process; "I/O" in this case.</span><br><div style="text-align: right;"><a href="#beginning"><span style="font-family: Helvetica,Arial,sans-serif;">Back to top</span></a></div><hr style="width: 100%; height: 2px; font-family: Helvetica,Arial,sans-serif;"><h3 style="font-family: Helvetica,Arial,sans-serif;"><a name="2._Adding_the_button_"></a><big><a name="2._Adding_the_button"></a>2. Adding the button</big></h3><span style="font-family: Helvetica,Arial,sans-serif;">Now
+that we have choosen which kind of button to add, we can take a good
+look to the corresponding class. As we just said, we're going to add a
+new "I/O" button. It is therefore in interfIOMenu where we have to look.</span><br style="font-family: Helvetica,Arial,sans-serif;"><br style="font-family: Helvetica,Arial,sans-serif;"><div style="text-align: center; font-family: Helvetica,Arial,sans-serif;"><img style="width: 947px; height: 426px;" alt="This image shows the code contained within the hader file of the interfIOMenu class" title="Header file of interfIOMenu" src="header_interfIOMenu.png"><br><h5>Figure [3]. Header file of interfIOMenu</h5></div><span style="font-family: Helvetica,Arial,sans-serif;">Taking
+a quick look a it we can identify the usual constructor/destructor pair
+and a virtual "initButtons" method. Each class that represents a button
+category must have implimented this virtual method, where all of the
+buttons that belong to it have to be created and added. Other than
+that, there is a method for each of the functions performed by each of
+the category's button. In this case, "I/O" contains the Load, Save and
+Import buttons and therefore there is a "On" method for each function.
+These functions receive as parameters wxCommandEvent events. This basic
+structure is replicated in each category class (interfSegmentationMenu,
+interfToolsMenu, etc).</span><br style="font-family: Helvetica,Arial,sans-serif;"><br style="font-family: Helvetica,Arial,sans-serif;"><span style="font-family: Helvetica,Arial,sans-serif;">Hence, in order to add the new button we must go to the initButtons method in the .cxx.</span><br style="font-family: Helvetica,Arial,sans-serif;"><br style="font-family: Helvetica,Arial,sans-serif;"><div style="text-align: center; font-family: Helvetica,Arial,sans-serif;"><div style="text-align: center;"><img style="width: 735px; height: 315px;" alt="Code where a new button is added to the category. The image also shows what's to be written when adding a new button." title="Code where a new button is added" src="code_add_button.png"><br><h5>Figure [4]. &nbsp;Where to add the new button.</h5><div style="text-align: left;">As
+we can see, adding a new button it's just a matter or replicating the
+code that's been already written for the previous buttons. In this
+case, we have added a new test button, underneath the big "New Button"
+heading. In orther for this to work as expected, it's necessary to add
+the button's image (in this case, test.png <img style="width: 27px; height: 27px;" alt="Image which is shown over the test button once it is sucessfully added to the interface" title="Test button image" src="test.png">)
+to the data/Icons folder of the creaContours' CMake project. It's also
+worth nothing that once a button is being added, its callback function
+it's specified. In this case, it's the function OnTest, as shown in
+Figure [4], which must also be added to the header file. If we go back
+to it in Figure [3] we'll notice that it's already there.<br><br>If we
+run the application now, we'll see that the button's been successfully
+added to the interface. Finally, the callback function has to be
+written!<br><div style="text-align: right;"><div style="text-align: right;"><a href="new_button.html#beginning"><span style="font-family: Helvetica,Arial,sans-serif;">Back to top</span></a></div></div><h3><a name="3._The_callback_function_"></a><big><a name="3._The_callback_function"></a>3. The callback function</big></h3>We now have a new button in our interface.<br><div style="text-align: center;"><img style="width: 200px; height: 70px;" alt="In this image we can see the original I/O buttons alongside the new test button" title="The new button's been added" src="new_button_added.png"><br><h5>Figure [5]. The I/O buttons alongside the new test button.</h5></div>It's
+time to create a new callback function to associate a function to it.
+For that purpose, we take a look at the existing callback functions.<br><br><div style="text-align: center;"><img style="width: 406px; height: 244px;" alt="Image which shows the code of the existing callback functions as well as that of the new callback function. The latter is marked in red." title="Existing callback functions" src="callback_functions.png"><br><h5>Figure [6]. The callback functions for each of the buttons.</h5><div style="text-align: left;">As
+we can see, all that this function does is call the corresponding
+callback function on the interfMainPanel class. This mean that there
+we'll have to define at least one more callback function! The first
+step is to find the interfMainPanel class header file
+(interfMainPanel.h) and include a new function, "OnTest". <br><br><div style="text-align: center;"><img style="width: 317px; height: 174px;" alt="An image which shows how in the interfMainPanel class the callback functions are defined" title="The interfMainPanel callback functions" src="interfMainPanel.png"><br></div></div><h5><span style="font-weight: bold;">Figure [7]. The callback functions in interfMainPanel.</span></h5><div style="text-align: left;">By
+principle, interfMainPanel is not a class where the "business logic" is
+to be defined. It can be thought of as the agglomeration of the
+different menu categories. We can thus expect the onLoad, onSave,
+onImport and onTest functions to simply call another function on a
+class where it's pertinent to perform the callback action. Taking a
+look at the interfMainPanel.cxx file, we find out that this is
+effectively the case.<br><br><div style="text-align: center;"><img style="width: 433px; height: 394px;" alt="An image that shows the piece of code where the interfMainPanel's callback function are defined (for the I/O menu category)" title="The callback functions in interfMainPanel" src="interfMainPanel_callback.png"><br><h5><span style="font-weight: bold;">Figure [8]. &nbsp;The callback functions in the interfMainPanel class.</span></h5></div></div><div style="text-align: left;">Once
+again, we see that we have to go deeper into
+&lt;link&gt;creaContours'&lt;link&gt; architecture. Each callback
+function calls another function in another class, this time the
+wxContourMainFrame class. But we're finally getting closer!<br><div style="text-align: right;"><div style="text-align: right;"><a href="new_button.html#beginning"><span style="font-family: Helvetica,Arial,sans-serif;">Back to top</span></a></div></div><h3><a name="4._The_callback_action_"></a><big><a name="4._The_callback_action"></a>4. The callback action</big></h3>Since
+we must define a new callback function within wxContourMainFrame, it
+goes without saying that it's declaration must be included in this
+class' header file. Having done that, it's time to define the actual
+callback function. Now, as wxContourMainFrame is where all callback
+functions eventually end up, this is where the callback action has to
+be defined. A callback action can be many things: opening a new window,
+showing a new panel to configure the parameters of a segmentation (and
+then execute it by pressing on the appropiate button) or drawing a new
+contour. For this part of the example, we'll be satisfied by just
+showing a File Selector window.<br><br><div style="text-align: center;"><img style="width: 758px; height: 267px;" alt="The code that shows the callback action code that's necessary so that a File Selector pops up when clicking on the button" title="The callback action code" src="callback_action.png"><br><h5>Figure [9]. &nbsp;The callback action, opening a file selector window.</h5></div>&nbsp;And
+that's it! Now, we have to run creaContours and click on the newly
+created button... and the File Selector window will pop up!<br><div style="text-align: center;"><a href="file_selector_popsup.png"><img style="border: 0px solid ; width: 757px; height: 573px;" alt="Image which shows the file selector window being shown once one clicks on the newly created button" title="The file selector window pops up" src="file_selector_popsup.png"></a><br><h5><span style="font-weight: bold;">Figure [10]. The file selector window pops up!</span></h5><div style="text-align: right;"><div style="text-align: right;"><a href="new_button.html#beginning"><span style="font-family: Helvetica,Arial,sans-serif;">Back to top</span></a></div></div><div style="text-align: justify;"><h3><a name="5._Button-click_pipeline_sequence_"></a><big><a name="5._Button-click_pipeline_sequence"></a>5.</big> <big>Button-click pipeline (sequence diagram)</big></h3><div style="text-align: right;"><div style="text-align: right;"><a href="new_button.html#beginning"><span style="font-family: Helvetica,Arial,sans-serif;">Back to top</span></a></div></div><h3><a name="6._Adding_a_panel_"></a><big><a name="6._Adding_a_panel"></a>6. Adding a panel</big></h3>It
+must be said that a button that shows a file selector window is not
+really the most interesting thing that can be done. By playing around
+for a bit with creaContours' other buttons, we'll quickly notice that
+many of them add small panels to the space underneath all the buttons.
+These panels let the user configure the parameters of the function
+associated to the button's he's pressed. These panels are particularly
+important&nbsp;when doing segmentations. As one of creaContours' main
+functions is to let the user segment the images he's working with,
+knowing how to create a panel and use it afterwards it's very
+important. This part of the guide deals precisely with this process.<br><br>We'll
+start with the button that we just created, which causes a file
+selector window to pop up. In order to add a panel to the window, we
+follow the same process until the onTest method in interfMainPanel.
+This is where the process starts to diverge as it is precisely in this
+method where we'll create the panel and add it to the window. <br><br>However, before doing that, we have created the panel that we're going to add!<br><br>At this moment we can pose ourselves the questions: where exactly do we have to add this new panel? Let's take a look at <span style="font-weight: bold;">Interface_Icons_NDimensions_lib</span>, where all of creaContours' graphical elements are to be found:<br><div style="text-align: center;"><img style="width: 244px; height: 234px;" alt="Image which shows creaContours' graphical classes, with the panel classes being highlighted" title="The panel classes highlighted" src="panels-highlighted.png"><br><h5>Figure [11]. The panel classes highlighted</h5><div style="text-align: justify;">Clearly,
+interfSegmentationPanels.cxx and interfToolsPanels.cxx are the two
+files we have to take a look&nbsp;at! Intuitively, we know that the
+prefix associated to each class (<span style="font-weight: bold;">Segmentation</span>Panels and <span style="font-weight: bold;">Tools</span>Panels)
+represents to which button category the panels belong to it. The former
+are the panels that are displayed once we press on a segmentation
+button; the latter are the panels that are displayed once we press on a
+Tools button. For the purpose of this guide, we will assume that our
+button is going to be a Segmentation Button and therefore the panel
+associated to it will be added to interfSegmentationPanels.<br><br>As a
+matter of fact, these two files have within them the definition of each
+panel that makes part of each particular category. For example, if we
+go to interfSegmentationPanels.cxx and examine which class definitions
+are contained within it, we'll see that there's three, one for each
+panel.<br><br><div style="text-align: center;"><img style="width: 679px; height: 125px;" alt="Image which shows that within the interfSegmentationPanels.cxx file there's 3 class definiotns" title="All the panels" src="all_panels.png"><br><h5>Figure [12]. The three classes inside the interfSegmentationPanel class</h5></div></div><div style="text-align: justify;">If
+we know look at the interfSegmentationPanels.h file, we'll see that in
+it there's a brief definition of each of the three aforementioned
+classes. This is where we must start, then. To get an idea of how to
+proceed, let's look at the class definition for interfMirrorPanel:<br><div style="text-align: center;"><img style="width: 403px; height: 503px;" alt="Fragment of code whiwh shows the definition of the interfMirrorPanel class" title="InterfMirrorPanel" src="interfMirrorPanel.png"><br><h5>Figure [13]. The definition of the interfMirrorPanel class.</h5><div style="text-align: justify;">As
+we can see, the class in itself it's not very complicated, but this is
+also because the panel that it represents is fairly basic. Let's take a
+quick look at it:<br><div style="text-align: center;"><img style="width: 206px; height: 163px;" alt="Image which shows the mirroring segmentation panel, in order to give the reader a rough idea of its graphical distribution" title="The mirroring panel" src="mirroring_panel.png"><br><h5>Figure [14]. The graphical distribution of the mirroring panel.</h5><div style="text-align: justify;">What
+we're going to try to achieve in this guide is actually a very similar
+panel; it'll have just two buttons, each one of which will have an
+associated functionality. We must begin by writing down the class
+definition of our new panel, that we'll name interfTestPanel. Following
+the pattern shown above, we'll have:<br><br><div style="text-align: center;"><img style="width: 434px; height: 306px;" alt="Fragment of code showing the declaration of the new panel" title="interfTestPanel" src="interfTestPanel.png"><br><h5><span style="font-weight: bold;">Figure [15]. The declaration of the interfTestPanel class.</span></h5></div></div></div>As
+we can see, we have two methods, onButton1Pressed and onButton2Pressed,
+which receive two wxCommandEvent&amp; events. These are the callback
+methods that are called once we click on a button. <br><br>Now that we have our class definition, we proceed to declare each method of our class.<br><br><div style="text-align: center;"><img style="width: 1033px; height: 623px;" alt="The full declaration of the interfTestPanel class" title="interfTestPanel" src="interfTestPanel_final.png"><br><h5>Figure [16]. The declaration of the new interfTestPanel class</h5></div>The
+button callback methods, as we can see, do nothing in particular; they
+just print into std::cout a message informing the use that the
+respective button's been pressed. Inside the constructor, we create
+both buttons as new <span style="font-weight: bold;">wxButtons. </span>These
+take as parameters the panel into which they're going to be added, an
+ID, a label, and a position. Explaining in detail these parameters (as
+well as those used in the call to the <span style="font-weight: bold;">wxPanel</span> constructor) goes beyond the scope of this guide. <br><br>We associated an event to each button with the Connect method. In this case it's a <span style="font-weight: bold;">wxEVT_COMMAND_BUTTON_CLICKED </span>event.
+Furthermore, each button has an associated callback function, which
+must also be specified through the Connect method. The <span style="font-weight: bold;">wxFlexGridSizer </span>which is added immediately afterwards serves as a way to organize the elements on the interface.<br><br>Having
+done that, we must now make sure that once we click on our button the
+panel is added to the interface. In order to make sure of this, we have
+to remember the "pipeline" that is followed when we click on a button.
+This time around, we will folllow it all the way to the "onTest" method
+in <span style="font-weight: bold;">interfMainPanel</span>, as it's
+here that we have the necessary tools to display our new panel. Before
+getting down to it, we have to add to new parameters to the <span style="font-weight: bold;">interfMainPanel.h</span> file:<br><div style="text-align: center;"><img style="width: 329px; height: 188px;" alt="Fragment of code which shows the new parameters added to an existing class so that the new panels can be created" title="The new panel" src="interfMainPanel_newPanel.png"><br><h5>Figure [17]. The declaration of the new panel parameters.</h5><div style="text-align: justify;">The first parameter is a regular <span style="font-weight: bold;">wxPanel </span>which will contain within it the actual <span style="font-weight: bold;">interfTestPanel, </span>which is the second parameter that's been added. As soon as we have them in our header file, we can go to the <span style="font-weight: bold;">OnTest </span>method and modify it so the panel is shown in the right place. Basing ourselves on the existing <span style="font-weight: bold;">onMirrorPressed </span>method, we get the following code which does exactly what we want it to:<br><br><div style="text-align: center;"><img style="width: 836px; height: 421px;" alt="Fragment of code which shows where the panel is actually shown" title="Showing the new panel" src="interfMainPanel_onShowPanel.png"><br><h5>Figure [18]. The fragment of code that serves to show the new panel</h5><div style="text-align: justify;">What is done here is actually quite simple. The new <span style="font-weight: bold;">testPanel</span> (of object type <span style="font-weight: bold;">wxPanel</span>)
+contains within it the panel where the actual test panel is going to be
+added. In other words, this is where we will store an instance of the
+space underneath &nbsp;the buttons, represented as a panel. Having
+created it, we further configure it before creating an instance of the
+actual <span style="font-weight: bold;">interfMirrorPanel. </span>&nbsp;This is added to the <span style="font-weight: bold;">wxFlexGridSizer </span>which in turn has been set as the <span style="font-weight: bold;">testPanel</span>'<span style="font-weight: bold;">s </span>Sizer. It is why by doing so we're adding the <span style="font-weight: bold;">interfMirrorPanel </span>to
+the space beneath the buttons, which is exactly what we wanted to do!
+We end by adding a little bit of text (just for the purpose of staying
+close to the other, already existing buttons) and we end by showing our
+panel by invoking the <span style="font-weight: bold;">showPanel </span>method&nbsp;and passing it an instance of <span style="font-weight: bold;">testPanel, </span>which now contains within it the <span style="font-weight: bold;">interfMirrorPanel.</span><br><br>If we now run the interface and click on the new button, we'll obtain the following result...<br><div style="text-align: center;"><a href="newPanel_newButtons.png"><img style="border: 0px solid ; width: 724px; height: 632px;" alt="Image which shows the new panel and the buttons it contains, as well as the result that's printed out when you click on one of the buttons" title="new panel with new buttons" src="newPanel_newButtons.png"></a><br><h5>Figure [19]. The resulting panel</h5></div></div><div style="text-align: justify;">Mission accomplished!<br><div style="text-align: right;"><div style="text-align: right;"><a href="new_button.html#beginning"><span style="font-family: Helvetica,Arial,sans-serif;">Back to top</span></a></div></div></div></div></div><div style="text-align: justify;"></div></div></div></div></div></div> </div></div></div></div></div></div></div><span style="font-family: Helvetica,Arial,sans-serif;" class="text">
 </span>
 </body></html>
\ No newline at end of file