CS 211 Lesson 27
Application Data, Finding Objects and Mouse Selection
Quote:
"Press on: nothing in the world can take place of perseverance. Talent will not; nothing is more common than unsuccessful men with talent. Education will not; the world is full of educated derelicts. Persistence and determination are alone omnipotent..." Calvin Coolidge
Lesson Objectives:
Know how to add user-defined properties to objects
Be able to get the handle of the current object
Be able to use the mouse to select objects
Lesson:
I. MATLAB Concepts
A. Storing Application Data With Graphic Objects
All graphics objects have a set of predefined properties based on their object type.
You can add additional properties and values to an individual object using the setappdata(Handle, 'FieldName', Value) function. For example, the following code adds an Author property to a figure object whose handle is Figure_handle.
setappdata(Figure_handle, 'Author', 'John Doe')
After data has been stored with a graphic object, it can be retrieved using the getappdata(Handle, 'FieldName') function. For example, the following statement retrieves the value of the author property of a figure object (assuming it has one).
Author_name = getappdata(Figure_handle, 'Author');
To test a graphic object to determine if it contains a specific, user-defined field, use the isappdata(Handle, 'FieldName') function. For example, to test whether a figure window contains a user-defined field called Author, you might write an if-statement like:
if isappdata(Figure_handle, 'Author')
Author_name = getappdata(Figure_handle, 'Author');
else
Author_name = 'Unknown';
end
To delete a specific, user-defined field from a graphics object, use the rmappdata(Handle, 'FieldName') function.
B. Finding Objects
If a function creates a graphic object, it typically returns a handle to the object it created. For example, the plot() function returns a vector containing the handles of all the line objects it created. Calling plot() may also have created axes and figure objects to contain the lines that were plotted, but the plot() function does not return handles to these objects.
It is often necessary to retrieve handles to graphic objects that were created by internal MATLAB code.
The following functions are useful for retrieving graphic object handles:
gcf() (get current figure)
Returns the handle of the current figure.
If a single figure exists, gcf() returns its handle
If there is more than one figure, the current figure is the one which has "focus", that is, the figure last selected by the user or last created.
If no figures exist (i.e., the root object has no children), gcf() creates a figure and returns its handle.
gca() (get current axes)
Returns the handle of the current axes
If there is a single axes in the current figure, gca() returns its handle.
If there is more than one axes in the current figure, the current axes is the one which was last selected by the user or last created.
If there are no axes in the current figure, gca() creates one and returns its handle.
gco() (get current object)
Returns the handle of the current object.
The current object is the last graphic object clicked on by the user.
If the user has not selected any objects, gco returns an empty vector ([]) .
A program can determine the type of the currently selected object by getting the value of its Type property.
findobj('PropertyName', PropertyValue)
findobj() returns a vector of handles to objects which have the specified property values.
For example, the following code returns the handles of all figure objects
Figure_handles = findobj('Type', 'figure');
get(KnownHandle, 'parent')
If you know the handle of a specific object, you can retrieve a handle to its parent object using the get() function.
get(KnownHandle, 'Children')
If you know the handle of a specific object, you can retrieve a list of the handles to its children objects using the get() function.
C. Selecting Objects with the Mouse
The user can designate the current object by clicking the mouse cursor on the object's graphic image.
Different types of objects have different mouse selection areas associated with them. For example, to select a line, the user must click the mouse cursor within 5 pixels of the line.
If the graphical representation of more than one object occupies the same space on the screen, selection is determined by type priority or stacking order
In general, an object has higher priority than its parent object. For example, a line gets selected over its enclosing axes, which gets selected over its enclosing figure.
When objects are of the same type, the object highest in the stacking order gets selected.
A program can determine the stacking order of objects by examining the order of handles in the Children property of the enclosing object. For example, if an axes contains several line objects, and you get the value of the axes' Children property, then the order of the line handles defines their stacking order.
Use the waitforbuttonpress() function to wait for the user to select an object with the mouse.
The waitforbuttonpress() function pauses the program until the user presses a key or clicks a mouse button.
The waitforbuttonpress() function returns zero if the user presses a mouse button. If you want to know additional information about the mouse click, ---
To get which mouse button was clicked, get the SelectionType property of the figure window (see example below).
To get the location of the mouse relative to the figure window, get the CurrentPoint property of the figure window. This returns a 2-element vector [pixelx pixely] that gives the location of the mouse in pixels from the lower-left corner of the figure window.
To get the location of the mouse relative to an axes object, get the CurrentPoint property of an axes object. This returns a 2x3 matrix [frontx fronty frontz; backx backy backz] that gives the location of the mouse in axes' units. A axes object can be 3-dimensional and the two (x,y,z) values that are returned specify where the mouse enters the "front face" of the axes and where it exits the "back face" of the axes. For 2-dimensional plots, the only values you need to use are the [frontx fronty] values.
The waitforbuttonpress() function returns one if the user presses any key. If you want to know the key that was pressed, you can get the CurrentCharacter property of the figure window.
The following example code demonstrates these ideas:
Key = ' '; while Key ~= 'q' Button = waitforbuttonpress(); if Button == 0 % A mouse button was pressed MouseButtonType = get( gcf(), 'SelectionType'); MouseFigureLocation = get( gcf(), 'CurrentPoint'); MouseAxesLocation = get( gca(), 'CurrentPoint'); if strcmp(MouseButtonType, 'normal') fprintf('LEFT-button '); elseif strcmp(MouseButtonType, 'extend') fprintf('MIDDLE-button'); elseif strcmp(MouseButtonType, 'alt') fprintf('RIGHT-button '); elseif strcmp(MouseButtonType, 'open') fprintf('DOUBLE-CLICK '); end fprintf(' mouse click at Figure (%3d %3d) Axes (%6.4f %6.4f)\n', ... MouseFigureLocation(1), MouseFigureLocation(2), ... MouseAxesLocation(1,1), MouseAxesLocation(1,2) ) else % Button == 1; A keyboard key was pressed Key = get( gcf(), 'CurrentCharacter'); fprintf('The user hit the %c(%d) key\n', Key, Key); end end
II. Good Programming Practices
(none for this lesson)
III. Algorithms
(none for this lesson)
Lab Work: Lab 27
References: Chapman Textbook: section 9.5-9.7