mirror of https://github.com/fltk/fltk
297 lines
9.7 KiB
C++
297 lines
9.7 KiB
C++
//
|
|
// Menubar test program for the Fast Light Tool Kit (FLTK).
|
|
//
|
|
// Copyright 1998-2023 by Bill Spitzak and others.
|
|
//
|
|
// This library is free software. Distribution and use rights are outlined in
|
|
// the file "COPYING" which should have been included with this file. If this
|
|
// file is missing or damaged, see the license at:
|
|
//
|
|
// https://www.fltk.org/COPYING.php
|
|
//
|
|
// Please see the following page on how to report bugs and issues:
|
|
//
|
|
// https://www.fltk.org/bugs.php
|
|
//
|
|
|
|
#include <FL/Fl.H>
|
|
#if defined(__APPLE__) && !(defined(FLTK_USE_X11) || defined(FLTK_USE_WAYLAND))
|
|
# define HAS_MAC_APP_MENU 1
|
|
#endif
|
|
#ifdef HAS_MAC_APP_MENU
|
|
# include <FL/platform.H> // for Fl_Mac_App_Menu
|
|
#endif
|
|
#include <FL/Fl_Box.H>
|
|
#include <FL/Fl_Double_Window.H>
|
|
#include <FL/Fl_Sys_Menu_Bar.H>
|
|
#include <FL/Fl_Toggle_Button.H>
|
|
#include <FL/Fl_Menu_Button.H>
|
|
#include <FL/Fl_Scheme_Choice.H>
|
|
#include <FL/Fl_Value_Slider.H>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <FL/fl_draw.H>
|
|
#include <FL/Fl_Terminal.H>
|
|
#include <FL/fl_ask.H>
|
|
#include <FL/fl_string_functions.h>
|
|
|
|
#define TERMINAL_HEIGHT 120
|
|
|
|
// Globals
|
|
Fl_Terminal *G_tty = 0;
|
|
|
|
void window_cb(Fl_Widget* w, void*) {
|
|
puts("window callback called"); // end of program, so stdout instead of G_tty
|
|
((Fl_Double_Window *)w)->hide();
|
|
}
|
|
|
|
void test_cb(Fl_Widget* w, void*) {
|
|
Fl_Menu_* mw = (Fl_Menu_*)w;
|
|
const Fl_Menu_Item* m = mw->mvalue();
|
|
if (!m)
|
|
G_tty->printf("NULL\n");
|
|
else if (m->shortcut())
|
|
G_tty->printf("%s - %s\n", m->label(), fl_shortcut_label(m->shortcut()));
|
|
else
|
|
G_tty->printf("%s\n", m->label());
|
|
}
|
|
|
|
void quit_cb(Fl_Widget*, void*) {exit(0);}
|
|
|
|
Fl_Menu_Item hugemenu[100];
|
|
|
|
Fl_Menu_Item menutable[] = {
|
|
{"foo",0,0,0,FL_MENU_INACTIVE},
|
|
{"&File",0,0,0,FL_SUBMENU},
|
|
{"&Open", FL_ALT+'o', 0, 0, FL_MENU_INACTIVE},
|
|
{"&Close", 0, 0},
|
|
{"&Quit", FL_ALT+'q', quit_cb, 0, FL_MENU_DIVIDER},
|
|
{"shortcut",'a'},
|
|
{"shortcut",FL_SHIFT+'a'},
|
|
{"shortcut",FL_CTRL+'a'},
|
|
{"shortcut",FL_CTRL+FL_SHIFT+'a'},
|
|
{"shortcut",FL_ALT+'a'},
|
|
{"shortcut",FL_ALT+FL_SHIFT+'a'},
|
|
{"shortcut",FL_ALT+FL_CTRL+'a'},
|
|
{"shortcut",FL_ALT+FL_SHIFT+FL_CTRL+'a', 0,0, FL_MENU_DIVIDER},
|
|
{"shortcut",'\r'/*FL_Enter*/},
|
|
{"shortcut",FL_CTRL+FL_Enter, 0,0, FL_MENU_DIVIDER},
|
|
{"shortcut",FL_F+1},
|
|
{"shortcut",FL_SHIFT+FL_F+1},
|
|
{"shortcut",FL_CTRL+FL_F+1},
|
|
{"shortcut",FL_SHIFT+FL_CTRL+FL_F+1},
|
|
{"shortcut",FL_ALT+FL_F+1},
|
|
{"shortcut",FL_ALT+FL_SHIFT+FL_F+1},
|
|
{"shortcut",FL_ALT+FL_CTRL+FL_F+1},
|
|
{"shortcut",FL_ALT+FL_SHIFT+FL_CTRL+FL_F+1, 0,0, FL_MENU_DIVIDER},
|
|
{"&Submenus", FL_ALT+'S', 0, (void*)"Submenu1", FL_SUBMENU},
|
|
{"A very long menu item"},
|
|
{"&submenu",FL_CTRL+'S', 0, (void*)"submenu2", FL_SUBMENU},
|
|
{"item 1"},
|
|
{"item 2"},
|
|
{"item 3"},
|
|
{"item 4"},
|
|
{0},
|
|
{"after submenu"},
|
|
{0},
|
|
{0},
|
|
{"&Edit",FL_F+2,0,0,FL_SUBMENU},
|
|
{"Undo", FL_ALT+'z', 0},
|
|
{"Redo", FL_ALT+'r', 0, 0, FL_MENU_DIVIDER},
|
|
{"Cut", FL_ALT+'x', 0},
|
|
{"Copy", FL_ALT+'c', 0},
|
|
{"Paste", FL_ALT+'v', 0},
|
|
{"Inactive", FL_ALT+'d', 0, 0, FL_MENU_INACTIVE},
|
|
{"Clear", 0, 0, 0, FL_MENU_DIVIDER},
|
|
{"Invisible", FL_ALT+'e', 0, 0, FL_MENU_INVISIBLE},
|
|
{"Preferences", 0, 0},
|
|
{"Size", 0, 0},
|
|
{0},
|
|
{"&Checkbox",FL_F+3,0,0,FL_SUBMENU},
|
|
{"&Alpha", FL_F+2, 0, (void *)1, FL_MENU_TOGGLE},
|
|
{"&Beta", 0, 0, (void *)2, FL_MENU_TOGGLE},
|
|
{"&Gamma", 0, 0, (void *)3, FL_MENU_TOGGLE},
|
|
{"&Delta", 0, 0, (void *)4, FL_MENU_TOGGLE|FL_MENU_VALUE},
|
|
{"&Epsilon",0, 0, (void *)5, FL_MENU_TOGGLE},
|
|
{"&Pi", 0, 0, (void *)6, FL_MENU_TOGGLE},
|
|
{"&Mu", 0, 0, (void *)7, FL_MENU_TOGGLE|FL_MENU_DIVIDER},
|
|
{"Red", 0, 0, (void *)1, FL_MENU_TOGGLE, 0, 0, 0, 1},
|
|
{"Black", 0, 0, (void *)1, FL_MENU_TOGGLE|FL_MENU_DIVIDER},
|
|
{"00", 0, 0, (void *)1, FL_MENU_TOGGLE},
|
|
{"000", 0, 0, (void *)1, FL_MENU_TOGGLE},
|
|
{0},
|
|
{"&Radio",0,0,0,FL_SUBMENU},
|
|
{"&Alpha", 0, 0, (void *)1, FL_MENU_RADIO},
|
|
{"&Beta", 0, 0, (void *)2, FL_MENU_RADIO},
|
|
{"&Gamma", 0, 0, (void *)3, FL_MENU_RADIO},
|
|
{"&Delta", 0, 0, (void *)4, FL_MENU_RADIO|FL_MENU_VALUE},
|
|
{"&Epsilon",0, 0, (void *)5, FL_MENU_RADIO},
|
|
{"&Pi", 0, 0, (void *)6, FL_MENU_RADIO},
|
|
{"&Mu", 0, 0, (void *)7, FL_MENU_RADIO|FL_MENU_DIVIDER},
|
|
{"Red", 0, 0, (void *)1, FL_MENU_RADIO},
|
|
{"Black", 0, 0, (void *)1, FL_MENU_RADIO|FL_MENU_DIVIDER},
|
|
{"00", 0, 0, (void *)1, FL_MENU_RADIO},
|
|
{"000", 0, 0, (void *)1, FL_MENU_RADIO},
|
|
{0},
|
|
{"&Font",0,0,0,FL_SUBMENU /*, 0, FL_BOLD, 20*/},
|
|
{"Normal", 0, 0, 0, 0, 0, 0, 14},
|
|
{"Bold", 0, 0, 0, 0, 0, FL_BOLD, 14},
|
|
{"Italic", 0, 0, 0, 0, 0, FL_ITALIC, 14},
|
|
{"BoldItalic",0,0,0, 0, 0, FL_BOLD+FL_ITALIC, 14},
|
|
{"Small", 0, 0, 0, 0, 0, FL_BOLD+FL_ITALIC, 10},
|
|
{"Emboss", 0, 0, 0, 0, (uchar)FL_EMBOSSED_LABEL},
|
|
{"Engrave", 0, 0, 0, 0, (uchar)FL_ENGRAVED_LABEL},
|
|
{"Shadow", 0, 0, 0, 0, (uchar)FL_SHADOW_LABEL},
|
|
{"@->", 0, 0, 0, 0, (uchar)FL_SYMBOL_LABEL},
|
|
{0},
|
|
{"&International",0,0,0,FL_SUBMENU},
|
|
{"Sharp Ess",0x0000df},
|
|
{"A Umlaut",0x0000c4},
|
|
{"a Umlaut",0x0000e4},
|
|
{"Euro currency",FL_COMMAND+0x0020ac},
|
|
{"the &\xc3\xbc Umlaut"}, // ü
|
|
{"the capital &\xc3\x9c"}, // Ü
|
|
{"convert \xc2\xa5 to &\xc2\xa3"}, // Yen to GBP
|
|
{"convert \xc2\xa5 to &\xe2\x82\xac"}, // Yen to Euro
|
|
{"Hangul character Sios &\xe3\x85\x85"},
|
|
{"Hangul character Cieuc", 0x003148},
|
|
{0},
|
|
{"E&mpty",0,0,0,FL_SUBMENU},
|
|
{0},
|
|
{"&Inactive", 0, 0, 0, FL_MENU_INACTIVE|FL_SUBMENU},
|
|
{"A very long menu item"},
|
|
{"A very long menu item"},
|
|
{0},
|
|
{"Invisible",0, 0, 0, FL_MENU_INVISIBLE|FL_SUBMENU},
|
|
{"A very long menu item"},
|
|
{"A very long menu item"},
|
|
{0},
|
|
{"&Huge", 0, 0, (void*)hugemenu, FL_SUBMENU_POINTER},
|
|
{"button",FL_F+4, 0, 0, FL_MENU_TOGGLE},
|
|
{0}
|
|
};
|
|
|
|
Fl_Menu_Item pulldown[] = {
|
|
{"Red", FL_ALT+'r'},
|
|
{"Green", FL_ALT+'g'},
|
|
{"Blue", FL_ALT+'b'},
|
|
{"Strange", FL_ALT+'s', 0, 0, FL_MENU_INACTIVE},
|
|
{"&Charm", FL_ALT+'c'},
|
|
{"Truth", FL_ALT+'t'},
|
|
{"Beauty", FL_ALT+'b'},
|
|
{0}
|
|
};
|
|
|
|
#ifdef HAS_MAC_APP_MENU
|
|
Fl_Menu_Item menu_location[] = {
|
|
{"Fl_Menu_Bar", 0, 0, 0, FL_MENU_VALUE},
|
|
{"Fl_Sys_Menu_Bar", },
|
|
{0}
|
|
};
|
|
|
|
Fl_Sys_Menu_Bar* smenubar;
|
|
|
|
void menu_location_cb(Fl_Widget* w, void* data)
|
|
{
|
|
Fl_Menu_Bar *menubar = (Fl_Menu_Bar*)data;
|
|
if (((Fl_Choice*)w)->value() == 1) { // switch to system menu bar
|
|
menubar->hide();
|
|
const Fl_Menu_Item *menu = menubar->menu();
|
|
smenubar = new Fl_Sys_Menu_Bar(0,0,0,30);
|
|
smenubar->menu(menu);
|
|
smenubar->callback(test_cb);
|
|
}
|
|
else { // switch to window menu bar
|
|
menubar->copy(smenubar->menu());
|
|
delete smenubar;
|
|
menubar->show();
|
|
}
|
|
}
|
|
#endif // HAS_MAC_APP_MENU
|
|
|
|
void menu_linespacing_cb(Fl_Widget* w, void*) {
|
|
Fl_Value_Slider *fvs = (Fl_Value_Slider*)w;
|
|
int val = (int)fvs->value();
|
|
Fl::menu_linespacing(val); // takes effect when someone opens a new menu..
|
|
}
|
|
|
|
#define WIDTH 700
|
|
|
|
Fl_Menu_* menus[4];
|
|
|
|
void about_cb(Fl_Widget*, void*) {
|
|
fl_message("The menubar test app.");
|
|
}
|
|
|
|
int main(int argc, char **argv) {
|
|
//Fl::set_color(Fl_Color(15),0,0,128);
|
|
for (int i=0; i<99; i++) {
|
|
char buf[100];
|
|
snprintf(buf, 100,"item %d",i);
|
|
hugemenu[i].text = fl_strdup(buf);
|
|
}
|
|
Fl_Double_Window window(WIDTH,400+TERMINAL_HEIGHT);
|
|
|
|
Fl_Scheme_Choice scheme_choice(300, 50, 100, 25, "&scheme");
|
|
|
|
G_tty = new Fl_Terminal(0,400,WIDTH,TERMINAL_HEIGHT);
|
|
|
|
window.callback(window_cb);
|
|
Fl_Menu_Bar menubar(0,0,WIDTH,30); menubar.menu(menutable);
|
|
menubar.callback(test_cb);
|
|
menus[0] = &menubar;
|
|
Fl_Menu_Button mb1(100,100,120,25,"&menubutton"); mb1.menu(pulldown);
|
|
mb1.tooltip("this is a menu button");
|
|
mb1.callback(test_cb);
|
|
menus[1] = &mb1;
|
|
Fl_Choice ch(300,100,80,25,"&choice:"); ch.menu(pulldown);
|
|
ch.tooltip("this is a choice menu");
|
|
ch.callback(test_cb);
|
|
menus[2] = &ch;
|
|
Fl_Menu_Button mb(0,0,WIDTH,400,"&popup");
|
|
mb.type(Fl_Menu_Button::POPUP3);
|
|
mb.menu(menutable);
|
|
mb.remove(1); // delete the "File" submenu
|
|
mb.callback(test_cb);
|
|
menus[3] = &mb;
|
|
Fl_Box b(200,200,200,100,"Press right button\nfor a pop-up menu");
|
|
window.resizable(&mb);
|
|
window.size_range(300,400,0,400+TERMINAL_HEIGHT);
|
|
#ifdef HAS_MAC_APP_MENU
|
|
Fl_Choice ch2(500,100,150,25,"Use:");
|
|
ch2.menu(menu_location);
|
|
ch2.callback(menu_location_cb, &menubar);
|
|
ch2.value(1);
|
|
menu_location_cb(&ch2, &menubar);
|
|
#endif
|
|
|
|
Fl_Value_Slider menu_linespacing_slider(500,150,150,20,"Fl::menu_linespacing()");
|
|
menu_linespacing_slider.tooltip("Changes the line spacing between all menu items");
|
|
menu_linespacing_slider.type(1);
|
|
//menu_linespacing_slider.labelsize(14);
|
|
menu_linespacing_slider.value(Fl::menu_linespacing());
|
|
menu_linespacing_slider.color((Fl_Color)46);
|
|
menu_linespacing_slider.selection_color((Fl_Color)1);
|
|
//menu_linespacing_slider.textsize(10);
|
|
menu_linespacing_slider.align(Fl_Align(FL_ALIGN_LEFT));
|
|
menu_linespacing_slider.range(0.1, 50.0);
|
|
menu_linespacing_slider.step(1.0);
|
|
menu_linespacing_slider.callback(menu_linespacing_cb);
|
|
|
|
window.end();
|
|
|
|
Fl_Sys_Menu_Bar::about(about_cb, NULL);
|
|
#ifdef HAS_MAC_APP_MENU
|
|
Fl_Menu_Item custom[] = {
|
|
{"Preferences…", 0, test_cb, NULL, FL_MENU_DIVIDER},
|
|
{"Radio1", 0, test_cb, NULL, FL_MENU_RADIO | FL_MENU_VALUE},
|
|
{"Radio2", 0, test_cb, NULL, FL_MENU_RADIO | FL_MENU_DIVIDER},
|
|
{0}
|
|
};
|
|
Fl_Mac_App_Menu::custom_application_menu_items(custom);
|
|
//Fl_Sys_Menu_Bar::window_menu_style(Fl_Sys_Menu_Bar::no_window_menu);
|
|
#endif
|
|
window.show(argc, argv);
|
|
return Fl::run();
|
|
}
|