Fwd: How a popup window receives input fous



---------- Forwarded message ----------
From: Vesselin Jeliazkov <vveesskkoo gmail com>
Date: 03.09.2007 23:04
Subject: Re: How a popup window receives input fous
To: Murray Cumming <murrayc murrayc com>


Hello,

Here I paste the code from the calendar example but I want to explain
what I am trying to achieve.

By pressing on the arrow the user is presented a calendar with focus on
it. The user can select a date with the enter button or with a mouse
double click. In this case the date is populated in the edit widget
and the calendar is poped down.
When the calendar looses its focus without selecting anything (by
pressing with the mouse somewhere else or pressing escape key) then
the popup window is hidden and no date is populated.

I tried to set_modal(true) but does not make sense to me because I do not
want to forse the user to select a date.

The modifications are commented. You can quickly find the differences
if you know the calendar example.

version: gtkmm-2.10.10

Vesselin

#include <gtkmm.h>
#include <iostream>


enum { DEF_PAD = 10 };
enum { DEF_PAD_SMALL = 5 };

enum { TM_YEAR_BASE = 1900 };

class CalendarExample : public Gtk::Window
{

public:
  CalendarExample();
  virtual ~CalendarExample();

  void set_flags();
  void font_selection_ok();
  void select_font();
  void toggle_flag(Gtk::CheckButton *toggle);

  void month_changed();
  void day_selected();
  void day_selected_double_click();

protected:
  Gtk::CheckButton* flag_checkboxes_[5];
  bool                          settings_[5];

  // new code here
  Gtk::HBox             _hbox;
  Gtk::Entry            _entry;
  Gtk::ToggleButton     _tgbtn;
  Gtk::Window           _wnd_popup;

  void          on_button_toggled();
  // end of new code

  Gtk::FontSelectionDialog* font_dialog_;
  Gtk::Calendar* calendar_;
  Gtk::Label* label_selected_;
  Gtk::Label* label_selected_double_click_;
  Gtk::Label* label_month_;

  Glib::Date get_date() const;
};

CalendarExample::~CalendarExample()
{
  for (int i = 0; i < 5; i++)
  {
          delete flag_checkboxes_[i];
  }

  delete calendar_;
  delete label_selected_;
  delete label_selected_double_click_;
  delete label_month_;
}

/*
 * GtkCalendar
 */

void CalendarExample::month_changed()
{
  label_month_->set_text(get_date().format_string("%x"));
}

void CalendarExample::day_selected()
{
  label_selected_->set_text(get_date().format_string("%x"));
}

void CalendarExample::day_selected_double_click()
{
  label_selected_double_click_->set_text(get_date().format_string("%x"));
}

void CalendarExample::set_flags()
{
  int options = 0;

  for (int i = 0; i < 5; i++)
  {
    if (settings_[i])
    {
      options = options + (1 << i);
    }
  }

  if (calendar_)
    calendar_->set_display_options((Gtk::CalendarDisplayOptions)options);
}

void CalendarExample::toggle_flag(Gtk::CheckButton *toggle)
{
  int j = 0;
  for (int i = 0; i < 5; i++)
    if (flag_checkboxes_[i] == (Gtk::CheckButton *)toggle)
      j = i;

  settings_[j] = !settings_[j];
  set_flags();
}

void CalendarExample::font_selection_ok()
{
  if(calendar_)
  {
    Glib::ustring font_name = font_dialog_->get_font_name();
    if (!font_name.empty())
    {
        calendar_->modify_font(Pango::FontDescription(font_name));
    }
  }
}


void CalendarExample::select_font()
{
  if (!font_dialog_)
  {
    font_dialog_  = new Gtk::FontSelectionDialog("Font Selection Dialog");
    font_dialog_->set_position(Gtk::WIN_POS_MOUSE);
    font_dialog_->get_ok_button()->signal_clicked().connect(sigc::mem_fun(*this,
&CalendarExample::font_selection_ok));
    //font_dialog_->get_cancel_button()->signal_clicked.connect(sigc::bind(sigc::mem_fun(this,
&CalendarExample::destroy_widget), font_dialog_));
  }

  if (!font_dialog_->is_visible())
    font_dialog_->show();
  else
  {
    delete font_dialog_;
    font_dialog_ = 0;
  }
}

        // new code here
        void
        CalendarExample::on_button_toggled()
        {
                if (_tgbtn.get_active()) {
                        //popup();
                        int     x, y, w, h, d;

                        _entry.get_window()->get_geometry(x, y, w, h, d);
                        _entry.get_window()->get_origin(x, y);
                        _wnd_popup.move(x, y + h);
                        _wnd_popup.show_all_children();
                        _wnd_popup.present();
                        _wnd_popup.grab_focus();
                }
                else {
                        //popdown();
                        _tgbtn.set_active(false);
                        _wnd_popup.hide();
                }
        }
        // end of new code

CalendarExample::CalendarExample():
   _wnd_popup(Gtk::WINDOW_POPUP)
{
  font_dialog_ = NULL;

  for (int i = 0; i < 5; i++) {
    settings_[i] = 0;
  }

  set_border_width(5);

  set_resizable(false);

  Gtk::VBox* vbox = Gtk::manage(new Gtk::VBox(false, DEF_PAD));
  add(*vbox);

  /*
   * The top part of the CalendarExample, flags and fontsel.
   */

  Gtk::HBox* hbox = Gtk::manage(new Gtk::HBox(false, DEF_PAD));
  vbox->pack_start(*hbox, Gtk::PACK_EXPAND_WIDGET, DEF_PAD);
  Gtk::HButtonBox* hbbox = Gtk::manage(new Gtk::HButtonBox());
  hbox->pack_start(*hbbox, Gtk::PACK_SHRINK, DEF_PAD);
  hbbox->set_layout(Gtk::BUTTONBOX_SPREAD);
  hbbox->set_spacing(5);

  /* Calendar widget */
  Gtk::Frame* frame = Gtk::manage(new Gtk::Frame("Calendar"));
  hbbox->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET, DEF_PAD);
  calendar_ = new Gtk::Calendar();
  set_flags();
  calendar_->mark_day(19);

  // new code here
  _entry.set_max_length(10);
  _tgbtn.add(*Gtk::manage(new Gtk::Arrow(Gtk::ARROW_DOWN, Gtk::SHADOW_NONE)));
  _hbox.pack_start(_entry);
  _hbox.pack_start(_tgbtn);

  _wnd_popup.add(*calendar_);
  //_wnd_popup.set_modal(true);
  _wnd_popup.set_transient_for(*this/*parent*/);
  _tgbtn.signal_toggled().connect(sigc::mem_fun(*this,
&CalendarExample::on_button_toggled));
  //frame->add(*calendar_);
  frame->add(_hbox);
  // end of new code

  calendar_->signal_month_changed().connect(sigc::mem_fun(*this,
&CalendarExample::month_changed));
  calendar_->signal_day_selected().connect(sigc::mem_fun(*this,
&CalendarExample::day_selected));
  calendar_->signal_day_selected_double_click().connect(sigc::mem_fun(*this,
&CalendarExample::day_selected_double_click));

  Gtk::VSeparator* separator = Gtk::manage(new Gtk::VSeparator());
  hbox->pack_start (*separator, Gtk::PACK_SHRINK);

  Gtk::VBox* vbox2 = Gtk::manage(new Gtk::VBox(false, DEF_PAD));
  hbox->pack_start(*vbox2, Gtk::PACK_SHRINK, DEF_PAD);

  /* Build the Right frame with the flags in */

  Gtk::Frame* frameFlags = Gtk::manage(new Gtk::Frame("Flags"));
  vbox2->pack_start(*frameFlags, Gtk::PACK_EXPAND_WIDGET, DEF_PAD);
  Gtk::VBox* vbox3 = Gtk::manage(new Gtk::VBox(true, DEF_PAD_SMALL));
  frameFlags->add(*vbox3);

  struct {
    char *label;
  } flags[] =
    {
      { "Show Heading" },
      { "Show Day Names" },
      { "No Month Change" },
      { "Show Week Numbers" },
      { "Week Start Monday" }
    };

  for (int i = 0; i < 5; i++)
  {
    Gtk::CheckButton* toggle = new Gtk::CheckButton(flags[i].label);
    toggle->signal_toggled().connect(sigc::bind(sigc::mem_fun(*this,
&CalendarExample::toggle_flag), toggle));
    vbox3->pack_start(*toggle);
    flag_checkboxes_[i] = toggle;
  }

  /* Build the right font-button */
  Gtk::Button* button = Gtk::manage(new Gtk::Button("Font..."));
  button->signal_clicked().connect(sigc::mem_fun(*this,
&CalendarExample::select_font));
  vbox2->pack_start (*button, Gtk::PACK_SHRINK);

  /*
   *  Build the Signal-event part.
   */

  frame = Gtk::manage(new Gtk::Frame("Signal events"));
  vbox->pack_start(*frame, Gtk::PACK_EXPAND_WIDGET, DEF_PAD);
  vbox2 = Gtk::manage(new Gtk::VBox(true, DEF_PAD_SMALL));
  frame->add(*vbox2);

  hbox = Gtk::manage(new Gtk::HBox(false, 5));
  vbox2->pack_start (*hbox, Gtk::PACK_SHRINK);
  Gtk::Label* label = Gtk::manage(new Gtk::Label("Day selected:"));
  hbox->pack_start (*label, Gtk::PACK_SHRINK);
  label_selected_ = new Gtk::Label("");
  hbox->pack_start (*label_selected_, Gtk::PACK_SHRINK);

  hbox = Gtk::manage(new Gtk::HBox(false, 5));
  vbox2->pack_start (*hbox, Gtk::PACK_SHRINK);
  label = Gtk::manage(new Gtk::Label("Day selected double click:"));
  hbox->pack_start (*label, Gtk::PACK_SHRINK);
  label_selected_double_click_ = new Gtk::Label("");
  hbox->pack_start (*label_selected_double_click_, Gtk::PACK_SHRINK);

  hbox = Gtk::manage(new Gtk::HBox(false, 5));
  vbox2->pack_start (*hbox, Gtk::PACK_SHRINK);
  label = Gtk::manage(new Gtk::Label("Month change:"));
  hbox->pack_start (*label, Gtk::PACK_SHRINK);
  label_month_ = new Gtk::Label("");
  hbox->pack_start(*label_month_, Gtk::PACK_SHRINK);

  Gtk::HButtonBox* bbox = Gtk::manage(new Gtk::HButtonBox());
  vbox->pack_start(*bbox, Gtk::PACK_SHRINK);
  bbox->set_layout(Gtk::BUTTONBOX_END);

  button = Gtk::manage(new Gtk::Button("Close"));
  button->signal_clicked().connect(&Gtk::Main::quit);
  bbox->add(*button);
  button->set_flags(Gtk::CAN_DEFAULT);
  button->grab_default();

  show_all();
}

Glib::Date CalendarExample::get_date() const
{
  using Glib::Date;

  unsigned int year = 0, month = 0, day = 0;
  calendar_->get_date(year, month, day);

  return Date(Date::Day(day), Date::Month(Date::JANUARY + month),
Date::Year(year));
}


int main(int argc, char** argv)
{
  Gtk::Main myapp(&argc, &argv);
  CalendarExample calendar;
  Gtk::Main::run(calendar);
  return 0;
}


2007/9/3, Murray Cumming <murrayc murrayc com>:
>
> On Mon, 2007-09-03 at 01:17 +0300, Vesselin Jeliazkov wrote:
> > Hello,
> >
> > I want to place a calendar (Gtk::Calendar) in a popup window. The
> > popup window is made modal and is presented to the user with the
> > Gtk::Window::present() call.
> >  Dates from the calendar can be selected
> > with the mouse but the calendar does not have the input focus - dates
> > can not be choosen with the keyboard. The keyboard focus stays on the
> > parent window.
>
> Could you show this with a small test case, maybe modifying the
> examples/calendar/ example?
>
> Have you used set_transient_for()?
>
> > How can I make the calendar to receive the input focus from the keyboard?
> >
> > If the calendar is not modal (Gtk::Window::set_modal() has not been
> > called) then no date from the calendar can be selected witrh the mouse
> > as well.
> >
> > I tried to activate the keyboard and mose events for the popup window
> > but it doesn't work.
>
> --
> murrayc murrayc com
> www.murrayc.com
> www.openismus.com
>
>



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]