├── .gitignore ├── CMakeLists.txt ├── README.md ├── cmake ├── FindGTKMM.cmake ├── GlibUtils.cmake ├── InstallScript.cmake ├── projectdefinitions.h.in └── uninstall.sh ├── data ├── CMakeLists.txt ├── desktop.in ├── gresource.xml.in ├── gschema.xml.in ├── icons │ └── 48x48 │ │ └── icon.png └── ui │ ├── headerbar.glade │ ├── menu.glade │ ├── preferences.glade │ └── window.glade ├── init.sh ├── src ├── CMakeLists.txt ├── application.cpp ├── application.h ├── main.cpp ├── preferences.cpp ├── preferences.h ├── window.cpp └── window.h └── test └── CMakeLists.txt /.gitignore: -------------------------------------------------------------------------------- 1 | *.user* 2 | *.glade~ 3 | .clang-format 4 | build/ 5 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 3.2) 2 | 3 | project(_PROJECT_NAME_ VERSION 1.0) 4 | 5 | set(APPLICATION_ID "_APPLICATION_ID_") 6 | string(REPLACE "." "/" APPLICATION_PREFIX "/${APPLICATION_ID}/") 7 | 8 | list(INSERT CMAKE_MODULE_PATH 0 ${PROJECT_SOURCE_DIR}/cmake) 9 | include(GlibUtils) 10 | include(InstallScript) 11 | 12 | set(GENERATED_FILES_DIR ${PROJECT_BINARY_DIR}/generated) 13 | set(GENERATED_SOURCES_DIR ${GENERATED_FILES_DIR}/src) 14 | set(GENERATED_DATA_DIR ${GENERATED_FILES_DIR}/data) 15 | 16 | configure_file(cmake/projectdefinitions.h.in ${GENERATED_SOURCES_DIR}/projectdefinitions.h) 17 | 18 | find_package(GTKMM) 19 | 20 | add_subdirectory(src) 21 | add_subdirectory(data) 22 | add_subdirectory(test) 23 | 24 | install(FILES cmake/uninstall.sh DESTINATION ${PROJECT_BINARY_DIR} PERMISSIONS OWNER_EXECUTE OWNER_READ OWNER_WRITE) 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Gtkmm-Application-Template 2 | 3 | Simple template to write Gtkmm applications using CMake and Glade 4 | 5 | ## Requirements 6 | * Gtkmm-3.0 7 | * CMake-3.2 or higher 8 | * Glade (optional) 9 | 10 | ## Getting started 11 | 1. Clone repository with preferred project name: 12 | ```bash 13 | git clone https://github.com/anschu/gtkmm-application-template.git PROJECT_NAME 14 | ``` 15 | 16 | 2. Run initialization script located in the project root... 17 | ```bash 18 | cd PROJECT_NAME/ 19 | bash init.sh 20 | ``` 21 | ...and choose your application-ID e.g. "org.gtkmm.MyApplication". 22 | 23 | 3. Write your code. 24 | 25 | 4. Build the project: 26 | ```bash 27 | mkdir build 28 | cd build/ 29 | cmake .. 30 | make 31 | ``` 32 | 5. Installation: 33 | ```bash 34 | sudo make install 35 | ``` 36 | 37 | 6. If you want to uninstall your application run the shellscript in the build-directory: 38 | ```bash 39 | sudo ./uninstall.sh 40 | ``` 41 | 42 | ## References 43 | Most parts used in the source code are copied from the GNOME Developer Guide [Programming with gtkmm3](https://developer.gnome.org/gtkmm-tutorial/stable/ "Programming with gtkmm3"), especially chapter [Building applications](https://developer.gnome.org/gtkmm-tutorial/stable/chapter-building-applications.html.en "Building applications"). 44 | -------------------------------------------------------------------------------- /cmake/FindGTKMM.cmake: -------------------------------------------------------------------------------- 1 | find_package(PkgConfig REQUIRED) 2 | pkg_check_modules(GTKMM REQUIRED gtkmm-3.0) 3 | add_library(GTKMM INTERFACE IMPORTED) 4 | set_property(TARGET GTKMM PROPERTY INTERFACE_INCLUDE_DIRECTORIES ${GTKMM_INCLUDE_DIRS}) 5 | set_property(TARGET GTKMM PROPERTY INTERFACE_LINK_LIBRARIES ${GTKMM_LIBRARIES}) 6 | set_property(TARGET GTKMM PROPERTY INTERFACE_COMPILE_OPTIONS ${GTKMM_CFLAGS_OTHER}) 7 | -------------------------------------------------------------------------------- /cmake/GlibUtils.cmake: -------------------------------------------------------------------------------- 1 | macro(compile_resources OUTPUT) 2 | find_program(GLIB_RESOURCE_COMPILER NAMES glib-compile-resources REQUIRED) 3 | 4 | set(GRESOURCE_FILE ${GENERATED_DATA_DIR}/${PROJECT_NAME}.gresource.xml) 5 | set(WORK_DIR ${PROJECT_SOURCE_DIR}/data) 6 | 7 | if(${ARGC} GREATER 1) 8 | foreach(arg IN ITEMS ${ARGN}) 9 | string(CONCAT RESOURCE ${WORK_DIR}/ui/ ${arg}) 10 | list(APPEND RESOURCES ${RESOURCE}) 11 | endforeach() 12 | endif() 13 | 14 | add_custom_command( 15 | OUTPUT ${OUTPUT} 16 | WORKING_DIRECTORY ${WORK_DIR} 17 | COMMAND ${GLIB_RESOURCE_COMPILER} --target=${OUTPUT} --generate-source ${GRESOURCE_FILE} 18 | DEPENDS ${GRESOURCE_FILE} ${RESOURCES} 19 | COMMENT "Generating ${OUTPUT}..." 20 | ) 21 | endmacro() 22 | 23 | macro(compile_schemas GSCHEMA_XML) 24 | find_program(GLIB_SCHEMA_COMPILER NAMES glib-compile-schemas REQUIRED) 25 | 26 | set(WORK_DIR ${PROJECT_SOURCE_DIR}/data) 27 | 28 | if(${ARGC} GREATER 1) 29 | foreach(arg IN ITEMS ${ARGN}) 30 | string(CONCAT SCHEMA ${WORK_DIR} ${arg}) 31 | list(APPEND SCHEMAS ${SCHEMA}) 32 | endforeach() 33 | endif() 34 | 35 | set(OUTPUT_DIR ${PROJECT_BINARY_DIR}/generated/data) 36 | set(OUTPUT ${OUTPUT_DIR}/gschemas.compiled) 37 | add_custom_command( 38 | OUTPUT ${OUTPUT} 39 | WORKING_DIRECTORY ${WORK_DIR} 40 | COMMAND mkdir -p ${OUTPUT_DIR} 41 | COMMAND ${GLIB_SCHEMA_COMPILER} --strict --dry-run --schema-file=${GSCHEMA_XML} 42 | COMMAND ${GLIB_SCHEMA_COMPILER} --schema-file=${GSCHEMA_XML} --targetdir=${OUTPUT_DIR} 43 | DEPENDS ${GSCHEMA_XML} ${SCHEMAS} 44 | COMMENT "Generating ${OUTPUT}..." 45 | ) 46 | add_custom_target(gschemas.compiled ALL DEPENDS ${OUTPUT}) 47 | endmacro() 48 | -------------------------------------------------------------------------------- /cmake/InstallScript.cmake: -------------------------------------------------------------------------------- 1 | execute_process( 2 | COMMAND glib-compile-schemas . 3 | WORKING_DIRECTORY /usr/share/glib-2.0/schemas 4 | OUTPUT_QUIET 5 | ERROR_QUIET 6 | ) 7 | -------------------------------------------------------------------------------- /cmake/projectdefinitions.h.in: -------------------------------------------------------------------------------- 1 | #ifndef CONFIG_H_IN 2 | #define CONFIG_H_IN 3 | 4 | #include 5 | 6 | namespace projectdefinitions { 7 | static std::string getProjectName() { 8 | return "@PROJECT_NAME@"; 9 | } 10 | 11 | static std::string getProjectVersion() { 12 | return "@PROJECT_VERSION@"; 13 | } 14 | 15 | static std::string getApplicationID() { 16 | return "@APPLICATION_ID@"; 17 | } 18 | 19 | static std::string getApplicationPrefix() { 20 | return "@APPLICATION_PREFIX@"; 21 | } 22 | 23 | static std::string getGeneratedFilesDirectory() { 24 | return "@GENERATED_FILES_DIR@"; 25 | } 26 | 27 | static std::string getGeneratedDataDirectory() { 28 | return "@GENERATED_DATA_DIR@"; 29 | } 30 | } 31 | 32 | #endif // CONFIG_H_IN 33 | -------------------------------------------------------------------------------- /cmake/uninstall.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | xargs rm < install_manifest.txt 4 | glib-compile-schemas /usr/share/glib-2.0/schemas/. 5 | -------------------------------------------------------------------------------- /data/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(GRESOURCE_FILE ${GENERATED_DATA_DIR}/${PROJECT_NAME}.gresource.xml) 2 | set(GSCHEMA_FILE ${GENERATED_DATA_DIR}/${APPLICATION_ID}.gschema.xml) 3 | set(DESKTOP_FILE ${GENERATED_DATA_DIR}/${APPLICATION_ID}.desktop) 4 | set(ICON_FILE ${GENERATED_DATA_DIR}/${PROJECT_NAME}.png) 5 | 6 | configure_file(gresource.xml.in ${GRESOURCE_FILE}) 7 | configure_file(gschema.xml.in ${GSCHEMA_FILE}) 8 | configure_file(desktop.in ${DESKTOP_FILE}) 9 | configure_file(icons/48x48/icon.png ${ICON_FILE} COPYONLY) 10 | 11 | compile_schemas(${GSCHEMA_FILE}) 12 | 13 | install(FILES ${GSCHEMA_FILE} DESTINATION /usr/share/glib-2.0/schemas) 14 | install(FILES ${DESKTOP_FILE} DESTINATION /usr/share/applications) 15 | install(FILES ${ICON_FILE} DESTINATION /usr/share/icons/${PROJECT_NAME}) 16 | install(SCRIPT ${PROJECT_SOURCE_DIR}/cmake/InstallScript.cmake) 17 | -------------------------------------------------------------------------------- /data/desktop.in: -------------------------------------------------------------------------------- 1 | [Desktop Entry] 2 | Type=Application 3 | Name=@PROJECT_NAME@ 4 | GenericName=@PROJECT_NAME@ 5 | Comment=Application 6 | Icon=/usr/share/icons/@PROJECT_NAME@/@PROJECT_NAME@.png 7 | StartupNotify=true 8 | Exec=@PROJECT_NAME@ 9 | Categories=GNOME;GTK; 10 | -------------------------------------------------------------------------------- /data/gresource.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ui/window.glade 5 | ui/headerbar.glade 6 | ui/preferences.glade 7 | ui/menu.glade 8 | icons/48x48/icon.png 9 | 10 | 11 | -------------------------------------------------------------------------------- /data/gschema.xml.in: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 'one' 11 | First 12 | First Setting 13 | 14 | 15 | false 16 | Second 17 | Second Setting 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /data/icons/48x48/icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anschu/gtkmm-application-template/774a6a9a474e39f7ef655d990ddfaaab04aa0905/data/icons/48x48/icon.png -------------------------------------------------------------------------------- /data/ui/headerbar.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | True 7 | False 8 | True 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /data/ui/menu.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 |
6 | 7 | _Preferences 8 | app.preferences 9 | 10 |
11 |
12 | 13 | _Quit 14 | app.quit 15 | 16 |
17 |
18 |
19 | -------------------------------------------------------------------------------- /data/ui/preferences.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | False 7 | Preferences 8 | True 9 | dialog 10 | 11 | 12 | 13 | 14 | 15 | False 16 | vertical 17 | 2 18 | 19 | 20 | False 21 | end 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | False 31 | False 32 | 0 33 | 34 | 35 | 36 | 37 | True 38 | False 39 | 12 40 | 6 41 | 42 | 43 | True 44 | False 45 | First 46 | 47 | 48 | 0 49 | 0 50 | 51 | 52 | 53 | 54 | True 55 | False 56 | Second 57 | 58 | 59 | 0 60 | 1 61 | 62 | 63 | 64 | 65 | True 66 | False 67 | 68 | FirstItem 69 | SecondItem 70 | ThirdItem 71 | 72 | 73 | 74 | 1 75 | 0 76 | 77 | 78 | 79 | 80 | checkbutton 81 | True 82 | True 83 | False 84 | True 85 | 86 | 87 | 1 88 | 1 89 | 90 | 91 | 92 | 93 | False 94 | True 95 | 1 96 | 97 | 98 | 99 | 100 | 101 | 102 | -------------------------------------------------------------------------------- /data/ui/window.glade: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 800 7 | 600 8 | False 9 | 10 | 11 | 12 | 13 | 14 | True 15 | False 16 | vertical 17 | 18 | 19 | True 20 | False 21 | label 22 | 23 | 24 | False 25 | True 26 | 2 27 | 28 | 29 | 30 | 31 | True 32 | False 33 | label 34 | 35 | 36 | False 37 | True 38 | 3 39 | 40 | 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /init.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | function init_project { 4 | IFS="." read -a ID_PARTS <<< "${1}" 5 | 6 | sed -i -e "s/_APPLICATION_ID_/${1}/g" CMakeLists.txt 7 | sed -i -e "s/_PROJECT_NAME_/${ID_PARTS[-1]}/g" CMakeLists.txt 8 | 9 | rm -rf .git* 10 | rm -f README.md 11 | rm -f init.sh 12 | 13 | echo "Project initialized as '${1}'" 14 | } 15 | 16 | DEFAULT_PROJECT_ID="org.gtkmm.ApplicationTemplate" 17 | 18 | read -p "ProjectID [default: $DEFAULT_PROJECT_ID]: " PROJECT_ID 19 | 20 | if [[ ! $PROJECT_ID ]] 21 | then 22 | PROJECT_ID=$DEFAULT_PROJECT_ID 23 | fi 24 | 25 | init_project $PROJECT_ID 26 | -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_executable(${PROJECT_NAME} 2 | main.cpp 3 | application.cpp 4 | window.cpp 5 | preferences.cpp 6 | ${GENERATED_DATA_DIR}/resources.c 7 | ) 8 | 9 | target_link_libraries(${PROJECT_NAME} 10 | GTKMM 11 | ) 12 | 13 | target_include_directories(${PROJECT_NAME} PRIVATE ${GENERATED_SOURCES_DIR}) 14 | 15 | compile_resources( 16 | ${GENERATED_DATA_DIR}/resources.c 17 | window.glade 18 | headerbar.glade 19 | menu.glade 20 | preferences.glade 21 | ) 22 | 23 | install(TARGETS ${PROJECT_NAME} DESTINATION bin) 24 | -------------------------------------------------------------------------------- /src/application.cpp: -------------------------------------------------------------------------------- 1 | #include "application.h" 2 | 3 | #include 4 | 5 | #include "projectdefinitions.h" 6 | 7 | Application::Application() : Gtk::Application(projectdefinitions::getApplicationID() + ".application") { 8 | } 9 | 10 | Application::~Application() { 11 | } 12 | 13 | Glib::RefPtr Application::create() { 14 | return Glib::RefPtr(new Application()); 15 | } 16 | 17 | Window *Application::createWindow() { 18 | auto window = Window::create(); 19 | add_window(*window); 20 | window->signal_hide().connect(sigc::bind(sigc::mem_fun(*this, &Application::on_hide_window), window)); 21 | return window; 22 | } 23 | 24 | void Application::on_activate() { 25 | try { 26 | auto window = createWindow(); 27 | window->present(); 28 | } catch (const Glib::Error &ex) { 29 | std::cerr << "Application::on_activate(): " << ex.what() << std::endl; 30 | } catch (const std::exception &ex) { 31 | std::cerr << "Application::on_activate(): " << ex.what() << std::endl; 32 | } 33 | } 34 | 35 | void Application::on_startup() { 36 | Gtk::Application::on_startup(); 37 | 38 | add_action("preferences", sigc::mem_fun(*this, &Application::on_action_preferences)); 39 | add_action("quit", sigc::mem_fun(*this, &Application::on_action_quit)); 40 | set_accel_for_action("app.quit", "Q"); 41 | 42 | auto builder = Gtk::Builder::create(); 43 | try { 44 | builder->add_from_resource(projectdefinitions::getApplicationPrefix() + "ui/menu.glade"); 45 | } catch (const Glib::Error &ex) { 46 | std::cerr << "Application::on_startup(): " << ex.what() << std::endl; 47 | return; 48 | } 49 | 50 | auto object = builder->get_object("appmenu"); 51 | auto app_menu = Glib::RefPtr::cast_dynamic(object); 52 | if (app_menu) { 53 | set_app_menu(app_menu); 54 | } else { 55 | std::cerr << "Application::on_startup(): No \"appmenu\" object in menu.glade" << std::endl; 56 | } 57 | } 58 | 59 | void Application::on_hide_window(Gtk::Window *window) { 60 | delete window; 61 | } 62 | 63 | void Application::on_action_preferences() { 64 | try { 65 | auto prefsDialog = Preferences::create(*get_active_window()); 66 | prefsDialog->present(); 67 | prefsDialog->signal_hide().connect(sigc::bind(sigc::mem_fun(*this, &Application::on_hide_window), prefsDialog)); 68 | } catch (const Glib::Error &ex) { 69 | std::cerr << "Application::on_action_preferences(): " << ex.what() << std::endl; 70 | } catch (const std::exception &ex) { 71 | std::cerr << "Application::on_action_preferences(): " << ex.what() << std::endl; 72 | } 73 | } 74 | 75 | void Application::on_action_quit() { 76 | auto windows = get_windows(); 77 | for (auto window : windows) { 78 | window->hide(); 79 | } 80 | quit(); 81 | } 82 | -------------------------------------------------------------------------------- /src/application.h: -------------------------------------------------------------------------------- 1 | #ifndef APPLICATION_H 2 | #define APPLICATION_H 3 | 4 | #include 5 | 6 | #include "preferences.h" 7 | #include "window.h" 8 | 9 | class Application : public Gtk::Application { 10 | public: 11 | virtual ~Application() override; 12 | 13 | static Glib::RefPtr create(); 14 | 15 | private: 16 | Application(); 17 | 18 | Window* createWindow(); 19 | 20 | void on_activate() override; 21 | void on_startup() override; 22 | void on_hide_window(Gtk::Window* window); 23 | void on_action_preferences(); 24 | void on_action_quit(); 25 | }; 26 | 27 | #endif // APPLICATION_H 28 | -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include "application.h" 6 | #include "projectdefinitions.h" 7 | 8 | int main(int argc, char** argv) { 9 | Glib::setenv("GSETTINGS_SCHEMA_DIR", projectdefinitions::getGeneratedDataDirectory(), false); 10 | auto app = Application::create(); 11 | return app->run(argc, argv); 12 | } 13 | -------------------------------------------------------------------------------- /src/preferences.cpp: -------------------------------------------------------------------------------- 1 | #include "preferences.h" 2 | 3 | #include "projectdefinitions.h" 4 | 5 | Preferences::Preferences(BaseObjectType *cobject, const Glib::RefPtr &builder) 6 | : Gtk::Dialog(cobject), builder(builder), settings(nullptr), comboBoxText(nullptr), checkButton(nullptr) { 7 | builder->get_widget("comboBoxText", comboBoxText); 8 | if (!comboBoxText) { 9 | throw std::runtime_error("No \"comboBoxText\" object in preferences.glade"); 10 | } 11 | 12 | builder->get_widget("checkButton", checkButton); 13 | if (!checkButton) { 14 | throw std::runtime_error("No \"checkButton\" object in preferences.glade"); 15 | } 16 | 17 | settings = Gio::Settings::create(projectdefinitions::getApplicationID()); 18 | settings->bind("first", comboBoxText->property_active_id()); 19 | settings->bind("second", checkButton->property_active()); 20 | } 21 | 22 | Preferences::~Preferences() { 23 | } 24 | 25 | Preferences *Preferences::create(Gtk::Window &parent) { 26 | auto builder = Gtk::Builder::create_from_resource(projectdefinitions::getApplicationPrefix() + "ui/preferences.glade"); 27 | 28 | Preferences *prefsDialog = nullptr; 29 | builder->get_widget_derived("prefsDialog", prefsDialog); 30 | if (!prefsDialog) { 31 | throw std::runtime_error("No \"prefsDialog\" object in preferences.glade"); 32 | } 33 | 34 | prefsDialog->set_transient_for(parent); 35 | return prefsDialog; 36 | } 37 | -------------------------------------------------------------------------------- /src/preferences.h: -------------------------------------------------------------------------------- 1 | #ifndef PREFERENCES_H 2 | #define PREFERENCES_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class Preferences : public Gtk::Dialog { 11 | public: 12 | Preferences(BaseObjectType* cobject, const Glib::RefPtr& builder); 13 | virtual ~Preferences(); 14 | 15 | static Preferences* create(Gtk::Window& parent); 16 | 17 | private: 18 | Glib::RefPtr builder; 19 | Glib::RefPtr settings; 20 | Gtk::ComboBoxText* comboBoxText; 21 | Gtk::CheckButton* checkButton; 22 | }; 23 | 24 | #endif // PREFERENCES_H 25 | -------------------------------------------------------------------------------- /src/window.cpp: -------------------------------------------------------------------------------- 1 | #include "window.h" 2 | 3 | #include 4 | 5 | #include 6 | 7 | #include "projectdefinitions.h" 8 | 9 | Window::Window(Gtk::ApplicationWindow::BaseObjectType* cobject, const Glib::RefPtr& builder) 10 | : Gtk::ApplicationWindow(cobject), 11 | builder(builder), 12 | settings(nullptr), 13 | headerBar(nullptr), 14 | firstLabel(nullptr), 15 | secondLabel(nullptr) { 16 | builder->get_widget("firstLabel", firstLabel); 17 | if (!firstLabel) { 18 | throw std::runtime_error("No \"firstLabel\" object in window.glade"); 19 | } 20 | 21 | builder->get_widget("secondLabel", secondLabel); 22 | if (!secondLabel) { 23 | throw std::runtime_error("No \"secondLabel\" object in window.glade"); 24 | } 25 | 26 | settings = Gio::Settings::create(projectdefinitions::getApplicationID()); 27 | settings->bind("first", firstLabel->property_label()); 28 | settings->bind("second", secondLabel->property_visible()); 29 | 30 | set_icon(Gdk::Pixbuf::create_from_resource(projectdefinitions::getApplicationPrefix() + "icons/48x48/icon.png")); 31 | setHeaderBar(); 32 | } 33 | 34 | Window::~Window() { 35 | } 36 | 37 | Window* Window::create() { 38 | auto builder = Gtk::Builder::create_from_resource(projectdefinitions::getApplicationPrefix() + "ui/window.glade"); 39 | 40 | Window* window = nullptr; 41 | builder->get_widget_derived("window", window); 42 | if (!window) { 43 | throw std::runtime_error("No \"window\" object in window.glade"); 44 | } 45 | return window; 46 | } 47 | 48 | void Window::setHeaderBar() { 49 | auto builder = 50 | Gtk::Builder::create_from_resource(projectdefinitions::getApplicationPrefix() + "ui/headerbar.glade"); 51 | builder->get_widget("headerBar", headerBar); 52 | if (!headerBar) { 53 | throw std::runtime_error("No \"headerBar\" object in headerbar.glade"); 54 | } else { 55 | headerBar->set_title(projectdefinitions::getProjectName()); 56 | set_titlebar(*headerBar); 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /src/window.h: -------------------------------------------------------------------------------- 1 | #ifndef WINDOW_H 2 | #define WINDOW_H 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | class Window : public Gtk::ApplicationWindow { 11 | public: 12 | Window(BaseObjectType* cobject, const Glib::RefPtr& builder); 13 | virtual ~Window(); 14 | 15 | static Window* create(); 16 | 17 | private: 18 | Glib::RefPtr builder; 19 | Glib::RefPtr settings; 20 | Gtk::HeaderBar* headerBar; 21 | Gtk::Label* firstLabel; 22 | Gtk::Label* secondLabel; 23 | 24 | void setHeaderBar(); 25 | }; 26 | 27 | #endif // WINDOW_H 28 | -------------------------------------------------------------------------------- /test/CMakeLists.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/anschu/gtkmm-application-template/774a6a9a474e39f7ef655d990ddfaaab04aa0905/test/CMakeLists.txt --------------------------------------------------------------------------------