28 марта 2010 г.

GtkDrawingArea. Автоматическое рисование точек на холсте

В группе "Русское сообщество PHP-GTK" человек под ником Gucha ZX попросил меня рассказать о том, как работать с классом для произвольного рисования GtkDrawingArea, что я в этой, а возможно, и в следующих статьях и сделаю. Сегодня Вы узнаете о том, как создать белый холст и нарисовать на нём точку.





И так. Класс GtkDrawingArea создаёт область для рисования. Как только область появляется первый раз на экране, издаётся сигнал 'expose-event'. В ответ на него мы вызываем функцию do_expose(), которая заполняет холст белым цветом. Функция простая и в коде есть комментарии, поэтому останавливаться на объяснении я не буду.
При нажатии на кнопку, вызываем функцию drawing_rand_point(), которая рисует точку на холсте. Она работает точно также, как и do_expose().

А теперь подводные камни. При перекрытии области GtkDrawingArea другим окном она стирается и издаётся сигнал 'expose-event', соответственно, перекрытая область перекрасится заново в белый цвет, и нарисованные точки пропадут. Как обойти этот "подводный камень" я пока не знаю.
P.S. Чуть позже ответ был найден - GtkDrawingArea. Усовершенствование.

Полный код программы:

<?php
 
// Размеры холста
define('WIDTH', 400);
define('HEIGHT', 170);
 
$window = new GtkWindow();
$window->set_position(Gtk::WIN_POS_CENTER);
$window->set_title('Работа с GtkDrawingArea');
$window->set_size_request(400, 200);
$window->connect_simple('destroy', array('Gtk', 'main_quit'));
 
$vbox = new GtkVBox();
 
$vbox->pack_start($button = new GtkButton('Нарисовать случайную точку'), FALSE, FALSE);
 
$vbox->pack_start($drawing = new GtkDrawingArea());
 
$button->connect_simple('clicked', 'drawing_rand_point', $drawing);
$drawing->connect('expose-event', 'do_expose');
 
$window->add($vbox);
$window->show_all();
Gtk::main();
 
/**
* Функция рисует точку случайного цвета со случайными размерами в случайном месте холста :)
* @param resource $widget Виджет GtkDrawingArea
*/

function drawing_rand_point($widget)
{
// Генерируем случайный цвет для точки
// Цвет указывается в RGB-формате
$color_rand = new GdkColor(rand(0, 65535), rand(0, 65535), rand(0, 65535));
$point = new GdkGc($widget->window);
$point->set_rgb_fg_color($color_rand);
 
// Рисуем точку
// Первый параметр - идентификатор цвета
// Второй параметр отвечает за заливку кисти. Если TRUE - кисть закрашенная, FALSE - рисуется только контур кисти
// 3 и 4 параметры - положение точки
// 5 и 6 параметры - размеры точки
$widget->window->draw_rectangle($point, TRUE, rand(0, WIDTH), rand(0, HEIGHT), rand(3, 20), rand(3, 20));
}
 
/**
* Функция заливает холст белым цветом.
* @param resource $widget Виджет GtkDrawingArea
*/

function do_expose($widget)
{
// Устанавливаем цвет фона
// Цвет указывается в RGB-формате
$color_white = new GdkColor(65535, 65535, 65535);
$background = new GdkGC($widget->window);
$background->set_rgb_fg_color($color_white);
 
// Заполняем виджет белым фоном
// Первый параметр - идентификатор цвета
// Назначение второй параметра мне не известно, оставим TRUE
// 3 и 4 параметры - положение точки
// 5 и 6 параметры - размеры точки
$widget->window->draw_rectangle($background, TRUE, 0, 0, WIDTH, HEIGHT);
}
 
?>

3 комментария:

LegioNemesis комментирует...

Неизвестный параметр отвечает за заливку. Если будет тру - прямоугольники заливается цветом, если фалс - контур прямоугольника будет цветной, а фон белый. Rectangle - это всё таки прямоуголник, а не точка.

Shecspi комментирует...

Спасибо, поправил.

Gucha ZX комментирует...

Спасибо за статью! :)