const Style Style::styleGTK(Glib::RefPtr<Gtk::StyleContext> styleContext) { const auto colorPositive = styleContext->get_color(); auto colorPositiveLight = colorPositive; colorPositiveLight.set_alpha(0.5); return { true, true, 1.0, styleContext->get_background_color(), colorPositive, colorPositiveLight, Gdk::RGBA("#3080e9"), Gdk::RGBA("#505050"), Gdk::RGBA("#606060"), 288.0, 60.0, 30.0, 20.0, 5.0, 3.0, 18.0 }; }
void PaletteItemTab::draw(DrawContext dc) { Glib::RefPtr<StyleContext> style = parent->get_style_context(); Gdk::RGBA dark = style->get_border_color(STATE_FLAG_NORMAL); Gdk::RGBA light = style->get_color(STATE_FLAG_NORMAL); dc->set_line_width(0.5); if(select || opened) { if(select) { Gdk::RGBA norm = style->get_background_color(STATE_FLAG_NORMAL); //TypeColor sel = style->get_base(Gtk::STATE_SELECTED); Cairo::RefPtr<Cairo::LinearGradient> lin_grad = Cairo::LinearGradient::create(0, y, width, y + minHeight); //Cairo::RefPtr<Cairo::LinearGradient> lin_grad = Cairo::LinearGradient::create(width / 2, y, width / 2, y + minHeight); lin_grad->add_color_stop_rgb(0, dark.get_red(), dark.get_green(), dark.get_blue()); lin_grad->add_color_stop_rgb(1, light.get_red(), light.get_green(), light.get_blue()); dc->set_source(lin_grad); } else if(opened) { Gdk::RGBA sel = style->get_color(STATE_FLAG_SELECTED); dc->set_source_rgb(sel.get_red(), sel.get_green(), sel.get_blue()); } dc->rectangle(x, y, width + 2, minHeight); dc->fill(); /* tabRoundRect(dc, x + 1, y, width, minHeight); dc->fill(); dc->set_source_rgb(light.get_red_p(), light.get_green_p(), light.get_blue_p()); tabRoundRect(dc, x + 1, y, width, minHeight); dc->stroke(); */ } //dc->rectangle(x, y, width, height); //dc->stroke(); /* style->paint_box(parent->get_window(), opened ? Gtk::STATE_SELECTED : (select ? Gtk::STATE_ACTIVE : Gtk::STATE_NORMAL), Gtk::SHADOW_IN, Gdk::Rectangle(x + 1, y, width, 20), *parent, ustring(), x + 1, y, width, 20); */ if(select) dc->set_source_rgb(1.0, 1.0, 1.0); else dc->set_source_rgb(0.0, 0.0, 0.0); dc->move_to(x + 20,y + 14); dc->set_font_size(TAB_FONT_SIZE); dc->show_text(caption); dc->set_line_width(1); if(opened) { Cairo::Antialias a = dc->get_antialias(); dc->set_antialias(Cairo::ANTIALIAS_NONE); dc->set_source_rgb(dark.get_red(), dark.get_green(), dark.get_blue()); dc->move_to(x + 3, y + height); dc->rel_line_to(width - 6, 0); dc->stroke(); dc->set_antialias(a); } dc->set_source_rgb(0.3, 0.3, 0.3); dc->arc(x + 10, y + 10, 4, 0, 2*3.1415); dc->fill(); PaletteItem::draw(dc); }
cGtkmmMainWindow::cGtkmmMainWindow(int argc, char** argv) : updateChecker(*this), notifyMainThread(*this), pMenuPopup(nullptr), comboBoxFolder(true), statusBar("0 photos"), photoBrowser(*this) { settings.Load(); set_title(BUILD_APPLICATION_NAME); set_size_request(400, 400); set_default_size(800, 800); // Restore the window size size_t width = 800; size_t height = 800; settings.GetMainWindowSize(width, height); resize(width, height); if (settings.IsMainWindowMaximised()) maximize(); // Set icon list std::vector<Glib::RefPtr<Gdk::Pixbuf> > icons; icons.push_back(Gdk::Pixbuf::create_from_file("data/icons/application_16x16.png")); icons.push_back(Gdk::Pixbuf::create_from_file("data/icons/application_32x32.png")); icons.push_back(Gdk::Pixbuf::create_from_file("data/icons/application_48x48.png")); icons.push_back(Gdk::Pixbuf::create_from_file("data/icons/application_64x64.png")); icons.push_back(Gdk::Pixbuf::create_from_file("data/icons/application_128x128.png")); icons.push_back(Gdk::Pixbuf::create_from_file("data/icons/application_256x256.png")); // GTK complains if we pass icons larger than 256x256 //icons.push_back(Gdk::Pixbuf::create_from_file("data/icons/application_512x512.png")); set_icon_list(icons); // Menu and toolbar // void Gtk::Application::set_app_menu(const Glib::RefPtr< Gio::MenuModel > & app_menu) // Sets or unsets the application menu for application. // The application menu is a single menu containing items that typically impact the application as a whole, rather than acting on a specific window or document. For example, you would expect to see "Preferences" or "Quit" in an application menu, but not "Save" or "Print". // If supported, the application menu will be rendered by the desktop environment. // You might call this method in your Application::property_startup() signal handler. // Use the base ActionMap interface to add actions, to respond to the user selecting these menu items. // Since gtkmm 3.4: // Create actions for menus and toolbars m_refActionGroup = Gtk::ActionGroup::create(); // File menu m_refActionGroup->add(Gtk::Action::create("FileMenu", "File")); m_refActionGroup->add(Gtk::Action::create("FileAddFiles", "Add Files"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnMenuFileBrowseFiles)); m_refActionGroup->add(Gtk::Action::create("FileAddFolder", "Add Folder"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnMenuFileBrowseFolder)); m_refActionGroup->add(Gtk::Action::create("FileAddFilesFromPicturesFolder", "Add Files From Pictures Folder"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionAddFilesFromPicturesFolder)); m_refActionGroup->add(Gtk::Action::create("FileImportFolder", "Import Folder From Removable Media"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnMenuFileImportFolder)); //m_refActionGroup->add(Gtk::Action::create("FileRemove", "Remove"), // sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionRemoveTrack)); //m_refActionGroup->add(Gtk::Action::create("FileMoveToFolderMenu", "Move to Folder")); //m_refActionGroup->add(Gtk::Action::create("FileMoveToFolderBrowse", "Browse..."), // sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionTrackMoveToFolderBrowse)); //m_refActionGroup->add(Gtk::Action::create("FileMoveToRubbishBin", "Move to the Rubbish Bin"), // sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionTrackMoveToRubbishBin)); //m_refActionGroup->add(Gtk::Action::create("FileShowInFileManager", "Show in the File Manager"), // sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionTrackShowInFileManager)); //m_refActionGroup->add(Gtk::Action::create("FileProperties", "Properties"), // sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionTrackProperties)); m_refActionGroup->add(Gtk::Action::create("FileQuit", Gtk::Stock::QUIT), sigc::mem_fun(*this, &cGtkmmMainWindow::OnMenuFileQuit)); // Edit menu m_refActionGroup->add(Gtk::Action::create("EditMenu", "Edit")); //Edit Tags -> edits each track separately //Batch Edit Tags -> edits all tracks at the same time m_refActionGroup->add(Gtk::Action::create("EditPreferences", Gtk::Stock::PREFERENCES), sigc::mem_fun(*this, &cGtkmmMainWindow::OnMenuEditPreferences)); // Playback menu m_refActionGroup->add(Gtk::Action::create("PlaybackMenu", "Playback")); //m_refActionGroup->add(Gtk::Action::create("PlaybackPrevious", Gtk::Stock::MEDIA_PREVIOUS), // sigc::mem_fun(*this, &cGtkmmMainWindow::OnPlaybackPreviousClicked)); //pPlayPauseAction = Gtk::ToggleAction::create("PlaybackPlayPause", Gtk::Stock::MEDIA_PLAY, "Play/Pause"); //m_refActionGroup->add(pPlayPauseAction, sigc::mem_fun(*this, &cGtkmmMainWindow::OnPlaybackPlayPauseMenuToggled)); //m_refActionGroup->add(Gtk::Action::create("PlaybackNext", Gtk::Stock::MEDIA_NEXT), // sigc::mem_fun(*this, &cGtkmmMainWindow::OnPlaybackNextClicked)); //m_refActionGroup->add(Gtk::Action::create("JumpToPlaying", "Jump to Playing"), // Gtk::AccelKey("<control>J"), // sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionJumpToPlaying)); //pRepeatAction = Gtk::ToggleAction::create("PlaybackRepeatToggle", Gtk::Stock::GOTO_TOP, "Repeat"); //m_refActionGroup->add(pRepeatAction, sigc::mem_fun(*this, &cGtkmmMainWindow::OnPlaybackRepeatMenuToggled)); // Help menu m_refActionGroup->add( Gtk::Action::create("HelpMenu", "Help") ); m_refActionGroup->add( Gtk::Action::create("HelpAbout", Gtk::Stock::ABOUT), sigc::mem_fun(*this, &cGtkmmMainWindow::OnMenuHelpAbout) ); m_refUIManager = Gtk::UIManager::create(); m_refUIManager->insert_action_group(m_refActionGroup); add_accel_group(m_refUIManager->get_accel_group()); // Layout the actions in a menubar and toolbar { Glib::ustring ui_info = "<ui>" " <menubar name='MenuBar'>" " <menu action='FileMenu'>" " <menuitem action='FileAddFiles'/>" " <menuitem action='FileAddFolder'/>" " <menuitem action='FileAddFilesFromPicturesFolder'/>" " <menuitem action='FileImportFolder'/>" //" <menuitem action='FileRemove'/>" //" <menu action='FileMoveToFolderMenu'>" //" <menuitem action='FileMoveToFolderBrowse'/>" //" </menu>" //" <menuitem action='FileMoveToRubbishBin'/>" //" <menuitem action='FileShowInFileManager'/>" //" <menuitem action='FileProperties'/>" //" <separator/>" " <menuitem action='FileQuit'/>" " </menu>" " <menu action='EditMenu'>" " <menuitem action='EditPreferences'/>" " </menu>" " <menu action='PlaybackMenu'>" //" <menuitem action='PlaybackPrevious'/>" //" <menuitem action='PlaybackPlayPause'/>" //" <menuitem action='PlaybackNext'/>" //" <menuitem action='JumpToPlaying'/>" //" <separator/>" //" <menuitem action='PlaybackRepeatToggle'/>" " </menu>" " <menu action='HelpMenu'>" " <menuitem action='HelpAbout'/>" " </menu>" " </menubar>" " <toolbar name='ToolBar'>" //" <toolitem action='PlaybackPrevious'/>" //" <toolitem action='PlaybackPlayPause'/>" //" <toolitem action='PlaybackNext'/>" //" <toolitem action='PlaybackRepeatToggle'/>" " </toolbar>" "</ui>"; try { m_refUIManager->add_ui_from_string(ui_info); } catch(const Glib::Error& ex) { std::cerr<<"building menus failed: "<<ex.what(); } } // Get the menubar and toolbar widgets, and add them to a container widget Gtk::Widget* pMenubar = m_refUIManager->get_widget("/MenuBar"); if (pMenubar != nullptr) boxMainWindow.pack_start(*pMenubar, Gtk::PACK_SHRINK); // Photo browser right click menu Glib::RefPtr<Gtk::ActionGroup> popupActionGroupRef; // Right click menu popupActionGroupRef = Gtk::ActionGroup::create(); // File|New sub menu: // These menu actions would normally already exist for a main menu, because a context menu should // not normally contain menu items that are only available via a context menu. popupActionGroupRef->add(Gtk::Action::create("ContextMenu", "Context Menu")); popupActionGroupRef->add(Gtk::Action::create("ContextAddFiles", "Add Files"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionBrowseFiles)); popupActionGroupRef->add(Gtk::Action::create("ContextAddFolder", "Add Folder"), Gtk::AccelKey("<control>P"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionBrowseFolder)); popupActionGroupRef->add(Gtk::Action::create("ContextRemove", "Remove"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionRemovePhoto)); //Edit Tags -> edits each track separately //Batch Edit Tags -> edits all tracks at the same time /*/popupActionGroupRef->add(Gtk::Action::create("ContextMoveToFolderMenu", "Move to Folder")); popupActionGroupRef->add(Gtk::Action::create("ContextTrackMoveToFolderBrowse", "Browse..."), sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionTrackMoveToFolderBrowse)); popupActionGroupRef->add(Gtk::Action::create("ContextTrackMoveToRubbishBin", "Move to the Rubbish Bin"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionTrackMoveToRubbishBin)); popupActionGroupRef->add(Gtk::Action::create("ContextShowInFileManager", "Show in the File Manager"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionTrackShowInFileManager)); popupActionGroupRef->add(Gtk::Action::create("ContextProperties", "Properties"), sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionTrackProperties));*/ popupUIManagerRef = Gtk::UIManager::create(); popupUIManagerRef->insert_action_group(popupActionGroupRef); add_accel_group(popupUIManagerRef->get_accel_group()); // Layout the actions in our popup menu { Glib::ustring ui_info = "<ui>" " <popup name='PopupMenu'>" " <menuitem action='ContextAddFiles'/>" " <menuitem action='ContextAddFolder'/>" " <menuitem action='ContextRemove'/>" /*" <menu action='ContextMoveToFolderMenu'>" " <menuitem action='ContextTrackMoveToFolderBrowse'/>" " </menu>" " <menuitem action='ContextTrackMoveToRubbishBin'/>" " <menuitem action='ContextShowInFileManager'/>" " <menuitem action='ContextProperties'/>"*/ " </popup>" "</ui>"; try { popupUIManagerRef->add_ui_from_string(ui_info); } catch(const Glib::Error& ex) { std::cerr<<"building menus failed: "<<ex.what(); } } // Get the menu pMenuPopup = dynamic_cast<Gtk::Menu*>(popupUIManagerRef->get_widget("/PopupMenu")); if (pMenuPopup == nullptr) g_warning("Popup menu not found"); assert(pMenuPopup != nullptr); // In gtkmm 3 set_orientation is not supported so we create our own toolbar out of plain old buttons //Gtk::Toolbar* pToolbar = dynamic_cast<Gtk::Toolbar*>(m_refUIManager->get_widget("/ToolBar")); //if (pToolbar != nullptr) { // pToolbar->property_orientation() = Gtk::ORIENTATION_VERTICAL; // //pToolbar->set_orientation(Gtk::ORIENTATION_VERTICAL); // pToolbar->set_toolbar_style(Gtk::TOOLBAR_ICONS); // boxToolbar.pack_start(*pToolbar); //} buttonAddFiles.signal_clicked().connect(sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionBrowseFiles)); buttonAddFolder.signal_clicked().connect(sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionBrowseFolder)); boxToolbar.pack_start(buttonFolderUp, Gtk::PACK_SHRINK); boxToolbar.pack_start(buttonFolderShowInFileManager, Gtk::PACK_SHRINK); boxToolbar.pack_start(buttonAddFiles, Gtk::PACK_SHRINK); boxToolbar.pack_start(buttonAddFolder, Gtk::PACK_SHRINK); boxToolbar.pack_start(*Gtk::manage(new Gtk::Separator()), Gtk::PACK_SHRINK); // Controls comboBoxFolder.get_entry()->signal_changed().connect(sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionChangeFolder)); buttonFolderUp.signal_clicked().connect(sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionFolderUp)); buttonFolderUp.set_tooltip_text("Move up"); buttonFolderShowInFileManager.signal_clicked().connect(sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionFolderShowInFileManager)); buttonFolderShowInFileManager.set_tooltip_text("Show folder in file manager"); buttonStopLoading.signal_clicked().connect(sigc::mem_fun(*this, &cGtkmmMainWindow::OnActionStopLoading)); photoBrowser.Init(argc, argv); boxControls.pack_start(comboBoxFolder, Gtk::PACK_SHRINK); boxControls.pack_start(photoBrowser.GetWidget(), Gtk::PACK_EXPAND_WIDGET); boxControlsAndToolbar.pack_start(boxControls, Gtk::PACK_EXPAND_WIDGET); boxControlsAndToolbar.pack_start(boxToolbar, Gtk::PACK_SHRINK); // Hide the stop button until we start loading some files buttonStopLoading.hide(); boxStatusBar.pack_start(statusBar, Gtk::PACK_SHRINK); boxStatusBar.pack_start(buttonStopLoading, Gtk::PACK_SHRINK); //... show progress bar indeterminate when we are loading any files or playlists boxMainWindow.pack_start(boxControlsAndToolbar, Gtk::PACK_EXPAND_WIDGET); boxMainWindow.pack_start(boxStatusBar, Gtk::PACK_SHRINK); // Add the box layout to the main window add(boxMainWindow); { // Get a typical selection colour for the selections on our photo browser Gtk::Table table; Glib::RefPtr<Gtk::StyleContext> pStyleContext = table.get_style_context(); ASSERT(pStyleContext); const Gdk::RGBA colour = pStyleContext->get_background_color(Gtk::STATE_FLAG_SELECTED); const spitfire::math::cColour colourSelected(colour.get_red(), colour.get_green(), colour.get_blue(), colour.get_alpha()); photoBrowser.SetSelectionColour(colourSelected); } // Register our icon theme and update our icons iconTheme.RegisterThemeChangedListener(*this); UpdateIcons(); ApplySettings(); show_all_children(); // Start the update checker now that we have finished doing the serious work updateChecker.Run(); notifyMainThread.Create(); }