Custom Dialog

When none of the predefined dialog classes suit your needs, you can make your own dialog by deriving a class from Window and fill it with the widgets you need.

Window Reference

Example

Figure 17.6. Window Dialog

Window Dialog

Source Code

File: examplewindow.h (For use with gtkmm 4)

#ifndef GTKMM_EXAMPLEWINDOW_H
#define GTKMM_EXAMPLEWINDOW_H

#include <gtkmm.h>
#include "namedialog.h"

class ExampleWindow : public Gtk::Window
{
public:
  ExampleWindow();
  ~ExampleWindow() override;

protected:
  //Signal handlers:
  void on_button_clicked();
  void on_dialog_response(const Glib::ustring& response);
  void on_dialog_hidden();

  //Child widgets:
  Gtk::Button m_Button;

  NameDialog m_Dialog;
};

#endif //GTKMM_EXAMPLEWINDOW_H

File: namedialog.h (For use with gtkmm 4)

#ifndef GTKMM_NAME_DIALOG_H_
#define GTKMM_NAME_DIALOG_H_

#include <gtkmm.h>

class NameDialog : public Gtk::Window
{
public:
  NameDialog();
  ~NameDialog() override;

  void buttons_clicked_connect(const sigc::slot<void(const Glib::ustring&)>& slot);
  Glib::ustring get_entry1() const;
  Glib::ustring get_entry2() const;

protected:
  //Member widgets:
  Gtk::Grid m_Grid;
  Gtk::Image m_Image;
  Gtk::Label m_Label1;
  Gtk::Label m_Label2;
  Gtk::Entry m_Entry1;
  Gtk::Entry m_Entry2;
  Gtk::Box m_ButtonBox;
  Gtk::Button m_Button_OK;
  Gtk::Button m_Button_Cancel;
};

#endif /* GTKMM_NAME_DIALOG_H_ */

File: examplewindow.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <iostream>

ExampleWindow::ExampleWindow()
: m_Button("Show Dialog"),
  m_Dialog()
{
  set_title("Custom Dialog example");

  set_child(m_Button);
  m_Button.signal_clicked().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_button_clicked));

  m_Dialog.set_default_size(250, 100);
  m_Dialog.set_transient_for(*this);
  m_Dialog.set_modal();
  m_Dialog.set_hide_on_close();
  m_Dialog.buttons_clicked_connect(
    sigc::mem_fun(*this, &ExampleWindow::on_dialog_response));
  m_Dialog.signal_hide().connect(
    sigc::mem_fun(*this, &ExampleWindow::on_dialog_hidden));
}

ExampleWindow::~ExampleWindow()
{
}

void ExampleWindow::on_button_clicked()
{
  m_Dialog.set_visible(true);
}

void ExampleWindow::on_dialog_response(const Glib::ustring& response)
{
  m_Dialog.set_visible(false);

  if (response == "OK")
    std::cout << "Name: " << m_Dialog.get_entry1() << " "
      << m_Dialog.get_entry2() << std::endl; 
  else
    std::cout << response << " button clicked" << std::endl;
}

void ExampleWindow::on_dialog_hidden()
{
  std::cout << "Dialog hidden" << std::endl;
}

File: main.cc (For use with gtkmm 4)

#include "examplewindow.h"
#include <gtkmm/application.h>

int main(int argc, char *argv[])
{
  auto app = Gtk::Application::create("org.gtkmm.example");

  //Shows the window and returns when it is closed.
  return app->make_window_and_run<ExampleWindow>(argc, argv);
}

File: namedialog.cc (For use with gtkmm 4)

NameDialog::NameDialog()
: m_Label1("_First name", true),
  m_Label2("_Second name", true),
  m_ButtonBox(Gtk::Orientation::HORIZONTAL, 5),
  m_Button_OK("_OK", true),
  m_Button_Cancel("_Cancel", true)
{
  set_destroy_with_parent(true);

  set_title("Name Dialog");
  set_child(m_Grid);

  m_Grid.set_row_spacing(4);
  m_Grid.set_column_spacing(4);
  m_Grid.set_expand(true);

  m_Image.set_from_icon_name("dialog-question");
  m_Image.set_icon_size(Gtk::IconSize::LARGE);
  m_Grid.attach(m_Image, 0, 0, 1, 2);

  m_Grid.attach(m_Label1, 1, 0);
  m_Grid.attach(m_Entry1, 2, 0);
  m_Label1.set_mnemonic_widget(m_Entry1);

  m_Grid.attach(m_Label2, 1, 1);
  m_Grid.attach(m_Entry2, 2, 1);
  m_Label2.set_mnemonic_widget(m_Entry2);

  m_Grid.attach(m_ButtonBox, 0, 2, 3, 1);
  m_ButtonBox.set_halign(Gtk::Align::END);
  m_ButtonBox.append(m_Button_OK);
  m_ButtonBox.append(m_Button_Cancel);
}

void NameDialog::buttons_clicked_connect(
  const sigc::slot<void(const Glib::ustring&)>& slot)
{
  m_Button_OK.signal_clicked().connect(sigc::bind(slot, "OK"));
  m_Button_Cancel.signal_clicked().connect(sigc::bind(slot, "Cancel"));
}

Glib::ustring NameDialog::get_entry1() const
{
  return m_Entry1.get_text();
}

Glib::ustring NameDialog::get_entry2() const
{
  return m_Entry2.get_text();
}

NameDialog::~NameDialog()
{
}