ポップアップメニューの位置を指定する

概要

ポップアップメニューの位置を指定する。

Gtk::Menu::popup()によってポップアップメニューを表示すると通常はマウスポインタの下に メニューを表示するが、好きな位置に表示したい場合はGtk::Menu::popup()の引数に スロット関数を指定してその関数の中で座標を指定する。例えば

void slot_position_calc( int& x, int& y, bool& push_in );

という関数を用意しておくとポップアップメニューが表示される直前に関数が 呼び出されるので、その時にx,y,push_inに値をセットしておく。ここでx,yは座標であり、 push_inがtrueの時はメニューが画面内に収まるように座標が自動調整される。

ソース

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

class MainWin : public Gtk::Window
{
    Glib::RefPtr< Gtk::ActionGroup > m_actiongroup;
    Glib::RefPtr< Gtk::UIManager > m_uimanager;

public:
    MainWin();

private:
    void on_popupmenu_test();
    void slot_position_calc(int& x, int& y, bool& push_in);

protected:
    virtual bool on_button_press_event( GdkEventButton* event );
};

MainWin::MainWin()
{
    // OFFになってるイベントを追加
    add_events( Gdk::BUTTON_PRESS_MASK );

    // アクショングループの作成とアクション登録
    m_actiongroup = Gtk::ActionGroup::create();
    m_actiongroup->add( Gtk::Action::create( "MenuTitle", "メニュー" ) );
    m_actiongroup->add( Gtk::Action::create( "TestMenu", "テスト"), sigc::mem_fun( *this, &MainWin::on_popupmenu_test ) );    

    // UIマネージャの作成とアクショングループ挿入
    m_uimanager = Gtk::UIManager::create();
    m_uimanager->insert_action_group( m_actiongroup );

    // ポップアップメニューのレイアウト
    Glib::ustring ui_info = 
        "<ui>"
 
        "<popup name='PopupMenu' >"
        "<menuitem action='MenuTitle'/>"
        "<menuitem action='TestMenu'/>"
        "</popup>"
 
        "</ui>";
 
    m_uimanager->add_ui_from_string(ui_info);
}


// マウスクリック
bool MainWin::on_button_press_event( GdkEventButton* event )
{
    Gtk::Menu* popupmenu = dynamic_cast< Gtk::Menu* >( m_uimanager->get_widget( "/PopupMenu" ) );
    popupmenu->popup( sigc::mem_fun( *this, &MainWin::slot_position_calc ), event->button, event->time );

    return true;
}


// シグナルハンドラ
void MainWin::on_popupmenu_test()
{
    std::cout << "ok\n";
}


// ポップアップメニューの位置決め用関数
void MainWin::slot_position_calc( int& x, int& y, bool& push_in )
{
    get_window()->get_root_origin( x, y );
    push_in = false;
}


int main( int argc, char *argv[] )
{
    Gtk::Main kit( argc, argv );
    MainWin mainwin;
    Gtk::Main::run( mainwin );

    return 0;
}

コンパイル

必要なコンパイルオプションは pkg-config を使って取得する。

g++ pmenu2.cpp -o pmenu2 `pkg-config gtkmm-2.4 --cflags --libs`

結果