Re: Connecting to Configure signal event



On 11/27/2013 12:59 PM, Kjell Ahlstedt wrote:

2013-11-26 22:37, a skrev:
On 11/26/2013 08:33 AM, Kjell Ahlstedt wrote:

2013-11-26 05:09, a skrev:
Hi,

I'm trying to connect to the configure signal event(signal_configure_event()), in the documentation I read that you have to enable Gdk::STRUCTURE_MASK, and I think that is the problem I am having. I tried do it several different ways, like this:

this->add_events(Gdk::STRUCTURE_MASK);
Gtk::Window::add_events(Gdk::STRUCTURE_MASK);
MainWindow::add_events(Gdk::STRUCTURE_MASK); //I think they are all synonyms, but just in case they weren't

and I tried using set_events() function too. Is this the correct way to enable STRUCTURE_MASK?

Thank you.

Tim O.
Have you read https://developer.gnome.org/gtkmm-tutorial/stable/sec-xeventsignals.html.en#signal-handler-sequence and added an after = false parameter in your call to signal_configure_event().connect()?

Kjell

Thank you for the link, but I recently just read that using the configure signal could have performance problems, and I read in an old mailing list that signal_expose_event should be used, which is now signal_draw. So instead I was thinking of using signal_size_allocate. Because all I really want is just the window's size. So which one of these would have better for getting the window's size and then increases a Gtk::Entry width. Thank you.

Tim O.
Is this a continuation of your question in https://mail.gnome.org/archives/gtkmm-list/2013-November/msg00070.html ?
I made a small test with the example program in https://git.gnome.org/browse/gtkmm-documentation/tree/examples/book/entry/simple?h=master
I changed the vertical box to a horizontal box. The Entry widget expands with the window if it's added to the box with pack_start(m_Entry, Gtk::PACK_EXPAND_WIDGET). If you want the Entry to get all extra space, you should add other widgets to the box with Gtk::PACK_SHRINK.

If you can't get this to work, can you post a small program here on the mailing list? A program that does not behave the way you want, when its window is expanded.

Kjell
Here is how I solved it the problem, probably not the best way, but it works kind of:

//mainwindow.h
class MainWindow : public Gtk::Window
{
public:
    MainWindow();
    virtual ~MainWindow();
   
protected:
    bool txtChange(GdkEventKey*, Gtk::Entry&, bool override = false);
    void txtDelete(int start_pos, int end_pos, Gtk::Entry&, bool override = false);
    void boxMainChange(Gtk::Allocation&);
   
    Gtk::Box box_main_, box_split_, box_ans_, box_exp_;
    Gtk::Label lbl_exp_, lbl_ans_;
    Gtk::Entry txt_exp_, txt_ans_;
   
private:
    inline int charToPixals(int chars) const;
    int getSize(int diff);
    inline int txt_length_to_pix(int txt_length) const;
   
    const int default_txtbox_size_;
    static constexpr int kchar_limit_ = 20;
    static constexpr int kavg_char_size = 2;
    static constexpr int kchars_width_ = 4;
   
    int win_width_;
};

//mainwinoh.cc
MainWindow::MainWindow() : default_txtbox_size_(txt_exp_.get_allocated_width())
{   
    Gtk::Window::set_default_size(400, 320);
    //box_main
    box_main_.set_orientation(Gtk::ORIENTATION_VERTICAL);
   
    //box_split
    box_split_.set_orientation(Gtk::ORIENTATION_VERTICAL);
   
    //box_exp
    box_exp_.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
    box_exp_.set_halign(Gtk::ALIGN_CENTER);
    box_exp_.set_margin_top(30);
    box_exp_.set_margin_bottom(30);
   
    //box_ans
    box_ans_.set_orientation(Gtk::ORIENTATION_HORIZONTAL);
    box_ans_.set_halign(Gtk::ALIGN_CENTER);
    box_ans_.set_margin_bottom(30);
   
    //lbl_exp
    lbl_exp_.set_text("_expression_: ");
    lbl_exp_.set_margin_right(5);
   
    //lbl_ans
    lbl_ans_.set_text("Answer: ");
    lbl_ans_.set_margin_right(5);
   
    //Setup MainWindow
    Gtk::Window::add(box_main_);

    box_main_.pack_start(box_split_);
   
    box_split_.pack_start(box_exp_);
    box_split_.pack_start(box_ans_);
   
    box_exp_.pack_start(lbl_exp_);
    box_exp_.pack_start(txt_exp_);
   
    box_ans_.pack_start(lbl_ans_);
    box_ans_.pack_start(txt_ans_);

    //update txtbox size
    txt_exp_.signal_key_press_event().connect(sigc::bind<Gtk::Entry&, bool>(sigc::mem_fun(*this, &MainWindow::txtChange), txt_exp_, true), false);
    txt_exp_.signal_delete_text().connect(sigc::bind<Gtk::Entry&, bool>(sigc::mem_fun(*this, &MainWindow::txtDelete), txt_exp_, true));
   
    //txt_ans_.signal_changed()
    txt_ans_.signal_delete_text().connect(sigc::bind<Gtk::Entry&, bool>(sigc::mem_fun(*this, &MainWindow::txtDelete), txt_ans_, false));
    txt_ans_.signal_key_press_event().connect(sigc::bind<Gtk::Entry&, bool>(sigc::mem_fun(*this, &MainWindow::txtChange), txt_ans_, false), false);
   
    //increases txt box size when window size is increased
    signal_size_allocate().connect(sigc::mem_fun(*this, &MainWindow::boxMainChange));
   
    MainWindow::show_all_children();
}

MainWindow::~MainWindow()
{
}

inline int MainWindow::charToPixals(int chars) const
{
    return kavg_char_size * chars;
}

bool MainWindow::txtChange(GdkEventKey* key, Gtk::Entry& entry, bool override)
{
    if(key->keyval == 65288) //Gdk number for backspace
        return false;
   
    int txt_length = entry.get_text_length();
    int txtl_p = txt_length_to_pix(txt_length);
   
    if(entry.get_allocated_width() > txtl_p) //txtbox is big enough already from Mainwindow
        return false;
   
    if(txt_length < kchar_limit_)
        return false;
   
    if(override)
        txt_ans_.set_size_request(entry.get_width() + charToPixals(kchars_width_), -1);
   
    entry.set_size_request(entry.get_width() + charToPixals(kchars_width_), -1);
   
    return false;
}

void MainWindow::txtDelete(int start_pos, int end_pos, Gtk::Entry& entry, bool override)
{
    int txt_length = entry.get_text_length();
       
    if(txt_length < kchar_limit_)
        return;
       
    if(override)
        txt_ans_.set_size_request(entry.get_width() - charToPixals(kchars_width_), -1);
   
    entry.set_size_request(entry.get_width() - charToPixals(kchars_width_), -1);
       
    if(txt_length < kchar_limit_)
        entry.set_size_request(default_txtbox_size_, -1);
}
int MainWindow::getSize(int diff)
{
    if(diff == 1)
        return 1;
    else if(diff < 6)
        return 2;
    else if(diff < 11)
        return 3;
    else if(diff < 21)
        return 10;
    else if(diff < 31)
        return 25;
    else if(diff < 41)
        return 35;
    else if(diff < 51)
        return 40;
    else
        return 60;
   
}

inline int MainWindow::txt_length_to_pix(int txt_length) const
{
    return txt_length * 10;
}

void MainWindow::boxMainChange(Gtk::Allocation& a)
{
    if(txt_length_to_pix(txt_exp_.get_text_length()) > txt_exp_.get_width())
        return;
   
    if(win_width_ < get_width())
    {
        txt_exp_.set_size_request(txt_exp_.get_width() + getSize(a.get_width() - win_width_), -1);
        txt_ans_.set_size_request(txt_ans_.get_width() + getSize(a.get_width() - win_width_), -1);
        win_width_ = a.get_width();
    }
    else if (win_width_ > get_width())
    {
        txt_exp_.set_size_request(txt_exp_.get_width() - getSize(win_width_ - a.get_width()), -1);
        txt_ans_.set_size_request(txt_ans_.get_width() - getSize(win_width_ - a.get_width()), -1);
        win_width_ = a.get_width();
    }
   
    //return false;
}


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