Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
ЛАБ № 5 Создание приложений с GUI без среды GU...doc
Скачиваний:
9
Добавлен:
24.11.2019
Размер:
470.53 Кб
Скачать

Перемещение объектов на осях мышью

Мы разберем простой способ организации передвижения объектов, нарисованных на осях, при помощи мыши. Ограничимся пока приложением movecrc, в котором на осях есть три кружка, для их перемещения используется мышь при нажатой левой кнопке (см. рис. 1). Далее немного модифицируем приложение, добавив в него возможность копирования кружков движением мыши при нажатой клавише Ctrl и удаление кружка двойным щелчком.

Рис. 1. Приложение movecrc для перемещения кружков мышью.

Приложение movecrc состоит из основной функции с подфункциями (их текст приведен ниже). В основной функции создаются:

  • графическое окно и оси с пределами по x и y от -1 до 1 и с рамкой вокруг;

  • три круглых маркера заданного размера и цвета при помощи функции line (в функции line указаны координаты одной точки, поэтому линии не будет, а будет только маркер), указатели на маркеры записываем в массив hM.

Далее с событием ButtonDownFcn каждого маркера (которое возникает при нажатии кнопки мыши, если курсор находится на маркере) в цикле связываем подфункцию MarkerButtonDownFcn.

Назначение подфункций приложения movecrc следующее.

  • MarkerButtonDownFcn(src, eventdata) — подфункция, вызываемая при нажатии кнопки мыши на маркере. В ней с событием графического окна WindowButtonMotionFcn (которое возникает при движении курсора мыши в пределах графического окна) связывается подфункция MouseMoving. В подфункцию MouseMoving передается дополнительный аргумент — указатель на маркер, который возвращается функцией gcbo (функция gcbo возвращает указатель на объект, событие которого выполняется в данный момент времени). Кроме этого, с событием графического окна WindowButtonUpFcn (которое возникает при отпускании кнопки мыши) связывается подфункция ButtonUp.

  • MouseMoving(src, eventdata, hM) — подфункция, выполняемая при движении курсора мыши. Ее третий аргумент hM содержит указатель на текущий (двигаемый) маркер. В этой подфункции при помощи свойства осей CurrentPoint узнаются текущие координаты курсора мыши, делается проверка на выход за пределы осей и изменяются координаты маркера.

  • ButtonUp(src, eventdata) — подфункция, выполняемая при отпускании кнопки мыши. В этой подфункции свойствам WindowButtonMotionFcn и WindowButtonUpFcn графического окна присваивается пустая строка для разрыва соответствующих событий с прежними функциями MouseMoving и ButtonUp.

function movecrc

% создаем графическое окно

figure('Color', 'w')

% создаем оси

axes('XLim', [-1 1], 'YLim', [-1 1], 'Box', 'on');

% Рисуем три маркера (линии)

hM(1)=line(0.5, 0.5, 'Marker','o', 'MarkerSize', 20,...

'MarkerFaceColor', 'r', 'MarkerEdgeColor', 'g');

hM(2)=line(-0.5, -0.5, 'Marker','o', 'MarkerSize', 20,...

'MarkerFaceColor', 'y', 'MarkerEdgeColor', 'b');

hM(3)=line(0, 0, 'Marker','o', 'MarkerSize', 20,...

'MarkerFaceColor', 'c', 'MarkerEdgeColor', 'm');

% определяем подфункцию обработки события ButtonDownFcn каждой линии

for k = 1 : length(hM)

set(hM(k),'ButtonDownFcn',@MarkerButtonDownFcn)

end

function MarkerButtonDownFcn(src,eventdata)

% Подфункция обработки события ButtonDownFcn линии

% Определяем подфункции для событий WindowButtonMotionFcn

% и WindowButtonUpFcn графического окна

set(gcf,'WindowButtonMotionFcn',{@MouseMoving,gcbo})

set(gcf,'WindowButtonUpFcn',@ButtonUp)

function MouseMoving(src,eventdata,hM)

% Подфункция для события WindowButtonMotionFcn

% получаем координаты текущей точки осей

C = get(gca, 'CurrentPoint');

x = C(1,1);

y = C(1,2);

% получаем пределы осей

xlim = get(gca, 'XLim');

ylim = get(gca, 'YLim');

% в inaxes 1, если не вышли за оси, иначе - 0

inaxes = xlim(1)< x & xlim(2) > x & ...

ylim(1)< y & ylim(2) > y;

if inaxes

% если находимся в пределах осей,

% то изменяем координаты маркера

set(hM,'XData', x, 'YData', y)

end

function ButtonUp(src, eventdata)

% Подфункция для события WindowButtonUpFcn

% Когда отпустили кнопку мыши, графическое окно должно перестать

% реагировать на движение мыши

set(gcf,'WindowButtonMotionFcn', '')

set(gcf,'WindowButtonUpFcn', '')

Небольшая модификация подфункции MarkerButtonDownFcn позволяет копировать маркеры (мышью при нажатой клавише Ctrl) и удалять их двойным щелчком. Для того, чтобы узнать тип щелчка используется свойство SelectionType графического окна. Это свойство принимает следующие значения.

  • normal — при обычном щелчке левой кнопкой;

  • extend — при щелчке левой кнопкой с удержанием Shift, или при щелчке одновременно двумя клавишами;

  • alt — при щелчке левой кнопкой с удержанием Ctrl, или при щелчке правой кнопкой

  • open — при двойном щелчке любой кнопкой.

После определения типа щелчка в подфункции MarkerButtonDownFcn происходит его обработка. Если был сделан щелчок с удержанием Ctrl, то маркер копируется при помощи функции copyobj. Ее первым входным аргументом является указатель на копируемый объект, вторым — указатель на объект, которому по иерархии принадлежит копируемый объект (оси), а в выходном аргументе возвращается указатель на новый объект. Далее с событием ButtonDownFcn нового маркера связывается функция MarkerButtonDownFcn. Если был сделан двойной щелчок, то удаляем маркер и завершаем работу подфункции при помощи return. Связывание с событиями WindowButtonMotionFcn и WindowButtonUpFcn соответствующих подфункций остается без изменений.

function MarkerButtonDownFcn(src,eventdata,hM)

% Подфункция обработки события ButtonDownFcn линии

% узнаем тип щелчка мышью

key = get(gcf, 'SelectionType');

if isequal(key, 'alt')

% если щелчок с Ctrl, то дублируем маркер

hM = copyobj(hM, gca)

% назначем подфункцию обработки его события ButtonDownFcn

set(hM, 'ButtonDownFcn', {@MarkerButtonDownFcn, hM})

end

if isequal(key, 'open')

% если двойной щелчок, то удаляем маркер

delete(hM)

% и завершаем работу подфункции

return

end

% Определяем подфункции для событий WindowButtonMotionFcn

% и WindowButtonUpFcn графического окна

set(gcf,'WindowButtonMotionFcn',{@MouseMoving,hM})

set(gcf,'WindowButtonUpFcn',@ButtonUp)