00001 #include "HMMModuleGUI.h"
00002 #include <iostream>
00003 #include "../util/utils.h"
00004 #include "../util/ConfigManager.h"
00005 #include <gtkmm/messagedialog.h>
00006 #include <gtkmm/filefilter.h>
00007 #include <gtkmm/stock.h>
00008 #include <gtkmm/treemodelsort.h>
00009 #include "ModuleWindow.h"
00010
00011
00012
00013 HMMModuleGUI::GestureTreeView::GestureTreeView()
00014 {
00015 m_refGestureTreeModel = Gtk::ListStore::create(m_gestureDataModel);
00016
00017 Glib::RefPtr<Gtk::TreeModelSort> sortModel =
00018 Gtk::TreeModelSort::create(m_refGestureTreeModel);
00019 set_model(sortModel);
00020 m_refGestureTreeModel->set_sort_column(m_gestureDataModel.m_id, Gtk::SORT_ASCENDING);
00021
00022 append_column("#", m_gestureDataModel.m_id);
00023 append_column("Name", m_gestureDataModel.m_name);
00024 append_column("Clusters", m_gestureDataModel.m_clusters);
00025 append_column("States", m_gestureDataModel.m_states);
00026 }
00027
00028 bool HMMModuleGUI::GestureTreeView::hasItemSelected()
00029 {
00030 return static_cast<bool>(get_selection()->get_selected());
00031 }
00032
00033 int HMMModuleGUI::GestureTreeView::getSelectedGestureID()
00034 {
00035 Gtk::TreeModel::iterator it = get_selection()->get_selected();
00036 if (!it) {
00037 return -1;
00038 }
00039 return (*it)[m_gestureDataModel.m_id];
00040 }
00041
00042 void HMMModuleGUI::GestureTreeView::delSelectedGesture()
00043 {
00044 int id = getSelectedGestureID();
00045 if (id == -1) {
00046 return;
00047 }
00048
00049
00050 typedef Gtk::TreeModel::Children tChildren;
00051 tChildren children = m_refGestureTreeModel->children();
00052 int newId;
00053 for (tChildren::iterator it = children.begin(); it != children.end(); ++it) {
00054 newId = (*it)[m_gestureDataModel.m_id];
00055 if (newId == id) {
00056 m_refGestureTreeModel->erase(it);
00057 } else if (newId > id) {
00058 (*it)[m_gestureDataModel.m_id] = newId - 1;
00059 }
00060 }
00061 }
00062
00063 void HMMModuleGUI::GestureTreeView::clearList()
00064 {
00065
00066 typedef Gtk::TreeModel::Children tChildren;
00067 tChildren children = m_refGestureTreeModel->children();
00068 for (tChildren::iterator it = children.begin(); it != children.end(); ++it) {
00069 m_refGestureTreeModel->erase(it);
00070 }
00071 }
00072
00073 void HMMModuleGUI::GestureTreeView::addRow(int id, Glib::ustring name, int clusters, int states)
00074 {
00075 Gtk::TreeModel::Row row = *(m_refGestureTreeModel->append());
00076 row[m_gestureDataModel.m_id] = id;
00077 row[m_gestureDataModel.m_name] = name;
00078 row[m_gestureDataModel.m_clusters] = clusters;
00079 row[m_gestureDataModel.m_states] = states;
00080 }
00081
00082 void HMMModuleGUI::GestureTreeView::addRow(Glib::ustring name, int clusters, int states)
00083 {
00084 addRow(m_refGestureTreeModel->children().size(), name, clusters, states);
00085 }
00086
00087 HMMModuleGUI::HMMModuleGUI(HMMModule *module) :
00088 AbstractGtkmmModuleGUI(module, "HMM"),
00089 m_boxOverview(false, 5),
00090 m_lblCountGestures("Current Gestures: "),
00091 m_boxGestures(false, 5),
00092 m_tblAddGesture(2,4,false),
00093 m_btnAddGesture("Add Gesture"),
00094 m_lblGestureName("Gesture Name:"),
00095 m_lblNClusters("Cluster count:"),
00096 m_lblNStates("State count:"),
00097 m_boxDelTrainButtons(false, 5),
00098 m_btnDelGesture("Delete Gesture"),
00099 m_btnClearGestures("Clear Gestures"),
00100 m_tbtnTrain("Train Gesture"),
00101 m_boxLoadSave(false, 5),
00102 m_btnLoadFile("Load file"),
00103 m_btnSaveFile("Save file"),
00104 m_dlgSave("Save Gestures to file", Gtk::FILE_CHOOSER_ACTION_SAVE),
00105 m_dlgLoad("Load Gestures from file", Gtk::FILE_CHOOSER_ACTION_OPEN)
00106 {
00107 makeOverviewTab();
00108 makeGestureTab();
00109 makeAddGestureTab();
00110 makeLoadSaveTab();
00111 makeDialogs();
00112
00113 m_notebook.append_page(m_boxOverview, "Overview");
00114 m_notebook.append_page(m_boxGestures, "Gestures");
00115 m_notebook.append_page(m_tblAddGesture, "Add Gesture");
00116 m_notebook.append_page(m_boxLoadSave, "Load/Save");
00117
00118 add(m_notebook);
00119 }
00120
00121 void HMMModuleGUI::init()
00122 {
00123 show_all();
00124 }
00125
00126 void HMMModuleGUI::destroy()
00127 {
00128 hide_all();
00129 }
00130
00131 void HMMModuleGUI::makeOverviewTab()
00132 {
00133 m_lblCountGestures.set_alignment(Gtk::ALIGN_LEFT, Gtk::ALIGN_CENTER);
00134 m_boxOverview.pack_start(m_lblCountGestures, Gtk::PACK_SHRINK);
00135 }
00136
00137 void HMMModuleGUI::makeGestureTab()
00138 {
00139 m_btnDelGesture.signal_clicked().connect(
00140 sigc::mem_fun(*this, &HMMModuleGUI::delGesture));
00141 m_btnClearGestures.signal_clicked().connect(
00142 sigc::mem_fun(*this, &HMMModuleGUI::clearGestures));
00143 m_tbtnTrain.signal_pressed().connect(
00144 sigc::mem_fun(*this, &HMMModuleGUI::toggleTraining));
00145 m_tbtnTrain.signal_released().connect(
00146 sigc::mem_fun(*this, &HMMModuleGUI::toggleTraining));
00147
00148 m_srwGestureListWindow.add(m_trwGestureListView);
00149 m_srwGestureListWindow.set_policy(Gtk::POLICY_AUTOMATIC, Gtk::POLICY_AUTOMATIC);
00150 m_srwGestureListWindow.set_size_request(-1, 120);
00151
00152 m_boxDelTrainButtons.pack_start(m_btnDelGesture, Gtk::PACK_SHRINK);
00153 m_boxDelTrainButtons.pack_start(m_btnClearGestures, Gtk::PACK_SHRINK);
00154 m_boxDelTrainButtons.pack_start(m_tbtnTrain, Gtk::PACK_SHRINK);
00155
00156 m_boxGestures.pack_start(m_srwGestureListWindow);
00157 m_boxGestures.pack_start(m_boxDelTrainButtons, Gtk::PACK_SHRINK, 0);
00158 }
00159
00160 void HMMModuleGUI::makeAddGestureTab()
00161 {
00162 m_btnAddGesture.signal_clicked().connect(
00163 sigc::mem_fun(*this, &HMMModuleGUI::addGesture));
00164
00165 m_tblAddGesture.attach(m_lblGestureName, 0, 1, 0, 1);
00166 m_tblAddGesture.attach(m_entGestureName, 1, 2, 0, 1);
00167 m_tblAddGesture.attach(m_lblNClusters, 0, 1, 1, 2);
00168 m_tblAddGesture.attach(m_entNClusters, 1, 2, 1, 2);
00169 m_tblAddGesture.attach(m_lblNStates, 0, 1, 2, 3);
00170 m_tblAddGesture.attach(m_entNStates, 1, 2, 2, 3);
00171 m_tblAddGesture.attach(m_btnAddGesture, 0, 2, 3, 4);
00172 }
00173
00174 void HMMModuleGUI::makeLoadSaveTab()
00175 {
00176 m_btnLoadFile.signal_clicked().connect(
00177 sigc::mem_fun(*this, &HMMModuleGUI::loadFromFile));
00178 m_btnSaveFile.signal_clicked().connect(
00179 sigc::mem_fun(*this, &HMMModuleGUI::saveToFile));
00180
00181 m_boxLoadSave.pack_start(m_btnLoadFile, Gtk::PACK_SHRINK);
00182 m_boxLoadSave.pack_start(m_btnSaveFile, Gtk::PACK_SHRINK);
00183 }
00184
00185 void HMMModuleGUI::makeDialogs()
00186 {
00187 Gtk::FileFilter gestureFilter;
00188 gestureFilter.set_name("Gesture Files");
00189 gestureFilter.add_pattern("*.gesture");
00190
00191 Gtk::FileFilter anyFilter;
00192 anyFilter.set_name("All Files");
00193 anyFilter.add_pattern("*");
00194
00195 m_dlgSave.set_transient_for(*MODULEWINDOW);
00196 m_dlgSave.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
00197 m_dlgSave.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK);
00198 m_dlgSave.add_filter(gestureFilter);
00199 m_dlgSave.add_filter(anyFilter);
00200
00201 m_dlgLoad.set_transient_for(*MODULEWINDOW);
00202 m_dlgLoad.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
00203 m_dlgLoad.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK);
00204 m_dlgLoad.add_filter(gestureFilter);
00205 m_dlgLoad.add_filter(anyFilter);
00206 }
00207
00208 void HMMModuleGUI::delGesture()
00209 {
00210 int id = m_trwGestureListView.getSelectedGestureID();
00211 if (id == -1) {
00212 return;
00213 }
00214 static_cast<HMMModule*>(getModule())->delGesture(id);
00215 m_trwGestureListView.delSelectedGesture();
00216 }
00217
00218 void HMMModuleGUI::clearGestures()
00219 {
00220 static_cast<HMMModule*>(getModule())->clearGestures();
00221 m_trwGestureListView.clearList();
00222 }
00223
00224 void HMMModuleGUI::toggleTraining()
00225 {
00226 if (m_tbtnTrain.get_active()) {
00227 static_cast<HMMModule*>(getModule())->trainGesture(0);
00228 m_tbtnTrain.set_active(false);
00229 return;
00230 }
00231 int id = m_trwGestureListView.getSelectedGestureID();
00232 if (id == -1) {
00233 m_tbtnTrain.set_active(false);
00234 return;
00235 }
00236 static_cast<HMMModule*>(getModule())->trainGesture(id);
00237 m_tbtnTrain.set_active(true);
00238 }
00239
00240 void HMMModuleGUI::addGesture()
00241 {
00242 int nClusters = convertTo<Glib::ustring, int>(m_entNClusters.get_text());
00243 int nStates = convertTo<Glib::ustring, int>(m_entNStates.get_text());
00244
00245 if (nClusters < 2 || nClusters > 100) {
00246 Gtk::MessageDialog errorDlg("Cluster-size makes no sense.",
00247 false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
00248 errorDlg.set_secondary_text("Try again with a number between 2 and 100");
00249 errorDlg.run();
00250 return;
00251 }
00252 if (nStates < 2 || nStates > 30) {
00253 Gtk::MessageDialog errorDlg("Number of states makes no sense.",
00254 false, Gtk::MESSAGE_WARNING, Gtk::BUTTONS_OK, true);
00255 errorDlg.set_secondary_text("Try again with a number between 2 and 30");
00256 errorDlg.run();
00257 return;
00258 }
00259
00260 static_cast<HMMModule*>(getModule())->addGesture(nClusters, nStates);
00261 m_trwGestureListView.addRow(m_entGestureName.get_text(), nClusters, nStates);
00262
00263 Gtk::MessageDialog msgDlg("Gesture added to list",
00264 false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK, true);
00265 msgDlg.run();
00266
00267 m_entGestureName.set_text("");
00268 m_entNClusters.set_text("");
00269 m_entNStates.set_text("");
00270 }
00271
00272 void HMMModuleGUI::loadFromFile()
00273 {
00274
00275 if (m_dlgLoad.run() != Gtk::RESPONSE_OK) {
00276 m_dlgLoad.hide();
00277 return;
00278 }
00279
00280
00281 ConfigManager gestureFile(m_dlgLoad.get_filename());
00282 gestureFile.load();
00283
00284 size_t maxId = m_trwGestureListView.getRefPointer()->get_n_columns() - 1;
00285
00286 for (ConfigManager::SectionMap::iterator it = gestureFile.begin(); it != gestureFile.end(); ++it) {
00287 static_cast<HMMModule*>(getModule())->deserializeGesture(it->second, it->first);
00288
00289 m_trwGestureListView.addRow(
00290 it->second.get<int>("id") + maxId,
00291 it->first,
00292 it->second.get<int>("clusters"),
00293 it->second.get<int>("states")
00294 );
00295 }
00296
00297 m_dlgLoad.hide();
00298 Gtk::MessageDialog msgDlg("Gestures loaded successfully",
00299 false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK, true);
00300 msgDlg.run();
00301 }
00302
00303 void HMMModuleGUI::saveToFile()
00304 {
00305
00306 if (m_dlgSave.run() != Gtk::RESPONSE_OK) {
00307 m_dlgSave.hide();
00308 return;
00309 }
00310
00311 Gtk::TreeModel::Children children = m_trwGestureListView.getRefPointer()->children();
00312
00313 Gtk::TreeModel::Children::iterator childrenIt;
00314 Gtk::TreeModel::Row row;
00315
00316 std::string filename = m_dlgSave.get_filename();
00317
00318 if (filename.find(".gesture") != (filename.size() - std::string(".gesture").size())) {
00319 filename += ".gesture";
00320 }
00321
00322
00323 ConfigManager gestureFile(filename);
00324 for (childrenIt = children.begin(); childrenIt != children.end(); ++childrenIt) {
00325 row = *childrenIt;
00326 Glib::ustring gestureName = row[m_trwGestureListView.getModel().m_name];
00327 static_cast<HMMModule*>(getModule())->serializeGesture(
00328 gestureFile,
00329 gestureName,
00330 row[m_trwGestureListView.getModel().m_id]
00331 );
00332 }
00333 gestureFile.save();
00334 m_dlgSave.hide();
00335
00336 Gtk::MessageDialog msgDlg("Gestures saved successfully",
00337 false, Gtk::MESSAGE_INFO, Gtk::BUTTONS_OK, true);
00338 msgDlg.run();
00339 }