Читаем Программирование полностью

    // ...как и прежде...

    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,

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже