/******************************************************************************* * PROJECT: Agave * AUTHOR: Jonathon Jongsma * Copyright (c) 2005 Jonathon Jongsma * * License: * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the * Free Software Foundation, Inc., 59 Temple Place, Suite 330, * Boston, MA 02111-1307 USA * *******************************************************************************/ #include "config.h" #include // for srand(), rand() #include // for time() #include #include #include #include #include #include #ifdef HAVE_GCONFMM #include #endif // HAVE_GCONFMM #include "gcs-mainwindow.h" #include "gcs-util.h" // for get_dropped_color #include "gcs-i18n.h" #include "gcs-history.h" #include "gcs-conf.h" #include "core/gcs-scheme.h" #include "core/log-stream.h" #include "widgets/gcs-schemebox.h" #include "widgets/gcs-schemeselector.h" #include "widgets/gcs-bookmarklist.h" #include "widgets/gcs-colorswatch.h" #include "widgets/gcs-paletteview.h" #include "dialogs/gcs-about-window.h" #define NO_SIZE_REQUEST (-1) namespace gcs { MainWindow* MainWindow::m_instance = NULL; MainWindow& MainWindow::Instance(void) { if (m_instance) { return *m_instance; } else { Glib::RefPtr glade = Glade::Xml::create(AGAVE_UIDIR "/agave.glade"); glade->get_widget_derived("AgaveWindow", m_instance); return *m_instance; } } MainWindow::MainWindow(GtkWindow *cobject, Glib::RefPtr& refGlade) : Gtk::Window(cobject), m_glade(refGlade), m_vbox_layout(NULL), m_vbox_menu_toolbar(NULL), m_vbox_main(NULL), m_vbox_favorites(NULL), m_vbox_scheme_display(NULL), m_pane(NULL), m_main_menu(NULL), m_toolbar(NULL), m_bookmark_bar(NULL), m_color_button(NULL), m_scheme_selector(NULL), m_scheme_box(Gtk::manage(new Widgets::SchemeBox())), m_bookmark_list(Gtk::manage(new Widgets::BookmarkList())), m_palette_view(NULL), m_pAbout(new Dialogs::AboutWindow()), m_pHistory(new HistoryNavigation()) { // seed the random number generator for generating random color schemes srand(time(NULL)); // migrate the old settings if it hasn't been done yet Conf::migrate_old_config_directory(); // make sure the glade file has been loaded g_assert(m_glade); init_actions(); init_ui(); // load menus, cache glade widgets /* The menu bar across the top of the window */ m_vbox_menu_toolbar->pack_start(*m_main_menu, Gtk::PACK_SHRINK); LOG("Added main menu"); m_toolbar->set_toolbar_style(Gtk::TOOLBAR_BOTH_HORIZ); m_vbox_menu_toolbar->pack_start(*m_toolbar, Gtk::PACK_SHRINK, 0); m_color_button->signal_color_set().connect(sigc::mem_fun(*this, &MainWindow::on_color_changed)); m_scheme_selector->signal_changed().connect(sigc::mem_fun(*this, &MainWindow::on_schemetype_changed)); LOG("Created Scheme Selector"); // Set up the SchemeBox g_assert(m_scheme_box); m_vbox_scheme_display->pack_start(*m_scheme_box, Gtk::PACK_EXPAND_WIDGET, 0); m_scheme_box->signal_color_selected().connect( sigc::mem_fun(*this, &MainWindow::on_schemebox_color_selected)); std::list listTargets; listTargets.push_back(Gtk::TargetEntry("application/x-color")); m_scheme_box->drag_dest_set(listTargets); m_scheme_box->signal_drag_data_received().connect(sigc::mem_fun(*this, &MainWindow::on_drop_drag_data_received)); m_palette_view->signal_color_selected().connect( sigc::mem_fun(*this, &MainWindow::on_schemebox_color_selected)); m_palette_view->set_from_file(Glib::build_filename(AGAVE_PALETTEDIR, "Web.gpl")); m_palette_view->set_expanded(Conf::get_palette_expanded()); m_bookmark_list->get_selection()->signal_changed().connect( sigc::mem_fun(*this, &MainWindow::on_bookmarks_selection_changed)); m_scrolledwindow_favorites->add(*m_bookmark_list); m_vbox_favorites->pack_start(*m_bookmark_bar, Gtk::PACK_SHRINK); m_bookmark_bar->set_toolbar_style(Gtk::TOOLBAR_BOTH_HORIZ); m_statusbar->push(_("Choose a Color and a Scheme Type"), 1); g_assert(m_pAbout); set_default_size(Conf::get_window_width(), Conf::get_window_height()); show_all(); } MainWindow::~MainWindow(void) { delete m_pAbout; delete m_pHistory; //delete m_pHistory; LOG("MainWindow DELETED!"); } void MainWindow::on_realize() { Gtk::Window::on_realize(); // this can't be done in the constructor because get_width() doesn't // return anything meaningful in the constructor g_assert (m_pane); m_pane->set_position(get_width() - Conf::get_favorites_width()); } // Actions must be initialized first void MainWindow::init_ui(void) { m_refUIManager = Gtk::UIManager::create(); m_refUIManager->insert_action_group(m_refActionGroup); add_accel_group(m_refUIManager->get_accel_group()); try { m_refUIManager->add_ui_from_file(AGAVE_UIDIR "/agave.ui"); LOG("added UI"); } catch(const Glib::Error& ex) { // we can't do anything without the UI / toolbar definition. std::cerr << __FILE__ << ": " << ex.what() << std::endl; throw ex; } // cache some pointers to widgets from glade in class variables m_vbox_layout = static_cast(m_glade->get_widget("vbox_layout")); g_assert(m_vbox_layout); m_vbox_menu_toolbar = static_cast(m_glade->get_widget("vbox_menu_toolbar")); g_assert(m_vbox_menu_toolbar); m_vbox_main = static_cast(m_glade->get_widget("vbox_main")); g_assert(m_vbox_main); m_vbox_favorites = static_cast(m_glade->get_widget("vbox_favorites")); g_assert(m_vbox_favorites); m_scrolledwindow_favorites = static_cast(m_glade->get_widget("scrolledwindow_favorites")); g_assert(m_scrolledwindow_favorites); m_vbox_scheme_display = static_cast(m_glade->get_widget("vbox_scheme_display")); g_assert(m_vbox_scheme_display); m_pane = static_cast(m_glade->get_widget("hpaned1")); g_assert(m_pane); m_main_menu = static_cast( m_refUIManager->get_widget("/MainMenu")); g_assert(m_main_menu); m_toolbar = static_cast( m_refUIManager->get_widget("/TweakBar")); g_assert(m_toolbar); m_color_button = static_cast(m_glade->get_widget("colorbutton1")); g_assert(m_color_button); m_glade->get_widget_derived("combobox_scheme_selector", m_scheme_selector); g_assert(m_scheme_selector); m_glade->get_widget_derived("expander_palette", m_palette_view); g_assert(m_palette_view); m_bookmark_bar = dynamic_cast(m_refUIManager->get_widget("/BookmarkBar")); g_assert(m_bookmark_bar); m_statusbar = static_cast(m_glade->get_widget("statusbar1")); g_assert(m_statusbar); } void MainWindow::set_color(ColorPtr c) { m_color_button->set_color(c->gdk()); on_color_changed(); } void MainWindow::on_show(void) { Gtk::Window::on_show(); m_scheme_selector->set_scheme_type(Conf::get_last_scheme_type()); // hack to get the schemetype selector to select the right starting // scheme on_schemetype_changed(); update_bookmark_actions(); set_color(Conf::get_last_color()); } bool MainWindow::on_delete_event(GdkEventAny* event) { quit(); return true; } void MainWindow::quit(void) { hide(); ColorPtr clr = m_scheme_box->get_color(); Conf::set_last_color(clr); Conf::set_last_scheme_type(m_scheme_box->get_scheme_type()); // only save the window size if the window isn't maximized if (!(get_window()->get_state() & Gdk::WINDOW_STATE_MAXIMIZED)) { Conf::set_window_width(get_width()); Conf::set_window_height(get_height()); Conf::set_favorites_width(get_width() - m_pane->get_position()); Conf::set_palette_expanded(m_palette_view->get_expanded()); } } void MainWindow::on_color_changed(void) { ColorPtr clr = Color::create(m_color_button->get_color()); m_scheme_box->set_color(clr); m_pHistory->add(clr->get_hexstring()); //LOG(*m_pHistory); m_refActionGroup->get_action("HistoryBack")->set_sensitive(m_pHistory->has_back()); m_refActionGroup->get_action("HistoryFwd")->set_sensitive(m_pHistory->has_forward()); // check if we're at limits Glib::RefPtr action = m_refActionGroup->get_action("LightenScheme"); if (clr->get_value() == maxSvValue) { // disable lighten button action->set_sensitive(false); } else { action->set_sensitive(); } action = m_refActionGroup->get_action("DarkenScheme"); if (clr->get_value() <= minColorValue + 5) { // disable darken button action->set_sensitive(false); } else { action->set_sensitive(); } action = m_refActionGroup->get_action("SaturateScheme"); if (clr->get_saturation() == maxSvValue) { // disable saturate button action->set_sensitive(false); } else { action->set_sensitive(); } action = m_refActionGroup->get_action("DesaturateScheme"); if (clr->get_saturation() <= minColorValue + 5) { // disable desaturate button action->set_sensitive(false); } else { action->set_sensitive(); } LOG("Color was changed!"); ColorPtr ptr = m_bookmark_list->get_color(); if (ptr && (*ptr != *clr)) { m_bookmark_list->get_selection()->unselect_all(); } } void MainWindow::on_schemetype_changed(void) { tSchemeType type = m_scheme_selector->get_scheme_type(); m_scheme_box->set_scheme_type(type); LOG("Scheme type is " << type); } void MainWindow::on_bookmarks_selection_changed(void) { LOG("Bookmarks changed"); ColorPtr pClr = m_bookmark_list->get_color(); if (pClr) { set_color(pClr); } update_bookmark_actions(); } void MainWindow::on_schemebox_color_selected(ColorPtr pColor) { // Need to make a copy of the color that we're passed so that if we // change the color of the swatch it doesn't change the color in the // palette / favorite list as well ColorPtr c = Color::create(*pColor); set_color(c); } void MainWindow::on_drop_drag_data_received(const Glib::RefPtr& context, int x, int y, const Gtk::SelectionData& selection_data, guint info, guint time) { LOG("== Drop received =="); bool drag_success = false; boost::shared_ptr c = get_dropped_color(selection_data); if(c) { // create a gcs::Color from the Gdk::Color ColorPtr pClr = Color::create(*c); // set the application's current color set_color(pClr); drag_success = true; } context->drag_finish(drag_success, false, time); } } // namespace gcs