egami
C++ Image Processing program
|
00001 #include <string> 00002 #include <vector> 00003 00004 #include <glibmm/refptr.h> 00005 #include <glibmm/ustring.h> 00006 #include <gtkmm/aboutdialog.h> 00007 #include <gtkmm/action.h> 00008 #include <gtkmm/actiongroup.h> 00009 #include <gtkmm/enums.h> 00010 #include <gtkmm/filechooserdialog.h> 00011 #include <gtkmm/filefilter.h> 00012 #include <gtkmm/messagedialog.h> 00013 #include <gtkmm/stock.h> 00014 #include <gtkmm/uimanager.h> 00015 00016 #include "catalogue.hpp" 00017 #include "main_window.hpp" 00018 #include "utils.hpp" 00019 00020 Main_window::Main_window(): parent_table(2, 2) { 00021 set_title("Egami"); 00022 add(parent_table); 00023 set_resizable(); 00024 init_menu(); 00025 00026 parent_table.attach(*menu, 0, 2, 0, 1, Gtk::FILL, static_cast<Gtk::AttachOptions>(0)); 00027 parent_table.attach(display_catalogue, 0, 1, 1, 2); 00028 parent_table.attach(processing_catalogue, 1, 2, 1, 2, static_cast<Gtk::AttachOptions>(0)); 00029 00030 show_all_children(); 00031 } 00032 00033 void Main_window::init_menu(){ 00034 struct Leaf{ const std::string id; const Gtk::StockID ic; const std::string txt, info; void (Main_window::*fn)(); }; 00035 00036 menu_action_group = Gtk::ActionGroup::create(); 00037 menu_action_group->add(Gtk::Action::create("FileMenu", "File")); 00038 menu_action_group->add(Gtk::Action::create("EditMenu", "Edit")); 00039 menu_action_group->add(Gtk::Action::create("HelpMenu", "Help")); 00040 00041 std::vector<Leaf> menu_leafs{ 00042 { "Open", Gtk::Stock::OPEN, "_Open", "Open a new file", &Main_window::on_open }, 00043 { "Save", Gtk::Stock::SAVE, "_Save", "Save", &Main_window::on_save }, 00044 { "Save As", Gtk::Stock::SAVE_AS, "Save As...", "Save as new file", &Main_window::on_save_as }, 00045 { "Quit", Gtk::Stock::QUIT, "_Quit", "Quit egami", &Main_window::on_quit }, 00046 { "Undo", Gtk::Stock::UNDO, "_Undo", "Undo previous action", &Main_window::on_undo }, 00047 { "Redo", Gtk::Stock::REDO, "_Redo", "Redo previous undo", &Main_window::on_redo }, 00048 { "About", Gtk::Stock::ABOUT, "_About", "About this program", &Main_window::on_about }, 00049 { "Region of Interest", Gtk::Stock::HELP, "_Region of Interest", "Help on ROI", &Main_window::on_roi }, 00050 }; 00051 00052 Glib::ustring menu_shape = 00053 "<ui>" 00054 " <menubar name='MenuBar'>" 00055 " <menu action='FileMenu'>" 00056 " <menuitem action='Open'/>" 00057 " <menuitem action='Save'/>" 00058 " <menuitem action='Save As'/>" 00059 " <menuitem action='Quit'/>" 00060 " </menu>" 00061 " <menu action='EditMenu'>" 00062 " <menuitem action='Undo'/>" 00063 " <menuitem action='Redo'/>" 00064 " </menu>" 00065 " <menu action='HelpMenu'>" 00066 " <menuitem action='About'/>" 00067 " <menuitem action='Region of Interest'/>" 00068 " </menu>" 00069 " </menubar>" 00070 "</ui>"; 00071 00072 // Generate leafs' Action. 00073 for(std::vector<Leaf>::iterator it=menu_leafs.begin(); it!=menu_leafs.end(); ++it){ 00074 Glib::RefPtr<Gtk::Action> o=Gtk::Action::create(it->id, it->ic, it->txt, it->info); 00075 o->set_always_show_image(); 00076 menu_action_group->add(o, sigc::mem_fun(*this, it->fn)); 00077 } 00078 00079 // Populate menu_ui_manager. 00080 menu_ui_manager = Gtk::UIManager::create(); 00081 menu_ui_manager->insert_action_group(menu_action_group); 00082 add_accel_group(menu_ui_manager->get_accel_group()); 00083 menu_ui_manager->add_ui_from_string(menu_shape); 00084 00085 // Extract the menu. 00086 menu = menu_ui_manager->get_widget("/MenuBar"); 00087 } 00088 00089 void Main_window::on_open(){ 00090 Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_OPEN); 00091 dialog.set_transient_for(*this); 00092 dialog.set_select_multiple(); 00093 dialog.set_current_folder(cmake_install_prefix+std::string("/share/egami/Image Library")); 00094 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); 00095 dialog.add_button(Gtk::Stock::OPEN, Gtk::RESPONSE_OK); 00096 00097 00098 Glib::RefPtr<Gtk::FileFilter> filter_images = Gtk::FileFilter::create(); 00099 filter_images->set_name("Image files"); 00100 filter_images->add_mime_type("image/jpeg"); 00101 filter_images->add_mime_type("image/png"); 00102 filter_images->add_mime_type("image/bmp"); 00103 filter_images->add_mime_type("image/tiff"); 00104 dialog.add_filter(filter_images); 00105 00106 Glib::RefPtr<Gtk::FileFilter> filter_any = Gtk::FileFilter::create(); 00107 filter_any->set_name("Any files"); 00108 filter_any->add_pattern("*"); 00109 dialog.add_filter(filter_any); 00110 00111 int result = dialog.run(); 00112 00113 std::vector<std::string> targetfilenames; 00114 switch(result){ 00115 case(Gtk::RESPONSE_OK): 00116 targetfilenames = std::move(dialog.get_filenames()); 00117 break; 00118 case(Gtk::RESPONSE_CANCEL): 00119 return; 00120 } 00121 00122 for(std::vector<std::string>::iterator it=targetfilenames.begin(); it!=targetfilenames.end(); ++it) 00123 display_catalogue.open_image(*it); 00124 } 00125 00126 void Main_window::on_save(){ 00127 try{ 00128 if(!display_catalogue.save()) 00129 on_save_as(); 00130 } catch(std::exception &e){ 00131 Gtk::MessageDialog d(*this, e.what()); 00132 d.run(); 00133 } 00134 } 00135 00136 void Main_window::on_save_as(){ 00137 Gtk::FileChooserDialog dialog("Please choose a file", Gtk::FILE_CHOOSER_ACTION_SAVE); 00138 dialog.set_transient_for(*this); 00139 dialog.set_current_folder(cmake_install_prefix+std::string("/share/egami/Image Library")); 00140 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); 00141 dialog.add_button(Gtk::Stock::SAVE, Gtk::RESPONSE_OK); 00142 00143 int result = dialog.run(); 00144 00145 switch(result){ 00146 case(Gtk::RESPONSE_OK): 00147 try{ 00148 display_catalogue.save_as(dialog.get_filename()); 00149 } catch(std::exception &e){ 00150 Gtk::MessageDialog d(*this, e.what()); 00151 d.run(); 00152 } 00153 break; 00154 case(Gtk::RESPONSE_CANCEL): 00155 return; 00156 } 00157 } 00158 00159 void Main_window::on_quit(){ 00160 hide(); 00161 } 00162 00163 void Main_window::on_undo(){ 00164 display_catalogue.undo_current(); 00165 } 00166 00167 void Main_window::on_redo(){ 00168 display_catalogue.redo_current(); 00169 } 00170 00171 void Main_window::on_about(){ 00172 Gtk::AboutDialog d; 00173 d.set_program_name("Egami"); 00174 d.set_version("Final"); 00175 d.set_comments("For the DCS339: C++ for Image Processing course"); 00176 d.set_authors(std::vector<Glib::ustring>{"Étienne Jean Lucien Simon"}); 00177 d.run(); 00178 } 00179 00180 void Main_window::on_roi(){ 00181 Gtk::Label text; 00182 text.set_markup("<big><b>Region of Interest</b></big>\n" 00183 "\n" 00184 "A region of interest is a subimage in an image. Like a normal image it must be rectangular.\n" 00185 "When an image has a currently active ROI (region of interest), all processes apply to this region only.\n" 00186 "Some processes are not avaible in ROI mode (e.g. Resizing, rotating). Moreover, copy has the special\n" 00187 "semantic of slicing the image. That is, the copy process will \"cut out\" the ROI and it will open it in\n" 00188 "another tab.\n" 00189 "\n" 00190 "In order to select a ROI: first click two times on the image (on two opposite angle of the sub image) then\n" 00191 "click on the Select ROI process button (on the \"Tools\" tab). The ROI is persistant, in order to reselect\n" 00192 "the image as a whole, you must click on the Unselect ROI process button (also on \"Tools\").\n" 00193 "\n" 00194 "Note that when a binary operation is effectued on an image in ROI mode, only the ROI portion is affected/used.\n"); 00195 Gtk::Dialog d; 00196 d.set_resizable(false); 00197 d.get_vbox()->pack_start(text); 00198 d.add_button(Gtk::Stock::OK, Gtk::RESPONSE_OK); 00199 d.show_all_children(); 00200 d.run(); 00201 }