/* Application main window * * Demonstrates a typical application window, with a menubar, toolbar and statusbar. */ #include "demowindow.hh" #include #include #include #include #include #include #include #include #include #include #include #include using namespace Xfc; class AppWindow : public Gtk::Window { static Pointer icon_factory; Pointer action_group; Pointer manager; Gtk::Statusbar *statusbar; Gtk::TextBuffer *buffer; void add_actions(); void update_statusbar(); void mark_set(const GtkTextIter*, GtkTextMark*); protected: void on_activate_action(Gtk::Action *action); void on_activate_radio_action(Gtk::RadioAction& current); bool on_update_resize_grip(const Gdk::EventWindowState& event); public: AppWindow(); ~AppWindow(); static void register_stock_icons(); }; //! enum { COLOR_RED, COLOR_GREEN, COLOR_BLUE }; enum { SHAPE_SQUARE, SHAPE_RECTANGLE, SHAPE_OVAL }; static const char *ui_info = "" " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " " ""; Pointer AppWindow::icon_factory; AppWindow::AppWindow() { set_title("Application Window"); set_default_size(200, 200); Gtk::Table *table = new Gtk::Table(1, 4); add(*table); // Register our stock items register_stock_icons(); // Create the menubar and toolbar action_group = new Gtk::ActionGroup("AppWindowActions"); add_actions(); manager = new Gtk::UIManager; manager->insert_action_group(*action_group); add_accel_group(manager->get_accel_group()); // Load XML description of the menus from a string. G::Error error; if (!manager->add_ui_from_string(ui_info, -1, &error)) { std::cout << "building menus failed: << " << error.message() << std::endl; } Gtk::Widget *menubar = manager->get_widget("/MenuBar"); menubar->show(); table->attach(*menubar, 0, 1, 0, 1, Gtk::EXPAND | Gtk::FILL, 0); Gtk::Toolbar *toolbar = static_cast(manager->get_widget("/ToolBar")); toolbar->set_tooltips (true); toolbar->show(); table->attach(*toolbar, 0, 1, 1, 2, Gtk::EXPAND | Gtk::FILL, 0); // Create document Gtk::ScrolledWindow *scrolled_window = new Gtk::ScrolledWindow; scrolled_window->set_policy_automatic(); scrolled_window->set_shadow_type(Gtk::SHADOW_IN); table->attach(*scrolled_window, 0, 1, 2, 3); Gtk::TextView *contents = new Gtk::TextView; contents->grab_focus(); scrolled_window->add(*contents); // Create statusbar statusbar = new Gtk::Statusbar; table->attach(*statusbar, 0, 1, 3, 4, Gtk::EXPAND | Gtk::FILL, 0); // Show text widget info in the statusbar buffer = contents->get_buffer(); buffer->signal_changed().connect(sigc::mem_fun(this, &AppWindow::update_statusbar)); buffer->signal_mark_set().connect(sigc::mem_fun(this, &AppWindow::mark_set)); signal_window_state_event().connect(sigc::mem_fun(this, &AppWindow::on_update_resize_grip)); update_statusbar(); show_all(); } AppWindow::~AppWindow() { } void AppWindow::on_activate_action(Gtk::Action *action) { String name = action->get_name(); String type_name = action->type_name(); Gtk::MessageDialog dialog(Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, this); dialog.format_message("You activated action: \"%s\" of type \"%s\"", name.c_str(), type_name.c_str()); if (dialog.run() == Gtk::RESPONSE_CLOSE) dialog.dispose(); } void AppWindow::on_activate_radio_action(Gtk::RadioAction& current) { if (current.get_active()) { String name = current.get_name(); String type_name = current.type_name(); int value = current.get_current_value(); Gtk::MessageDialog dialog(Gtk::MESSAGE_INFO, Gtk::BUTTONS_CLOSE, this); dialog.format_message("You activated radio action: \"%s\" of type \"%s\".\nCurrent value: %d", name.c_str(), type_name.c_str(), value); if (dialog.run() == Gtk::RESPONSE_CLOSE) dialog.dispose(); } } void AppWindow::update_statusbar() { statusbar->pop(); // clears any previous message int count = buffer->get_char_count(); Gtk::TextIter iter = buffer->get_iter_at_mark(*buffer->get_insert()); int row = iter.get_line(); int col = iter.get_line_offset(); String msg = String::format("Cursor at row %d column %d - %d chars in document", row, col, count); statusbar->push(msg); } void AppWindow::mark_set(const GtkTextIter*, GtkTextMark*) { update_statusbar(); } bool AppWindow::on_update_resize_grip(const Gdk::EventWindowState& event) { Gdk::WindowStateField state = Gdk::WINDOW_STATE_MAXIMIZED | Gdk::WINDOW_STATE_FULLSCREEN; if (event.changed_mask() & state) statusbar->set_has_resize_grip(!(event.new_window_state() & state)); return true; } void AppWindow::register_stock_icons() { // Register our custom toolbar icons, so they can be themed. Gtk::StockItem item("demo-gtk-logo", "_GTK!"); Gtk::Stock::add(item); // Add our custom icon factory to the list of defaults icon_factory = new Gtk::IconFactory; icon_factory->add_default(); // DemoWindow::find_file() looks in the the current directory first, then looks in the location where the file is installed. Pointer pixbuf; String filename = DemoWindow::find_file("gtk-logo-rgb.gif"); if (!filename.null()) pixbuf = Gdk::Pixbuf::create(filename); // Register icon to accompany stock item if (pixbuf) { Pointer transparent = pixbuf->add_alpha(true, 0xff, 0xff, 0xff); Pointer icon_set = new Gtk::IconSet(*transparent); icon_factory->add("demo-gtk-logo", *icon_set); } else g_warning ("failed to load GTK logo for toolbar"); } void AppWindow::add_actions() { using namespace Gtk; using namespace sigc; // Create Action entries action_group->add("FileMenu", "_File"); action_group->add("PreferencesMenu", "_Preferences"); action_group->add("ColorMenu", "_Color"); action_group->add("ShapeMenu", "_Shape"); action_group->add("HelpMenu", "_Help"); Action *action = action_group->add("New", "_New", StockId::NEW, AccelKey("N"), "Create a new file"); action->signal_activate().connect(bind(mem_fun(this, &AppWindow::on_activate_action), action)); action = action_group->add("Open", "_Open", StockId::OPEN, AccelKey("O"), "Open a file"); action->signal_activate().connect(bind(mem_fun(this, &AppWindow::on_activate_action), action)); action = action_group->add("Save", "_Save", StockId::SAVE, AccelKey("S"), "Save current file"); action->signal_activate().connect(bind(mem_fun(this, &AppWindow::on_activate_action), action)); action = action_group->add("SaveAs", "Save _As...", StockId::SAVE, "Save to a file"); action->signal_activate().connect(bind(mem_fun(this, &AppWindow::on_activate_action), action)); action = action_group->add("Quit", "_Quit", StockId::QUIT, AccelKey("Q"), "Quit"); action->signal_activate().connect(bind(mem_fun(this, &AppWindow::on_activate_action), action)); action = action_group->add("About", "_About", AccelKey("A"), "About"); action->signal_activate().connect(bind(mem_fun(this, &AppWindow::on_activate_action), action)); action = action_group->add("Logo", StockId("demo-gtk-logo"), "GTK+"); action->signal_activate().connect(bind(mem_fun(this, &AppWindow::on_activate_action), action)); // Create ToggleAction entries action = action_group->add("Bold", "_Bold", StockId::BOLD, AccelKey("B"), false, "Bold"); action->signal_activate().connect(bind(mem_fun(this, &AppWindow::on_activate_action), action)); // Create RadioAction color entries RadioActions ras; ras.add("Red", "_Red", AccelKey("R"), COLOR_RED, "Blood"), ras.add("Green", "_Green", AccelKey("G"), COLOR_GREEN, "Grass"); ras.add("Blue", "_Blue", AccelKey("B"), COLOR_BLUE, "Center justify the text"); action_group->add_actions(ras, COLOR_RED, mem_fun(this, &AppWindow::on_activate_radio_action)); // Create RadioAction shape entries ras.clear(); ras.add("Square", "_Square", AccelKey("S"), SHAPE_SQUARE, "Square"), ras.add("Rectangle", "_Rectangle", AccelKey("R"), SHAPE_RECTANGLE, "Rectangle"); ras.add("Oval", "_Oval", AccelKey("0"), SHAPE_OVAL, "Egg"); action_group->add_actions(ras, SHAPE_SQUARE, mem_fun(this, &AppWindow::on_activate_radio_action)); } Gtk::Window* do_appwindow(Gtk::Widget *do_widget) { static Gtk::Window *window = 0; if (!window) { window = new AppWindow; window->set_screen(*do_widget->get_screen()); } else { window->dispose(); window = 0; } return window; }