// ...как и прежде...
color_menu.attach(new Button(Point(0,0),0,0,"red",cb_red));
color_menu.attach(new Button(Point(0,0),0,0,"blue",cb_blue));
color_menu.attach(new Button(Point(0,0),0,0,"black",cb_black));
attach(color_menu);
}
Кнопки динамически связываются с меню (с помощью функции attach()
) и при необходимости могут быть удалены и/или изменены. Функция Menu::attach()
настраивает размер и место кнопки, а также связывает его с окном. Это все. Теперь мы увидим на экране следующее.
Экспериментируя с этой программой, мы решили, что нам необходимо выпадающее меню; т.е. мы не хотим фиксировать конкретное место на экране, в котором оно будет появляться. Итак, мы добавили кнопку Color menu. Когда пользователь щелкнет на ней, всплывет меню цвета, а после того как выбора меню снова исчезнет, и на экране отобразится кнопка.
Посмотрим сначала на окно, в которое добавлено несколько линий.
Мы видим новую кнопку Color menu и несколько черных линий. Щелкнем на кнопке Color menu, и на экране откроется меню.
Обратите внимание на то, что кнопка Color menu исчезла. Она не нужна, пока открыто меню. Щелкнем на кнопке blue и получим следующий результат.
Теперь линии стали синими, а кнопка Color menu вновь появилась на экране.
Для того чтобы достичь такого эффекта, мы добавили кнопку Color menu и модифицировали функцию “pressed”, настроив видимость меню и кнопки. Вот как выглядит класс Lines_window
после всех этих модификаций.
struct Lines_window:Window {
Lines_window(Point xy, int w, int h, const string& title );
private:
// данные:
Open_polyline lines;
// элементы управления окном:
Button next_button; // добавляет (next_x,next_y) к линиям
Button quit_button; // завершает работу программы
In_box next_x;
In_box next_y;
Out_box xy_out;
Menu color_menu;
Button menu_button;
void change(Color c) { lines.set_color(c); }
void hide_menu() { color_menu.hide(); menu_button.show(); }
// действия, инициирующие обратные вызовы:
void red_pressed() { change(Color::red); hide_menu(); }
void blue_pressed() { change(Color::blue); hide_menu(); }
void black_pressed() { change(Color::black); hide_menu(); }
void menu_pressed() { menu_button.hide(); color_menu.show(); }
void next();
void quit();
// функции обратного вызова:
static void cb_red(Address, Address);
static void cb_blue(Address, Address);
static void cb_black(Address, Address);
static void cb_menu(Address, Address);
static void cb_next(Address, Address);
static void cb_quit(Address, Address);
};
Lines_window::Lines_window(Point xy,int w,int h,
const string&title)
:Window(xy,w,h,title),
next_button(Point(x_max()–150,0),70,20,
"Next point", cb_next),
quit_button(Point(x_max()–70,0),70,20,"Quit",cb_quit),
next_x(Point(x_max()–310,0),50,20,"next x:"),
next_y(Point(x_max()–210,0),50,20,"next y:"),
xy_out(Point(100,0),100,20,"current (x,y):")
color_menu(Point(x_max()–70,30),70,20,Menu::vertical,"color"),
menu_button(Point(x_max()–80,30),80,20,