差分
このページの2つのバージョン間の差分を表示します。
| 次のリビジョン | 前のリビジョン | ||
| fltk:widget-basic-menus [2025/05/30 14:21] – 作成 freemikan | fltk:widget-basic-menus [2025/06/14 12:25] (現在) – [Fl_Menu_Buttonクラス] Write body text freemikan | ||
|---|---|---|---|
| 行 1: | 行 1: | ||
| - | ====== | + | ====== |
| - | {{: | + | [[fltk:|{{: |
| 行 19: | 行 19: | ||
| 具体的な用途によって、Fl_Menu_Barクラス、Fl_Menu_Buttonクラス、Fl_Choiceクラスが派生クラスとして提供されています。 | 具体的な用途によって、Fl_Menu_Barクラス、Fl_Menu_Buttonクラス、Fl_Choiceクラスが派生クラスとして提供されています。 | ||
| + | [[https:// | ||
| + | <WRAP centeralign> | ||
| - | Fl_Menuクラス前後の階層図 | ||
| - | {{ https:// | ||
| + | ==== Fl_Menu_Barクラス ==== | ||
| + | [[https:// | ||
| + | <WRAP centeralign> | ||
| + | |||
| + | |||
| + | 典型的なGUIアプリケーションで目にする、ウィンドウ最上部のメニューバーを実現するためのクラスです。 | ||
| + | FLTKではメニューバーもやはりウィジェットです。 | ||
| + | サイズや位置を設定することができるので、必ずしもウィンドウの最上部に配置しなければならないことはありません。 | ||
| + | この自由度は一方であまり直感的とは言えない使い方が求められます。 | ||
| + | 例えば、次のようなことが考えられます。 | ||
| + | |||
| + | * メニューバーの初期サイズにウィンドウのサイズと同じだけの幅とUIフォントのサイズを考慮した高さを与えることが必須である。 | ||
| + | * ユーザーがマウスでウィンドウの枠をドラッグしてサイズを変更したときにメニューバーが縦に拡大されることを回避するよう配慮しないといけない。 | ||
| + | |||
| + | 次のサンプルプログラムでは、メニューバーの構築方法と、ウィンドウのサイズ変更に対して自然な振る舞いになるようにする方法を示しています。 | ||
| + | |||
| + | <code cpp> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | #include < | ||
| + | |||
| + | void file_open_cb(Fl_Widget *w, void *data) { | ||
| + | if (auto file_name = fl_file_chooser(" | ||
| + | printf(" | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void file_quit_cb(Fl_Widget *w, void *data) { | ||
| + | if (fl_choice_n(" | ||
| + | Fl:: | ||
| + | } | ||
| + | } | ||
| + | |||
| + | void edit_undo_cb(Fl_Widget *w, void *data) { /* TODO */ } | ||
| + | void edit_redo_cb(Fl_Widget *w, void *data) { /* TODO */ } | ||
| + | void edit_cut_cb(Fl_Widget *w, void *data) { /* TODO */ } | ||
| + | void edit_copy_cb(Fl_Widget *w, void *data) { /* TODO */ } | ||
| + | void edit_paste_cb(Fl_Widget *w, void *data) { /* TODO */ } | ||
| + | |||
| + | void help_help_cb(Fl_Widget *w, void *data) { | ||
| + | fl_message(" | ||
| + | } | ||
| + | |||
| + | void help_about_cb(Fl_Widget *w, void *data) { | ||
| + | fl_message(" | ||
| + | } | ||
| + | |||
| + | int main(int argc, char **argv) { | ||
| + | auto window = new Fl_Window{400, | ||
| + | |||
| + | auto menu_bar = new Fl_Menu_Bar{0, | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | menu_bar-> | ||
| + | |||
| + | // マウスでドラッグしてウィンドウのサイズを変更できるようにする | ||
| + | // ただし、メニューバーの高さは変化しないようにする | ||
| + | // メニューバーの領域を含めないことがポイント | ||
| + | auto group = new Fl_Group{0, menu_bar-> | ||
| + | group-> | ||
| + | window-> | ||
| + | |||
| + | window-> | ||
| + | window-> | ||
| + | |||
| + | // https:// | ||
| + | for (int t = 0; t < menu_bar-> | ||
| + | const Fl_Menu_Item &item = menu_bar-> | ||
| + | fprintf(stderr, | ||
| + | item.label() ? item.label() : " | ||
| + | (item.flags & FL_MENU_VALUE) ? " | ||
| + | (item.flags & FL_SUBMENU) ? " | ||
| + | } | ||
| + | |||
| + | return Fl::run(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ==== Fl_Menu_Buttonクラス ==== | ||
| + | [[https:// | ||
| + | <WRAP centeralign> | ||
| + | |||
| + | Fl_Menu_Buttonクラスのウィジェットは、クリックすると選択項目が表示されるドロップダウン形式のボタンです。 | ||
| + | また、メンバ関数type()でポップアップのタイプを設定することによってポップアップメニューとして利用できます。 | ||
| + | これによって、多くのGUIアプリケーションやウィンドウシステムが採用している典型的な右クリックメニューを実現できます。 | ||
| + | |||
| + | <code cpp> | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | #include < | ||
| + | |||
| + | #include < | ||
| + | |||
| + | // ダミーのコールバック | ||
| + | void the_cb(Fl_Widget *w, void *data) {} | ||
| + | void strange_cb(Fl_Widget *w, void *data) {} | ||
| + | void charm_cb(Fl_Widget *w, void *data) {} | ||
| + | void truth_cb(Fl_Widget *w, void *data) {} | ||
| + | void beauty_cb(Fl_Widget *w, void *data) {} | ||
| + | |||
| + | int main(int argc, char **argv) { | ||
| + | auto window = new Fl_Window{400, | ||
| + | |||
| + | // https:// | ||
| + | Fl_Menu_Item menu_table[] = {{"& | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | {0}, | ||
| + | | ||
| + | | ||
| + | | ||
| + | | ||
| + | {0}}; | ||
| + | |||
| + | // ドロップダウンタイプのボタン | ||
| + | auto menu_button = new Fl_Menu_Button{10, | ||
| + | menu_button-> | ||
| + | |||
| + | // 右クリックで表示されるポップアップメニュー | ||
| + | // ボタンの位置とサイズがクリックの有効範囲となる | ||
| + | auto menu_popup = new Fl_Menu_Button{0, | ||
| + | menu_popup-> | ||
| + | menu_popup-> | ||
| + | |||
| + | window-> | ||
| + | window-> | ||
| + | |||
| + | // https:// | ||
| + | for (int t = 0; t < menu_button-> | ||
| + | const Fl_Menu_Item &item = menu_button-> | ||
| + | fprintf(stderr, | ||
| + | item.label() ? item.label() : " | ||
| + | (item.flags & FL_MENU_VALUE) ? " | ||
| + | (item.flags & FL_SUBMENU) ? " | ||
| + | } | ||
| + | |||
| + | return Fl::run(); | ||
| + | } | ||
| + | </ | ||
