\begindata{text,17197468} \textdsversion{12} \template{be2guide} \define{global } \define{underline menu:[Font~1,Underline~41] attr:[Flags Underline Int Set]} \define{index menu:[Title,Index~91] attr:[FontFace Italic Int Set]} \define{indexi menu:[Title,InvisibleIndex~92] attr:[Script PreviousScriptMovement Point -2] attr:[Flags Hidden Int Set] attr:[FontFace Italic Int Set]} \define{fixedtext menu:[Region~4,Fixedtext] attr:[Justification LeftJustified Point 0] attr:[FontFace FixedFace Int Set] attr:[FontFamily AndyType Int 0] attr:[FontSize ConstantFontSize Point 10]} \define{fixedindent menu:[Region~4,Fixedindent] attr:[LeftMargin LeftMargin Cm 83230] attr:[Justification LeftJustified Point 0] attr:[FontFace FixedFace Int Set] attr:[FontFamily AndyType Int 0] attr:[FontSize ConstantFontSize Point 10]} \define{paramname menu:[Font~1,Paramname] attr:[FontFace Italic Int Set]} \chapter{\formatnote{View} }\indexi{View} The class \italic{view} provides the methods, class procedures and data structures needed to (1) display information (often associated with a data object) in a rectangular area on the screen, (2) request display updates and respond to such requests, and (3) respond to input events generated by the user.\indexi{Display}\indexi{User interface} The class \italic{view} provides an interface to the underlying window systems. As an Andrew Toolkit application programmer, you should understand why applications programs should not interact directly with the underlying window system: application programs must often be ported to other workstations that will eventually be deployed. The workstations often have similar, but not identical, display capabilities and the hardware can be significantly different; the underlying window system may be different. To insure portability of your application, you should never make direct calls to the underlying window system; you should always use the \italic{view} class procedures and methods; doing so will maximize the device independence and portabilty of your application program. \indexi{View++Window system interface} The class \italic{view} contains a pointer to an instance of the class \italic{graphic}. \italic{View} exports a set of methods that allow the programmer to execute drawing operations using its associated graphic object. It is never proper to create an instance of a \italic{view}. only create subclasses of \italic{view}. You should \section{Quick reference list for View} \fixedtext{\bold{view_}BitBltSize }\fixedindent{(struct view *\paramname{view}, \paramname{srcX}, \paramname{srcY}, \paramname{dstX}, \paramname{dstY}, \paramname{Width}, \paramname{Height}, \paramname{DstView}, \paramname{clipX}, \paramname{clipY}, \paramname{clipWidth}, \paramname{clipHeight});} \fixedtext{\bold{view_}BitBlt }\fixedindent{(struct view *\paramname{view}, \paramname{SrcRect}, \paramname{DestView}, \paramname{DstOrigin}, \paramname{ClipRectList});} \fixedtext{\bold{view_}BlackPattern }\fixedindent{(struct view *\paramname{view});} \fixedtext{boolean \bold{view_}CanView }\fixedindent{(struct view *\paramname{view}, char *\paramname{TypeName});} \fixedtext{\bold{view_}ClearClippingRect }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}ColorPattern }\fixedindent{(struct view *\paramname{view}, \paramname{red}, \paramname{blue}, \paramname{green});} \fixedtext{void \bold{view_}DeleteApplicationLayer }\fixedindent{(struct view *\paramname{view}, struct view *\paramname{applicationLayer});} \fixedtext{enum view_DescriberErrs \bold{view_}Describe }\fixedindent{(struct view *\paramname{view}, char *\paramname{format}, FILE *\paramname{file}, long \paramname{rock});} \fixedtext{char *\bold{view_}DescriptionObject }\fixedindent{(struct view *\paramname{view}, char *\paramname{format}, long \paramname{rock});} \fixedtext{enum view_DSattributes \bold{view_}DesiredSize }\fixedindent{(struct view *\paramname{view}, long \paramname{width}, long \paramname{height}, enum view_DSpass \paramname{pass}, long *\paramname{dWidth}, long *\paramname{dheight});} \fixedtext{\bold{view_}DrawArcSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height}, \paramname{StartAngle}, \paramname{OffsetAngle});} \fixedtext{\bold{view_}DrawArc }\fixedindent{(struct view *\paramname{view}, \paramname{EnclRect}, \paramname{StartAngle}, \paramname{OffsetAngle});} \fixedtext{\bold{view_}DrawLineToPt }\fixedindent{(struct view *\paramname{view}, \paramname{LineEnd});} \fixedtext{\bold{view_}DrawLineTo }\fixedindent{(struct view *\paramname{view}, \paramname{XEnd}, \paramname{YEnd});} \fixedtext{\bold{view_}DrawLine }\fixedindent{(struct view *\paramname{view}, \paramname{DeltaX}, \paramname{DeltaY});} \fixedtext{\bold{view_}DrawOvalSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height});} \fixedtext{\bold{view_}DrawOval }\fixedindent{(struct view *\paramname{view}, \paramname{Rect});} \fixedtext{\bold{view_}DrawPath }\fixedindent{(struct view *\paramname{view}, \paramname{PointArray}, \paramname{PointCount});} \fixedtext{\bold{view_}DrawPolygon }\fixedindent{(struct view *\paramname{view}, \paramname{PointArray}, \paramname{PointCount});} \fixedtext{\bold{view_}DrawRectSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height});} \fixedtext{\bold{view_}DrawRect }\fixedindent{(struct view *\paramname{view}, \paramname{Rect});} \fixedtext{\bold{view_}DrawRgn }\fixedindent{(struct view *\paramname{view}, \paramname{Rgn});} \fixedtext{\bold{view_}DrawRRectSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height}, \paramname{cornerWidth}, \paramname{cornerHeight});} \fixedtext{\bold{view_}DrawRRect }\fixedindent{(struct view *\paramname{view}, \paramname{OuterBox}, \paramname{InnerBox});} \fixedtext{\bold{view_}DrawString }\fixedindent{(struct view *\paramname{view}, \paramname{Text}, \paramname{Operation});} \fixedtext{\bold{view_}DrawText }\fixedindent{(struct view *\paramname{view}, \paramname{Text}, \paramname{TextLength}, \paramname{Operation});} \fixedtext{\bold{view_}DrawTrapezoid }\fixedindent{(struct view *\paramname{view}, \paramname{topX}, \paramname{topY}, \paramname{topWidth}, \paramname{bottomX}, \paramname{bottomY}, \paramname{bottomWidth});} \fixedtext{\bold{view_}EnclosedXToLocalX }\fixedindent{(struct view *\paramname{view}, \paramname{xvalue});} \fixedtext{\bold{view_}EnclosedYToLocalY }\fixedindent{(struct view *\paramname{view}, \paramname{yvalue});} \fixedtext{\bold{view_}EraseRectSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height});} \fixedtext{\bold{view_}EraseRect }\fixedindent{(struct view *\paramname{view}, \paramname{Rect});} \fixedtext{\bold{view_}EraseVisualRect }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}FillArcSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height}, \paramname{StartAngle}, \paramname{OffsetAngle}, \paramname{Tile});} \fixedtext{\bold{view_}FillArc }\fixedindent{(struct view *\paramname{view}, \paramname{EnclRect}, \paramname{StartAngle}, \paramname{OffsetAngle}, \paramname{Tile});} \fixedtext{\bold{view_}FillOvalSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height}, \paramname{Tile});} \fixedtext{\bold{view_}FillOval }\fixedindent{(struct view *\paramname{view}, \paramname{Rect}, \paramname{Tile});} \fixedtext{\bold{view_}FillPolygon }\fixedindent{(struct view *\paramname{view}, \paramname{PointArray}, \paramname{PointCount}, \paramname{Tile});} \fixedtext{\bold{view_}FillRectSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height}, \paramname{Tile});} \fixedtext{\bold{view_}FillRect }\fixedindent{(struct view *\paramname{view}, \paramname{Rect}, \paramname{Tile});} \fixedtext{\bold{view_}FillRgn }\fixedindent{(struct view *\paramname{view}, \paramname{Rgn}, \paramname{Tile});} \fixedtext{\bold{view_}FillRRectSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height}, \paramname{cornerWidth}, \paramname{cornerHeight}, \paramname{Tile});} \fixedtext{\bold{view_}FillRRect }\fixedindent{(struct view *\paramname{view}, \paramname{OuterBox}, \paramname{InnerBox}, \paramname{Tile});} \fixedtext{\bold{view_}FillTrapezoid }\fixedindent{(struct view *\paramname{view}, \paramname{topX}, \paramname{topY}, \paramname{topWidth}, \paramname{bottomX}, \paramname{bottomY}, \paramname{bottomWidth}, \paramname{Tile});} \fixedtext{void \bold{view_}FinalizeObject }\fixedindent{(struct view *\paramname{self});} \fixedtext{\bold{view_}FlushGraphics }\fixedindent{(struct view *\paramname{view});} \fixedtext{void \bold{view_}FullUpdate }\fixedindent{(struct view *\paramname{view}, enum view_UpdateType \paramname{type}, long \paramname{left}, long \paramname{top}, long \paramname{width}, long \paramname{right});} \fixedtext{struct view *\bold{view_}GetApplicationLayer }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetBackgroundColor }\fixedindent{(struct view *\paramname{view}, \paramname{retred}, \paramname{retblue}, \paramname{retgreen});} \fixedtext{struct atomlist *\bold{view_}GetClass }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetClippingRectSize }\fixedindent{(struct view *\paramname{view}, \paramname{retx}, \paramname{rety}, \paramname{retwidth}, \paramname{retheight});} \fixedtext{\bold{view_}GetClippingRect }\fixedindent{(struct view *\paramname{view}, \paramname{Rect});} \fixedtext{\bold{view_}GetCurrentPt }\fixedindent{(struct view *\paramname{view}, \paramname{Pt});} \fixedtext{\bold{view_}GetDataObject }\fixedindent{(struct view *\paramname{view});} \fixedtext{long \bold{view_}GetDevice }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetDrawable }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetEnclosedBottom }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetEnclosedBoundsSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height});} \fixedtext{\bold{view_}GetEnclosedBounds }\fixedindent{(struct view *\paramname{view}, \paramname{Rect});} \fixedtext{\bold{view_}GetEnclosedHeight }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetEnclosedLeft }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetEnclosedRight }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetEnclosedTop }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetEnclosedWidth }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetFont }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetForegroundColor }\fixedindent{(struct view *\paramname{view}, \paramname{retred}, \paramname{retblue}, \paramname{retgreen});} \fixedtext{\bold{view_}GetHorizontalResolution }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetIM }\fixedindent{(struct view *\paramname{view});} \fixedtext{char *\bold{view_}GetInterface }\fixedindent{(struct view *\paramname{view}, char *\paramname{type});} \fixedtext{\bold{view_}GetLineWidth }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetLogicalBottom }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetLogicalBoundsSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height});} \fixedtext{\bold{view_}GetLogicalBounds }\fixedindent{(struct view *\paramname{view}, \paramname{Rect});} \fixedtext{\bold{view_}GetLogicalHeight }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetLogicalLeft }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetLogicalRight }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetLogicalTop }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetLogicalWidth }\fixedindent{(struct view *\paramname{view});} \fixedtext{void \bold{view_}GetManyParameters }\fixedindent{(struct view *\paramname{view}, struct resourceList *\paramname{resources}, struct atomlist *\paramname{name}, struct atomlist *\paramname{class});} \fixedtext{struct atomlist *\bold{view_}GetName }\fixedindent{(struct view *\paramname{view});} \fixedtext{void \bold{view_}GetOrigin }\fixedindent{(struct view *\paramname{view}, long \paramname{width}, long \paramname{height}, long *\paramname{originX}, long *\paramname{originY});} \fixedtext{short \bold{view_}GetParameter }\fixedindent{(struct view *\paramname{view}, struct atomlist *\paramname{name}, struct atom *\paramname{type}, long *\paramname{data});} \fixedtext{short \bold{view_}GetResource }\fixedindent{(struct view *\paramname{view}, struct atomlist *\paramname{name}, struct atomlist *\paramname{class}, struct atom *\paramname{type}, long *\paramname{data});} \fixedtext{\bold{view_}GetSpaceShim }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetTransferMode }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetVerticalResolution }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetVisualBottom }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetVisualBoundsSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height});} \fixedtext{\bold{view_}GetVisualBounds }\fixedindent{(struct view *\paramname{view}, \paramname{Rect});} \fixedtext{\bold{view_}GetVisualHeight }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetVisualLeft }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetVisualRight }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetVisualTop }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GetVisualWidth }\fixedindent{(struct view *\paramname{view});} \fixedtext{char *\bold{view_}GetWindowManagerType }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}GrayPattern }\fixedindent{(struct view *\paramname{view}, \paramname{IntensityNum}, \paramname{IntensityDenom});} \fixedtext{struct view *\bold{view_}Hit }\fixedindent{(struct view *\paramname{view}, enum view_MouseAction \paramname{action}, long \paramname{x}, long \paramname{y}, long \paramname{numberOfClicks});} \fixedtext{void \bold{view_}InitChildren }\fixedindent{(struct view *\paramname{view});} \fixedtext{boolean \bold{view_}InitializeClass }\fixedindent{();} \fixedtext{boolean \bold{view_}InitializeObject }\fixedindent{(struct view *\paramname{self});} \fixedtext{void \bold{view_}InsertViewSize }\fixedindent{(struct view *\paramname{view}, struct view *\paramname{EnclosingView}, long \paramname{xOriginInParent}, long \paramname{yOriginInParent}, long \paramname{width}, long \paramname{height});} \fixedtext{void \bold{view_}InsertView }\fixedindent{(struct view *\paramname{view}, struct view *\paramname{parent}, struct rectangle *\paramname{enclosingRect});} \fixedtext{boolean \bold{view_}IsAncestor }\fixedindent{(struct view *\paramname{view}, \paramname{possibleAncestor});} \fixedtext{void \bold{view_}LinkTree }\fixedindent{(struct view *\paramname{view}, struct view *\paramname{parent});} \fixedtext{void \bold{view_}LoseInputFocus }\fixedindent{(struct view *\paramname{view});} \fixedtext{\bold{view_}MoveLogicalOrigin }\fixedindent{(struct view *\paramname{view}, \paramname{DeltaX}, \paramname{DeltaY});} \fixedtext{\bold{view_}MoveToPt }\fixedindent{(struct view *\paramname{view}, \paramname{Pt});} \fixedtext{\bold{view_}MoveTo }\fixedindent{(struct view *\paramname{view}, \paramname{NewX}, \paramname{NewY});} \fixedtext{\bold{view_}Move }\fixedindent{(struct view *\paramname{view}, \paramname{DeltaX}, \paramname{DeltaY});} \fixedtext{void \bold{view_}ObservedChanged }\fixedindent{(struct view *\paramname{view}, struct thisobject *\paramname{changed}, long \paramname{value});} \fixedtext{void \bold{view_}PostCursor }\fixedindent{(struct view *\paramname{view}, struct rectangle *\paramname{rec}, struct cursor *\paramname{cursor});} \fixedtext{void \bold{view_}PostDefaultHandler }\fixedindent{(struct view *\paramname{view}, char *\paramname{handlerName}, struct basicobject *\paramname{handler});} \fixedtext{void \bold{view_}PostKeyState }\fixedindent{(struct view *\paramname{view}, struct keystate *\paramname{keystate});} \fixedtext{void \bold{view_}PostMenus }\fixedindent{(struct view *\paramname{view}, struct menulist *\paramname{menulist});} \fixedtext{void \bold{view_}PostResource }\fixedindent{(struct view *\paramname{view}, struct atomlist *\paramname{path}, struct atom *\paramname{type}, long \paramname{data});} \fixedtext{void \bold{view_}Print }\fixedindent{(struct view *\paramname{view}, FILE *\paramname{file}, char *\paramname{processor}, char *\paramname{finalFormat}, boolean \paramname{topLevel});} \fixedtext{void \bold{view_}ReceiveInputFocus }\fixedindent{(struct view *\paramname{view});} \fixedtext{void \bold{view_}RetractCursor }\fixedindent{(struct view *\paramname{view}, struct cursor *\paramname{cursor});} \fixedtext{void \bold{view_}RetractViewCursors }\fixedindent{(struct view *\paramname{view}, struct view *\paramname{requestor});} \fixedtext{\bold{view_}SetBackgroundColor }\fixedindent{(struct view *\paramname{view}, char *\paramname{colorName}, \paramname{red}, \paramname{blue}, \paramname{green});} \fixedtext{\bold{view_}SetBitAtLoc }\fixedindent{(struct view *\paramname{view}, \paramname{XPos}, \paramname{YPos}, \paramname{NewValue});} \fixedtext{\bold{view_}SetClippingRectSize }\fixedindent{(struct view *\paramname{view}, \paramname{x}, \paramname{y}, \paramname{width}, \paramname{height});} \fixedtext{\bold{view_}SetClippingRect }\fixedindent{(struct view *\paramname{view}, \paramname{ClipRect});} \fixedtext{void \bold{view_}SetDataObject }\fixedindent{(struct view *\paramname{view}, struct dataobject *\paramname{dataobject});} \fixedtext{\bold{view_}SetFont }\fixedindent{(struct view *\paramname{view}, \paramname{ChosenFont});} \fixedtext{\bold{view_}SetForegroundColor }\fixedindent{(struct view *\paramname{view}, char *\paramname{colorName}, \paramname{red}, \paramname{blue}, \paramname{green});} \fixedtext{\bold{view_}SetLineWidth }\fixedindent{(struct view *\paramname{view}, \paramname{NewLineWidth});} \fixedtext{\bold{view_}SetLogicalOriginPt }\fixedindent{(struct view *\paramname{view}, \paramname{Pt});} \fixedtext{\bold{view_}SetLogicalOrigin }\fixedindent{(struct view *\paramname{view}, \paramname{NewX}, \paramname{NewY});} \fixedtext{void \bold{view_}SetName }\fixedindent{(struct view *\paramname{view}, struct atomlist *\paramname{name});} \fixedtext{\bold{view_}SetSpaceShim }\fixedindent{(struct view *\paramname{view}, \paramname{Amount});} \fixedtext{\bold{view_}SetTransferMode }\fixedindent{(struct view *\paramname{view}, \paramname{NewTransferMode});} \fixedtext{void \bold{view_}UnlinkNotification }\fixedindent{(struct view *\paramname{view}, struct view *\paramname{unlinkedTree});} \fixedtext{void \bold{view_}UnlinkTree }\fixedindent{(struct view *\paramname{view});} \fixedtext{void \bold{view_}Update }\fixedindent{(struct view *\paramname{view});} \fixedtext{struct basicobject *\bold{view_}WantHandler }\fixedindent{(struct view *\paramname{view}, char *\paramname{handlerName});} \fixedtext{char *\bold{view_}WantInformation }\fixedindent{(struct view *\paramname{view}, char *\paramname{key});} \fixedtext{void \bold{view_}WantInputFocus }\fixedindent{(struct view *\paramname{view}, struct view *\paramname{requestor});} \fixedtext{void \bold{view_}WantNewSize }\fixedindent{(struct view *\paramname{view}, struct view *\paramname{requestor});} \fixedtext{void \bold{view_}WantUpdate }\fixedindent{(struct view *\paramname{view}, struct view *\paramname{requestor});} \fixedtext{\bold{view_}WhitePattern }\fixedindent{(struct view *\paramname{view});} \section{Overview of view} \subsection{The associated data object} \indexi{View++Associated data object} A \italic{view} may have an associated \italic{dataobject}. Typically, an instance of \italic{view} displays a \italic{dataobject} in a rectangular area on the workstation display. Usually the data object is displayed because a user wishes to view or change the data. The class \italic{view} is responsible for managing the display of the data and the interaction with the user; the class \italic{dataobject} is responsible for maintaining the data, including storing and manipulating it. In general, views represent the input/output interface to data objects; data objects represent memory or permanent storage. Together with the class \italic{dataobject}, the class \italic{view} provides an architecture that supports multiple views of a single data object. For example, a document may contain both a graphical and a tabular view of the same underlying numerical data. When the user changes the numbers in the table, the table and the graph can each adjust accordingly. Likewise, a text editor may display the same document in more than one window, with changes reflected appropriately in each. \begindata{bp,17209696} \enddata{bp,17209696} \view{bpv,17209696,0,0,0} \subsection{Subclassing view} \indexi{View++Subclassing} Suppose that \italic{spreadsheetview} is a subclass of the class \italic{view}. Then \example{struct spreadsheetview *ssv; ssv = spreadsheetview_New();} creates an instance of \italic{spreadsheetview}; \italic{ssv} points to the newly created instance. Since \italic{ssv} is a \italic{view}, it inherits \italic{view}'s data and methods. The writer of \italic{spreadsheetview} must override many of the \italic{view} methods. When \italic{spreadsheetview_New} is called, it initializes all the data associated with an instance of \italic{spreadsheetview}, including the data associated with the class \italic{view}. The system first calls \italic{view_InitializeObject}, then \italic{spreadsheetview_InitializeObject}. All the \italic{InitializeObject} routines are called automatically in the \italic{New} class procedures; you never call them directly. If you were creating the class \italic{spreadsheetview}, you would need to create \italic{spreadsheetview_InitializeObject}. \indexi{ \italic{New}} \indexi{ \italic{InitializeObject}} \example{class spreadsheetview: view \{ classprocedures: boolean; InitializeObject(struct spreadsheetview *view) returns FinalizeObject(struct spreadsheetview *view); data: boolean HasInputFocus; short nLines; short nRows; struct keystate *keystate; \};} Because spreadsheet has data, you must declare an \italic{InitilalizeObject} class procedure: \example{boolean spreadsheetview__InitializeObject(classID, ssv) struct classheader *classID; struct spreadsheetview *ssv; \{ ssv->HasInputFocus = FALSE; ssv->nLines=0; ssv->nRows=0; ssv->keystate = keystate_Create(ssv, ssvKeymap); return TRUE; \}} \formatnote{ Similarly, to delete an instance of \italic{spreadsheetview}, its \italic{Destroy} routine is called. procedure This will automatically call the \italic{FinalizeObject} for \italic{spreadsheetview}, if it is declared. As an application programmer, you never call \italic{FinalizeObject} directly. The \italic{FinalizeObject }procedure is normally used to delete any allocated memory associated with the instance being deleted. In this case the\italic{FinalizeObject} procedure would destroy its keystate. \indexi{ \italic{FinalizeObject}} \example{void spreadsheetview__FinalizeObject(classID, ssv) struct classheader *classID; struct spreadsheet *ssv; \{ if (ssv->keystate != NULL) keystate_Destroy(ssv->keystate); \} } } \paragraph{Associating a view with a data object} \indexi{View++Associated data object} \indexi{ \italic{view_SetDataObject}} \example{void view_SetDataObject(v, dataobj) struct view *v; struct dataobject *dataobj;} \leftindent{\bold{Method description. }\italic{view_SetDataObject} associates the view \italic{v} with the dataobject \italic{dataobj}. \bold{Side effect.} observers. Adds \italic{v} to \italic{dataobj}'s list of \bold{Usage.} Before drawing in a newly created instance of a \italic{view}, you should call \italic{view_SetDataObject} in order to associate the data object with the view and to add the view to the data object's list of observers. A \italic{view} may have only one data object at a time, but you can reassign a view to another data object. When defining a subclass of \italic{view}, you may override \italic{SetDataObject}. It is a convenient place for initializing \italic{view} data that depends on \italic{dataobject} data. If you override it, you should call \italic{super_SetDataObject} within the method. \bold{Example.} Before drawing the data object \italic{txt} in the newly created view \italic{txtview}, the call to \italic{view_SetDataObject} associates \italic{txtview} with \italic{txt} and adds \italic{txtview} to \italic{txt}'s list of observers. \example{struct text *txt; struct textview *txtview; txt = text_New(); txtview = textview_New(); } \begindata{bp,17177928} \enddata{bp,17177928} txtview_SetDataObject(txtview, txt);} \view{bpv,17177928,1,0,0} \subsection{The view tree}\indexi{View tree} Views are organized in a tree structure. Prior to any events being sent to a view it must be added to a tree. There is a view tree associated with each window opened on the display. For each window there is an interaction manager (im) view that is the root of the view tree. All views in the view tree have a pointer to the \italic{im} view that is the root of the tree. (See Overview, Vol. I for more detail on the Toolkit view tree). \paragraph{Adding a view into the view tree} \indexi{View++Adding to view tree}\indexi{ tree++Adding view} \indexi{ \italic{view_LinkTree}} \example{void view_LinkTree(childview, parentview) struct view *childview; struct view *parentview;} \leftindent{\bold{Method description. }\italic{view_LinkTree} links \italic{childview} (and its descendants) into \italic{parentview}'s view tree. This sets the parent pointer in the child to point to the parent. It sets \italic{childview}'s \italic{im} pointer to be the same as \italic{parentview}'s \italic{im} pointer. It also associates a graphical object with the child that is of the same type as the parent. \italic{view_LinkTree} can also be called with a \smaller{NULL} parentview. This is used to invalidate the \italic{graphic} and \italic{im} pointer associated with \italic{childview}. When \italic{parentview} is \smaller{NULL}, the parent field for the view should not be reset. \bold{Usage. } Before drawing in a child view or passing events to it, the parent should make a call to the child's \italic{LinkTree} method. When the child receives a call to its \italic{LinkTree} method it must call the \italic{LinkTree} method for all of its children. When the entire view tree is built, each view will have pointers to graphic objects of the type defined by the \italic{im} object. } \paragraph{Removing a view from the view tree} \indexi{View tree++Removing view} \indexi{View++Removing from view tree} \example{void view_UnlinkTree(rview) struct view *rview;} \leftindent{\bold{Method description. }\italic{view_UnlinkTree} removes \italic{rview} (and its descendants) from its current view tree. This method begins a notification procedure that notifies other views in the view tree that this subtree is being removed. It also must invalidate the \italic{graphic} objects associated with each of its children. The default \italic{UnlinkTree} method calls \italic{view_UnlinkNotification} on its parent, sets its parent pointer to \smaller{NULL}, then calls \italic{LinkTree} on itself with a \smaller{NULL} parent parameter. In most cases this method need not be overridden. \bold{Usage.} Whenever a view is being removed from a view tree it must be unlinked using this method. } \begindata{bp,17289124} \enddata{bp,17289124} \view{bpv,17289124,2,0,0} \paragraph{Notifying views of changes in the view tree} \indexi{View++Notifying changes} \indexi{View tree++Changes in} \indexi{ \italic{view_UnlinkNotification}}\example{void view_UnlinkNotification(v, unlinkedview) struct view *v; struct view unlinkedview;} \leftindent{\bold{Method description. }\italic{view_UnlinkNotification} is used to notify the view \italic{v} that the subtree \italic{unlinkedview} is being removed from the view tree. If \italic{v} has cached any pointers to views in the view tree, it must determine if any of those cached views are being removed. This is done via a call to the \italic{view_IsAncestor} method of the cached views with \italic{unlinkedview} as the second parameter. If that method returns true, the cached information must be invalidated. The \italic{UnlinkNotification} must also be passed up the tree. The default action for this method is to call the \italic{UnlinkNotification} method for the parent of \italic{v}. \bold{Usage.} This method is only called by the \italic{UnlinkTree} method. } \paragraph{Determining if a view is an ancestor of another view} \indexi{View++Finding ancestor} \indexi{Ancestors} \indexi{ \italic{view_IsAncestor}}\example{boolean view_IsAncestor(v, ancestor) struct view *v; struct view *ancestor;} \leftindent{\bold{Method description.} \italic{view_IsAncestor} returns true if \italic{ancestor} equals \italic{v} or is an ancestor of \italic{v}. The default method returns true if the two parameters are equal or the value of a recursive call to the parent of \italic{v}. This method is normally not overridden. } \subsection{Bringing a view onto the screen } \example{void view_ExposeSelf(v, recurse) struct view *v; boolean recurse; } \leftindent{\bold{Method description.} \italic{view_ExposeSelf} causes \italic{v} to request that its parent make it visible. This is done by calling the parent's \italic{ExposeChild} method. (See below.) If \italic{recurse} is TRUE, \italic{view_ExposeSelf} then calls the parent's \italic{ExposeSelf} method, with \italic{recurse} TRUE. This makes the parent in turn visible, and so on up the view tree, until (hopefully) the original is visible in every level up to the top window. \bold{Usage.} By anyone who wants to. \bold{Overriding.} In general, there is no need to override this method when writing new subclasses of view. } \example{void view_ExposeChild(v, childv) struct view *v, *childv; } \leftindent{\bold{Method description.} \italic{view_ExposeChild} causes \italic{v} to bring its child view \italic{childv} into its visible region -- usually by panning or scrolling itself. If \italic{childv}'s parent is not \italic{v}, the results are undefined. \bold{Usage.} By anyone who wants to. \bold{Overriding.} Each subclass of view must override this method if it supports both insets and any kind of scrolling. } \subsection{Recursively searching the view tree } \example{boolean view_RecSearch(v, pat, toplevel) struct view *v; struct SearchPattern *pat; boolean toplevel; } \leftindent{\bold{Method description.} \italic{view_RecSearch} causes \italic{v} to begin searching itself and all of its child views for the pattern \italic{pat}. (The \italic{search} class contains the methods which use struct SearchPattern *; see that class for details.) The method returns TRUE if the search is successful (for \italic{v} or any child), FALSE otherwise. If \italic{toplevel} is TRUE, the search is being begun at this view; this generally means that \italic{v} should begin searching at the cursor or selection point. If FALSE, the search is entering from the parent view, and the view should begin searching at the beginning. \bold{Usage.} By anyone who wants. One usually calls \italic{view_RecSrchExpose(v)} after a successful \italic{view_RecSearch}, in order to make the match visible on the screen. \bold{Overriding.} Any subclass of view which wants to support recursive search must override this method. The default simply returns FALSE. A view that is a wrapper for other views (matte, scroll, im, lpair, etc) should call this method on its child(ren) and return the result. A view that actually contains data should search through the data, calling this method on any child views. If it finds a match, it must cache the location of the result, so that RecSrchResume and RecSrchReplace calls can be handled properly. } \example{boolean view_RecSrchResume(v, pat) struct view *v; struct SearchPattern *pat; } \leftindent{\bold{Method description.} \italic{view_RecSrchResume} causes \italic{v} to continue a recursive search. The method returns TRUE if the search is successful (for \italic{v} or any child), FALSE otherwise. \bold{Usage.} By anyone who wants. The search must already have been started with a successful call to \italic{view_RecSearch} or \italic{view_RecSrchResume}. One usually calls \italic{view_RecSrchExpose(v)} after a successful \italic{view_RecSrchResume}, in order to make the match visible on the screen. \bold{Overriding.} Any subclass of view which wants to support recursive search must override this method. The default simply returns FALSE. A view that is a wrapper for other views (matte, scroll, im, lpair, etc) should call this method on its child(ren) and return the result. A view that actually contains data should continue its search, starting at the location that was cached by a previous RecSearch or RecSrchResume. If this location is inside a child view, \italic{view_RecSrchResume} should be called on that child and the result returned. Otherwise, continue searching as RecSearch did. } \example{boolean view_RecSrchReplace(v, srcob, srcpos, srclen) struct view *v; struct dataobject *srcob; long srcpos, srclen; } \leftindent{\bold{Method description.} \italic{view_RecSrchReplace} causes \italic{v} to replace the result of a previous recursive search. It is replaced with part of the contents of \italic{srcob}, as defined by \italic{srcpos} and \italic{srclen}. (The meaning of these values depends on the type of \italic{srcob}. If it is a subclass of simpletext, they simply indicate the start-position and length of the chunk of text to use.) The method returns TRUE if the replace is successful, FALSE otherwise. If the type of \italic{srcob} does not match the view that is being modified, the method will return FALSE. (Note that the view being modified may be \italic{v}, or any descendant of \italic{v}.) \bold{Usage.} By anyone who wants. The search must already have been started with a successful call to \italic{view_RecSearch} or \italic{view_RecSrchResume}. One usually calls \italic{view_RecSrchExpose(v)} after a successful \italic{view_RecSrchReplace}, in order to make the new match visible on the screen. \bold{Overriding.} Any subclass of view which wants to support recursive search must override this method. The default simply returns FALSE. A view that is a wrapper for other views (matte, scroll, im, lpair, etc) should call this method on its child(ren) and return the result. A view that actually contains data should replace the contents of the location that was cached by a previous RecSearch or RecSrchResume. This may be in a child view, in which case RecSrchReplace should be called on the child and the result returned; or it may be in \italic{v}, in which case v should perform the replacement. The cached rec-search result should be updated to point to the new length of the replacement. }\example{boolean view_RecSrchExpose(v) struct view *v; } \leftindent{\bold{Method description.} \italic{view_RecSrchExpose} causes \italic{v} to make visible the results of a successful recursive search. The method returns TRUE if the search is successful (for \italic{v} or any child), FALSE otherwise. \bold{Usage.} By anyone who wants. The search must already have been started with a successful call to \italic{view_RecSearch} or \italic{view_RecSrchResume}. \bold{Overriding.} Any subclass of view which wants to support recursive search must override this method. The default simply returns FALSE. A view that is a wrapper for other views (matte, scroll, im, lpair, etc) should call this method on its child(ren) and return the result. A view that actually contains data should make visible the match location that was cached by a previous RecSearch or RecSrchResume. If \italic{v} contained the match, it will highlight it and request the input focus; if a child of \italic{v} did, that child will be moved onto the screen (if \italic{v} is a scrolling view) and RecSrchExpose called on the child. } \subsection{Negotiating about the size of a view} \indexi{View++Negotiating size} \paragraph{Setting the size of a child view} \indexi{View++Setting child size} \indexi{ \italic{view_InsertView}} \example{void view_InsertView(childv, parentv, enclosedRectangle) struct view *childv; struct view *parentv; struct rectangle *enclosedRectangle;} \leftindent{\bold{Method description. }\italic{view_InsertView} inserts the child view, \italic{childv}, into the parent view, \italic{parentv}. \bold{Side effect. } The view \italic{childv}'s logical and visible rectangles are set to the values provided by \italic{enclosedRectangle}. \bold{Usage.} If you are creating a child view, the parent should call \italic{view_InsertView} to set rectangle parameters for the child. Normally you would make the call at the end of a size negotiation and before calling the child's \italic{FullUpdate} method. } \begindata{bp,17289076} \enddata{bp,17289076} \view{bpv,17289076,3,0,0} \paragraph{Specifying the desired size of the view} \indexi{View++Desired size} \indexi{ \italic{view_DesiredSize}} \example{enum view_DSattributes view_DesiredSize(childv, width, height, pass,desiredWidth, desiredHeight) struct view *childv; long width; long height; enum view_DSpass pass; long *desiredWidth; long *desiredHeight; } \leftindent{\bold{Method description.} \italic{view_DesiredSize} is used to conduct size negotiations between a parent and child view. The parameters for \italic{height} and \italic{width} are filled with the parent's preferred values; the \italic{pass} parameter tells the child which parameters are flexible and which are fixed. The \italic{desiredWidth} and \italic{desiredHeight} parameters are for the child to pass back what it would like for its size. \italic{view_DesiredSize} may be called several times as the parent negotiates with its child. of three values: The parameter \italic{pass} can take on one \leftindent{\description{\smaller{view_NOSET}\formatnote{ dimensions are flexible. \smaller{view_WIDTHSET}\formatnote{ \smaller{view_HEIGHTSET}\formatnote{ -- -- }Both }The width cannot be changed. -- }The height cannot be changed. } } In response to these three parameters, \italic{view_DesiredSize} sets the \italic{desiredWidth} and \italic{desiredHeight}. \bold{Return value.} The return value is a \italic{DSattributes} and can be set to an \smaller{OR-ed} combination of any of the following values: \leftindent{\formatnote{\smaller{view_FIXED}\formatnote{ is fixed, that is, not flexible. \smaller{view_WIDTHSMALLER}\formatnote{ smaller. \smaller{view_WIDTHLARGER}\formatnote{ larger. -- -- -- }The size }The width could be made }The width could be made \smaller{view_WIDTHFLEXIBLE}\formatnote{ -- }The width is flexible. \smaller{view_HEIGHTSMALLER}\formatnote{ smaller. -- }The height could be made \smaller{view_HEIGHTLARGER}\formatnote{ larger. -- \smaller{view_HEIGHTFLEXIBLE}\formatnote{ }} }The height could be made -- }The height is flexible. \italic{view_DesiredSize} returns \smaller{view_HEIGHTFLEXIBLE | view_WIDTHFLEXIBLE}. If you are creating a subclass of the class \italic{view} named \italic{x} and you want to negotiate the size of \italic{x}, you should return a value that is appropriate. The default method sets \italic{desiredWidth} and \italic{desiredHeight} to \italic{width} and \italic{height} respectively. It returns \smaller{view_NOSET}. \bold{Usage.} The process of negotiating between the parent's proposal and the child's request will normally take place during the call to the \italic{FullUpdate }of the parent. The actual size and position of the view \italic{childv} must be set prior to the parent calling the \italic{FullUpdate} procedure of \italic{childv}. } \begindata{bp,17289028} \enddata{bp,17289028} \view{bpv,17289028,4,0,0} \paragraph{Getting the origin of a view} \indexi{View++Getting origin} \indexi{ \italic{view_GetOrigin}} \example{void view_GetOrigin(childview, width, height, originX, originY) struct view *childview; long width; long height; long *originX; long *originY;} \leftindent{\bold{Method description. } view_GetOrigin provides a method for the child view, childview, to communicate with the parent about the placement of the origin of its rectangle. At the end of the size negotiation process, the parent view should call view_GetOrigin for the child view, childview. The parameters width and height should be set to the width and height that the parent is allocating for the child. \italic{view_GetOrigin} should set \italic{originX} and \italic{originY} to the (x,y) coordinate where it would like the parent to place its origin. The default method sets \italic{originX} to 0 and \italic{originY} to 0. \bold{Usage.} If you are creating a subclass of the class view named \italic{x}, you might want to override \italic{view_GetOrigin}. \italic{x_GetOrigin} should set \italic{originX} and \italic{originY} to appropriate values. This method is used when the parent view wants to line up the child view to a reference point. For example lines of text have a baseline and a view that is being inserted inline should be positioned properly along that baseline. } \paragraph{Requesting a new size} \indexi{View++Request new size} \indexi{ \italic{view_WantNewSize}} \example{void view_WantNewSize(requestor, requestee) struct view *requestor; struct view *requestee;} \leftindent{\bold{Method description.} \italic{view_WantNewSize} provides a method for a view, \italic{requestor} to request the view \italic{requestee} to begin a desired size negotiation. \bold{Usage.} A child view should request size negotiations from its parent by calling this method. } \begindata{bp,17288980} \enddata{bp,17288980} \view{bpv,17288980,5,0,0} \subsection{Requests for full updates and updates} \indexi{View++Full updates} \indexi{View++Updates}\indexi{ate} \indexi{Full update} All real resources allocated to a view may be changed at any time by the underlying \italic{window manager}. The specific things that can change are: \description{1. pixels). The size of the view (i.e., the width and height in 2. The underlying display. }The size of a view can change whenever the user takes an action which requires the underlying \italic{window manager} to allocate space on the display. The display may change if the user is working with multiple displays. The user may move a window from one display to another with different characteristics. The display change may, for example, affect the fonts that are being used by the view. Whenever any resources are changed, a call to the view's \italic{FullUpdate} method will be made; your class must provide a \italic{FullUpdate} method. \paragraph{Working with full update requests} \indexi{View++Full updates} \indexi{ \italic{view_FullUpdate}} \example{void view_FullUpdate(v, type, left, top, width, height) struct view *v; enum view_UpdateType type; long left; long top; long width; long height;} \leftindent{\bold{Method description.} \italic{view_FullUpdate} provides a method for communicating about the need for full updates. For example, if \italic{v} were a view in a window and the window changed size, a call to the view's \italic{FullUpdate} method is made to notify the view \italic{v }that it should do an update. The parameter \italic{type} specifies the type of update to be done. It can be one of the following: \formatnote{ \italic{view_FullRedraw}\formatnote{ -- }The view should be completely redrawn. The parameters left, top, width and height are ignored. \italic{view_PartialRedraw}\formatnote{ within the rectangle -- }The view should be redrawn specified by the parameters \italic{left}, \italic{top}, \italic{width}, and \italic{height}; further partial redraws will follow. A view receiving this call may defer the update until it receives the LastPartialRedraw. \italic{view_LastPartialRedraw}\formatnote{ redrawn within the rectangle -- }The view should be specified by the parameters \italic{left}, \italic{top}, \italic{width}, and \italic{height}; this is the last partial redraw. \italic{view_MoveNoRedraw}\formatnote{ occurring because the view is being moved. -- }The redraw request is If the view has posted cursors they should be reposted. \italic{view_Remove}\formatnote{ because the view is being removed from the screen. -- }The redraw request is occurring The view should remove all cursors that it has posted. } \bold{Usage.} If you are creating a subclass of the class \italic{view}, you should override \italic{view}'s \italic{FullUpdate} method. If you fail to supply this method, it will default to its parent method. The default method \italic{view_FullUpdate} is a no-op. A view must call \italic{FullUpdate} for all of its child views. } \paragraph{Requesting an update} \indexi{Updates++Requesting} \indexi{View++Requesting updates} \indexi{ \italic{view_WantUpdate}}\example{void view_WantUpdate(v, updateView) struct view *v; struct view *updateView;} \leftindent{\bold{Method description.} \italic{view_WantUpdate} reqeusts an update for view \italic{updateView} from view \italic{v}. This will result in a later call to \italic{v}'s \italic{Update} method. \bold{Usage.} If a view to update its image, it should call \italic{view_WantUpdate} with both arguments set to itself. You should always use the \italic{view_WantUpdate} procedure to notify a parent view that a view needs an update, rather than calling \italic{view_Update} directly. \italic{WantUpdate} requests are passed up the view tree. If a view is interested in controlling the order of updates of its descendants, it intercepts the update request, caching a pointer to the \italic{updateView}. It then passes itself up the tree as the \italic{updateView}. At some later time its \italic{Update} method will be called. During the processing of that update request it calls the \italic{Update} method for the view that it has cached. The default method passes the update request directly up to view's parent. This method should be overridden if a view needs to control the order of updates of its own image and its children. \bold{Example.} The following is a centering method written for \italic{helloworldview}. Note that \italic{WantUpdate} is called at the end. \example{ static void Center(hwv, key) struct helloworldview *hwv; long key; \{ hwv->newX = hwv->header.graphic.rectangle.width /2; hwv->newY = hwv->header.graphic.rectangle.height /2; helloworldview_WantUpdate(hwv, hwv); \} } } \begindata{bp,17189576} \enddata{bp,17189576} \view{bpv,17189576,6,0,0} \paragraph{Notifying a view that it should do an update} \indexi{Updates} \indexi{View++Updates} \indexi{ \italic{view_Update}}\example{void view_Update(v) struct view *v;} \leftindent{\bold{Method description.} \italic{view_Update} is used to do an incremental update to a view's image. The size of the view and its graphics characteristics will not have changed since the last call to \italic{FullUpdate}. \bold{Usage.} If your view needs an update, you should not call \italic{Update} directly; instead, you should call \italic{WantUpdate} to request an update from your parent. This will eventually result in a call to the view's \italic{Update} method. The default method \italic{view_Update} is a no-op. \bold{Example.} The following method is the \italic{Update} method for the view \italic{helloworldview}. Whereas \italic{FullUpdate} redraws the entire window, \italic{Update} only redraws the text string. \example{ void helloworldview__Update(hwv) struct helloworldview *hwv; \{ if (hwv->newX != hwv->x || hwv->newY != hwv->y) \{ helloworldview_SetFunction(hwv, graphics_INVERT); helloworldview_MoveTo(hwv, hwv->x, hwv->y); helloworldview_DrawString(hwv, "hello world", graphic_BETWEENTOPANDBASELINE | graphic_BETWEENLEFTANDRIGHT); hwv->x = hwv->newX; hwv->y = hwv->newY; helloworldview_MoveTo(hwv, hwv->x, hwv->y); helloworldview_DrawString(hwv, "hello world", graphic_BETWEENTOPANDBASELINE | graphic_BETWEENLEFTANDRIGHT); \} \} } } \paragraph{Observing that the data object has changed} \indexi{View++Observing data object} \indexi{Data objects++Observing} \indexi{ \italic{view_ObservedChange}}\example{void view_ObservedChanged(v,changedobj, status) struct view *v; struct observable *changedobj; long status;} \leftindent{\bold{Method description.} \italic{view_ObservedChanged} checks the value of \italic{status}. If \italic{status} has the value \italic{observable}_\smaller{OBJECTDESTROYED}, \italic{view_ObservedChanged} removes the \italic{changedobj} from \italic{v}; otherwise it calls \italic{view_WantUpdate} to request an update for \italic{v}. \italic{view_ObservedChanged} overrides \italic{observable_ObservedChanged}. } \begindata{bp,17189528} \enddata{bp,17189528} \view{bpv,17189528,7,0,0} \subsection{The input focus} At any one instance, a single view in the view tree has the input focus. \paragraph{Requesting the input focus}\indexi{Input focus} \indexi{View++Requesting input focus} \indexi{ \italic{view_WantInputFocus}}\example{void view_WantInputFocus(v, requester) struct view *v; struct view *requester;} \leftindent{\bold{Method description. }\italic{view_WantInputFocus} used when the view wants the input focus. is \bold{Usage.} A view requests the input focus by making a call to its own \italic{WantInputFocus} method with itself as the requestor. The default method passes this request up the tree. If a view want to control the granting of the input focus to its children, its \italic{WantInputFocus} method should cache the requesting view and call \italic{WantInputFocus} on its parent with itself as the requestor. It is normally the case that the default method is not overridden. } \paragraph{Receiving the input focus}\indexi{Input focus} \indexi{View++Receiving input focus} \indexi{ \italic{view_ReceiveInputFocus}}\example{void view_ReceiveInputFocus(v) struct view *v;} \leftindent{\bold{Method description.} \italic{view_ReceiveInputFocus} provides a way for the \italic{Interaction Manager} to inform an object that it has received the input focus. This method must post the keystates and menus associated with the view. This method should also set a flag in the view's data structure that will cause it to highlight itself to indicate that it has the input focus. \bold{Example.} The following example, from \italic{helloworldview}, illustrates the typical set-up for \italic{ReceiveInputFocus}. The flag \italic{haveInputFocus} is set to \smaller{TRUE}, to indicate the \italic{hwv} has received the input focus; \italic{PostKeyState} posts the key state to the \italic{Interaction Manager}; \italic{PostMenulist} posts the menus. \example{void helloworldview__ReceiveInputFocus(hwv) struct helloworldview *hwv;\{ hwv->haveInputFocus = TRUE; hwv->keystate->next = NULL; helloworldview_PostKeyState(hwv, hwv->keystate); helloworldview_PostMenulist(hwv, hwv->menulist); helloworldview_WantUpdate(hwv, hwv); \} } } \begindata{bp,17189480} \enddata{bp,17189480} \view{bpv,17189480,8,0,0} \paragraph{Giving up the input focus} \indexi{Input focus} \indexi{View++Losing input focus} \indexi{ \italic{view_LoseInputFocus}}\example{void view_LoseInputFocus (v) struct view *v;} \leftindent{\bold{Method description. }The \italic{Interaction Manger} will call a view's \italic{view_LoseInputFocus} to notify the view \italic{v} that it is losing the input focus. The method \italic{view_LoseInputFocus} need only cause the view to dehighlight itself, indicating that it no longer has the input focus. \bold{Example.} Here is the corresponding \italic{LoseInputFocus} for the \italic{helloworldview_ReceiveInputFocus} example above. \example{void helloworldview__LoseInputFocus(hwv) struct helloworldview *hwv;\{ hwv->haveInputFocus = FALSE; helloworldview_WantUpdate(hwv, hwv); \}} } \subsection{User input}\indexi{User input} \indexi{View++User input} The Andrew Toolkit distinguishes three kinds of user input : 1) mouse events, 2) key events, and 3) menu events. The class \italic{view} provides methods for working with two buttons associated with the mouse (left and right). Applications can detect up and down transitions of the left and right buttons. Applications can also detect movement with the left or right button depressed, but cannot detect mouse movement when no buttons are depressed. \paragraph{Mouse hits} \indexi{Mouse hits} \indexi{View++Mouse hits} \indexi{ \italic{view_Hit}} \example{struct view *view_Hit(v, action, x, y, numberOfClicks) struct view *v; enum view_MouseAction action; long x; long y; long numberOfClicks;} \leftindent{\bold{Method description.} \italic{view_Hit} notifies view \italic{v} that a mouse hit has occurred within the boundaries of its visual rectangle. The parameter \italic{action} defines the type of mouse input that has occurred and can have the following values: \formatnote{\italic{view_NoMouseEvent}\formatnote{ \italic{view_LeftDown}\formatnote{ \italic{view_LeftUp}\formatnote{ -- -- }No mouse action. }Left button pressed down. }Left button let up. \italic{view_LeftMovement}\formatnote{ has moved. \italic{view_RightDown}\formatnote{ -- -- -- }Left button down and mouse }Right button pressed down. \italic{view_RightUp}\formatnote{ -- \italic{view_RightMovement}\formatnote{ has moved. }Right button let up. -- }Right button down and mouse } The coordinates \italic{x} and \italic{y} provide the location of the the mouse event, relative to the views own coordinate system. The parameter \italic{numberOfClicks} is the number of times the mouse button was clicked at that location. The method \italic{view_Hit} is a no-op method that accepts the mouse event, takes no action and returns a pointer to itself. \bold{Return value.} \italic{view_Hit} returns the view that accepted the mouse event. The return value is used to pass all subsequent mouse events, until and including the up transition to that view. If the view accepts the mouse event it should return itself. If it passes the event to one of its children it should return the value returned by the child's \italic{Hit} method. \bold{Usage.} If you are creating a subclass of the class \italic{view} and you want to respond to any of the mouse actions specified by \italic{view_MouseAction}, you must override this method. If a view is passing a mouse event to one of its children it must translate the coordinates from its coordinate space to its child's coordinate space (using the methods \italic{view_EnclosedXToLocalX} and \italic{view_EnclosedYToLocalY}, described in \bold{Graphics}). See Example 2, Vol. I for more information about \italic{view_Hit}. \bold{Example.} The example below concerns mouse input for the view \italic{helloworldview}. When either mouse button is hit (\smaller{view_LeftDown, view_RightDown}), \italic{newx}, \italic{newy} is calculated and made the new "current" position for the text string. Then, the procedure requests an update so that the string can be redrawn in the new position. \programexample{ struct helloworldview *helloworldview__Hit(hwv, action, x, y, numberOfClicks) struct helloworldview *hwv; enum view_MouseAction action; long x; long y; long numberOfClicks; /* unused */ \{ if (action == view_LeftDown || action == view_RightDown) \{ hwv->movingString = TRUE; \} else if (hwv->movingString) \{ if (action == view_LeftUp || action == view_RightUp) \{ hwv->newX = x; hwv->newY = y; hwv->movingString = FALSE; helloworldview_WantUpdate(hwv, hwv); \} \} return hwv; \} } } \begindata{bp,17189432} \enddata{bp,17189432} \view{bpv,17189432,9,0,0} \paragraph{Keyboard input} \indexi{Keyboard input} Unlike mouse events, key events are handled directly by the top level \italic{im} view. A view post a keystate to its parent. The keystate provides a mapping from key sequences to routines. The parent can add its own keystate and passes the combined set further up the tree. When a sequence of characters is received by the \italic{im} view it determines the appropriate routine to call along with the view that posted it. Even though the key event is not passed down the view tree, a view still can maintain control over its descendants. When a view's \italic{PostKeyState} method is called it can add in its own keystate that overrides the keystate being passed up by its child. \example{void view_PostKeyState(v, kstate) \indexi{View++Posting key state} \indexi{ \italic{view_PostKeyState}} struct view *v; struct keystate *kstate;} \leftindent{\bold{Method description. }\italic{view_PostKeyState} posts the keystate \italic{kstate} for the view \italic{v}. \bold{Usage.} When a view receives the input focus it must post its associated keystate. If the view has no associated keystate it should post a \smaller{NULL} keystate. The default method posts \italic{kstate} to \italic{v}'s parent. If a view want to add in its own keystate it must override this method. See Example 4, Vol. I for more detail on how to use \italic{PostKeyState}. } \paragraph{Menus} \indexi{Menus} Like key events, menu events are also processed by the \italic{im} view. A view posts its list of menu items. Each menu item is a mapping from menu strings to procedures. The \italic{im} view receives a set of menulists and posts the menus to the underlying window system. When a user selects one of the menu items the associated procedure is called. A view can control the set of menus posted by its descendants by adding in its own menus and passing the combined set up the tree. \example{void view_PostMenus(v, menulist) \indexi{View++Posting menus} \indexi{ \italic{view_PostMenus}} struct view *v; struct menulist *menulist;} \leftindent{\bold{Method description. } \italic{view_PostMenus} used to post the menus in\italic{ menulist} for the view \italic{v}. is \bold{Usage.} When a view receives the input focus it must post its associated menulist. If the view has no associated menulist it should post a \smaller{NULL} menulist. The view also posts menus whenever the set of menus to be displayed changes. The default method posts \italic{menulist} to \italic{v}'s parent. If a view want to add in its own menulist it must override this method. See Example 5, Vol. I for more detail about how to use \italic{PostMenus}. } \begindata{bp,17189384} \enddata{bp,17189384} \view{bpv,17189384,10,0,0} \subsection{Cursors} \indexi{Cursors} The Toolkit uses a cursor to provide feedback to the user about the system. A view can create a cursor and request its use to provide feedback across an entire window (e.g., an hourglass to indicate that the user should wait) or to use it to provide feedback on movement only within the confines of its rectangle (e.g., a scrollbar cursor within a scrollbar view). For more information, see the chapters \bold{Cursor}, \bold{Menu}, and \bold{Scroll}. \paragraph{Posting a cursor} \indexi{View++Posting cursors} \indexi{ \italic{view_PostCursor}}\example{void view_PostCursor(v, rect, c) struct view *v; struct rectangle *rect; struct cursor *c;} \leftindent{\bold{Method description. }\italic{view_PostCursor} requests the display of the cursor \italic{c} whenever the user moves the mouse within the \italic{v}'s rectangle \italic{rect}. The view can only post a cursor over its assigned rectangle. This request is passed up the view tree. A higher level view may choose to block the posting of the cursor by not passing the request further up the tree. Cursors that are posted over the same physical screen space are ordered by time of posting, with the latest posted cursor appearing on the screen. \bold{Usage.} Normally, an object will create a cursor and set its shape in its \italic{Initialize} method and post/repost the cursor in its \italic{FullUpdate} method. When redefining the shape of an already posted cursor, it is not necessary to repost it. All cursors posted by a view must be reposted on a call to its \italic{FullUpdate} method. A view that uses cursors should destroy them in its \italic{FinalizeObject} method. (See Example 19, Vol. I). \bold{Example.} The following code segments will keep a cross cursor posted over the view \italic{mv}, an instance of \italic{myview}. In this case, the cursor object is created in \italic{mv}'s i[InitializeObject] procedure and stored as part of the object's data. Note that \italic{mv->myCursor} is of type \italic{struct cursor *}. \example{ myview__InitializeObject(...) \{ ... mv->myCursor = cursor_Create(mv); cursor_SetStandard(mv->myCursor,Cursor_Cross); ... \} myview__FullUpdate(mv,...) \{ ... struct rectangle tr; myview_GetVisualBounds(mv,&tr); myview_PostCursor(mv,&tr,mv->myCursor); ... \} myview__FinalizeObject(...) \} \{ ... } }\paragraph{Retracting a cursor} cursor_Destroy(mv->myCursor); \indexi{View++Retracting cursors} \indexi{ \italic{view_RetractCursor}} \example{void view_RetractCursor(v, c) struct view *v; struct cursor *c;} \leftindent{ \bold{Method description.} \italic{view_RetractCursor} \italic{v}'s cursor \italic{c}. } \paragraph{Retracting all of a view's cursors} retracts ... \indexi{View++Retracting all cursors} \indexi{ \italic{view_RetractViewCursors}} \example{void view_RetractViewCursors(v, requestor) struct view *v; struct view *requestor;} \leftindent{ \bold{Method Description.} \italic{view_RetractViewCursors} retracts all of the cursors associated with the view \italic{requestor} (but not with it's children). \bold{Usage.} Parent views should call this routine on their children before calling the child's \italic{FullUpdate} routine. \bold{Example.} \italic{v}: The following call retracts all the cursors from a view \example{view_RetractViewCursors(v, v);} } \begindata{bp,17189336} \enddata{bp,17189336} \view{bpv,17189336,11,0,0} \subsection{Handlers}\indexi{Handlers} A handler is an object that provides a specific set of functions. A view can request a pointer to a handler from its parent. A view can request a handler from its parents. It should do so whenever it wants to make a sequence of calls to the handler. Normally the requesting of a handler is hidden from the programmer by an additional package. The package provide an interface that first requests the handler and then makes the method call provided by the handler. The only handler used in the Toolkit at this time is the \italic{messages} handler. \indexi{Message handlers} Normally one view in the view tree will provide a handler for all the views in the tree. Since handlers are going to be provided by views other than the root view, it is necessary to be able to post a default handler to the root. This handler is used by views that are not descendants of the view providing the handler. \paragraph{Requesting a handler} \indexi{View++Requesting handler} \indexi{ \italic{view_WantHandler}}\example{struct basicobject *view_WantHandler(v, handlerName) struct view *v; char *handlerName;} \leftindent{\bold{Method description. }\italic{view_WantHandler} requests the handler, \italic{handlerName}. The default method is to pass the request up the view tree. This method is normally overridden if the view is going to provide a handler. \bold{Return value.} A pointer to a handler corresponding to \italic{handlerName}, or \smaller{NULL} if there is none. \bold{Usage.} Used by the package \italic{message}. } \paragraph{Posting the default handler for a view} \indexi{View++Posting default handler} \indexi{ \italic{view_PostDefaultHandler}}\example{void view_PostDefaultHandler(v, handlerName, handler) struct view *v; char *handlerName; struct basicobject *handler;} \leftindent{ \bold{Method description.} \italic{view_PostDefaultHandler} posts a default handler to the parent view. The default method passes this information to its parent. This method is overridden only if a view is posting its own default handles and want to prevent its children from posting corresponding default handlers. } \begindata{bp,17440504} \enddata{bp,17440504} \view{bpv,17440504,12,0,0} \subsection{The application layer} \indexi{Application layer} \indexi{View++Application layer} Many views are used in two contexts, as components in programs and in user applications. For example, \italic{textview} is used by the class \italic{frame} to build the message line and it is also used by the application program\bold{ ez}. When used as a component in other programs, it might be inappropriate for \italic{textview} to present itself with a scroll bar. For example, the class \italic{label} may want to use \italic{textview} as a component for presenting labels on drawings. However, when used in an user application like a text-editor, the scroll bar is appropriate. The class \italic{view} provides two methods, \italic{GetApplicationLayer} and \italic{DeleteApplicationLayer}, that allow views to present a second view of themselves that is appropriate for applications. The multi-media editor \bold{ez} uses these methods. When the multi-media editor encounters an arbitrary application's \italic{dataobject} and \italic{view}, it calls the view's \italic{GetApplicationLayer} method. This method should create and return an appropriate user application view of its \italic{dataobject}. For example, \italic{textview} returns a view consisting of a view of the text and a scroll bar; a drawing application might return a view consisting of a palette, two scroll bars and a view of the drawing. When the application view is about to be deleted, the multi-media editor calls \italic{DeleteApplicationLayer}. This method should destroy the application layer view that \italic{GetApplicationLayer} created earlier. \paragraph{Getting the application layer} \indexi{View++Getting application layer} \indexi{ \italic{view _GetApplicationLayer}}\example{struct view *view_GetApplicationLayer(v) struct view *v;} \leftindent{\bold{Method description. }\italic{view_GetApplicationLayer} provides a method that allows a view \italic{v} to present one view when used in an application and another when used as a component in a program. \italic{view_GetApplicationLayer} assumes that the program component view of \italic{v} and the application view are the same. \bold{Return value.} The default method returns \italic{v}. \bold{Usage.} If you are creating a subclass which will be used both as a program component and in a user application in which you want to present a special application view, you should override view's definition of this method with a definition tailored to your application. \bold{Example.} \italic{Textview} overrides \italic{view}'s definition. When used in an application program, \italic{textview} wraps itself in a scroll bar: \programexample{ struct view *textview__GetApplicationLayer(txtview) struct textview *txtview; \{ return (struct view *) scroll_Create(txtview, scroll_LEFT); \} } } \begindata{bp,17189260} \enddata{bp,17189260} \view{bpv,17189260,13,0,0} \paragraph{Deleting the application layer} \indexi{View++Deleting application layer} \indexi{ \italic{view_DeleteApplicationLayer}} \example{void view_DeleteApplicationLayer(v) struct view *v;} \leftindent{\bold{Method description. }\italic{view_DeleteApplicationLayer} destroys the view \italic{v}'s application layer. \bold{Usage.} If you are creating a subclass which will be used both as a program component and in a user application in which you want to present a special application view, you should override view's definition of this method with a definition tailored to your application. \bold{Example.} Since \italic{textview} overrides \italic{view_GetApplicationLayer}, it must provide an appropriate \italic{textview_DeleteApplicationLayer}: \example{ void textview__DeleteApplicationLayer(txtview, scrollbar) struct textview *txtview; struct scroll *scrollbar; \{ scroll_Destroy(scrollbar); \} } } \subsection{Printing} \indexi{Printing} The Toolkit provides a very simple (and unfortunately inadequate) method for printing. This will be undergoing substantial change in the upcoming months. The current printing model for the Toolkit is to have views generate \italic{troff} descriptions of themselves. These are combined and then fed to troff. In the future we will be heading to a PostScript (trademark, Adobe) model for printing. Objects will generate PostScript descriptions of themselves. These will be combined in a similar fashion as views. The following describes the current call used for printing. \paragraph{Printing the contents of a view} \indexi{View++Printing} \indexi{ \italic{view_Print}}\example{void view_Print(v, file, processor, finalFormat, topLevel) struct view *v; FILE *file; char *processor; char *finalFormat; boolean topLevel;} \leftindent{\bold{Method description. }\italic{view_Print} is called when a view is to be printed out. The view is to generate a description of itself that can be sent through \italic{ditroff}. The flag \italic{topLevel} is set to true if this is the top level view being printed. \bold{Usage.} If you want to print a view \italic{v}, you would call \italic{view_Print} with the name of the view, its file, the processor and the final format to be used, and whether it is a top level view or not. }\ \begindata{bp,17372868} \enddata{bp,17372868} \view{bpv,17372868,14,0,0} \subsection{The scroll bar interface} \indexi{Scroll bar interface} \paragraph{Getting a view's scroll bar interface}\indexi{View++Scroll bar} \indexi{ \italic{view_GetInterface}} \example{char *view_GetInterface(v, type) struct view *v; char *type;} \leftindent{\bold{Method description. }Views can export additional interfaces that can be used to manipulate their data. Another object can get a hold of that interface by making a call to the \italic{GetInterface} method. This method is used by the scroll bar to get a handle on a set of routines that can be used to scroll the view. \bold{Usage. } The default method is a no-op. If a view wants to be scrollable it must override this method to provide an interface when\italic{ type} equals \italic{scroll, vertical} (for vertical scrolling) or \italic{scroll, horizontal} (for horizontal scrolling). (See Example 6 and 7, Vol. I). } \subsection{Resources} The following methods provide the interface between views and the resource facility. \paragraph{Setting the name for a view} \indexi{ \italic{view_SetName}} \example{void view_SetName (v, name) struct view *v; struct atomlist *name;} \leftindent{\bold{Method description.} Provides a \italic{name} for the object when requesting a resource. If this method is not called, a unique name for the view is automatically generated. } \paragraph{Getting the name for a view} \indexi{ \italic{view_GetName}} \example{struct atomlist *view_GetName (v) struct view *v;} \leftindent{\bold{Method description.} Returns an \italic{atomlist} that contains a reference to the name associated with the view \italic{v}. } \begindata{bp,17303392} \enddata{bp,17303392} \view{bpv,17303392,15,0,0} \paragraph{Getting a class for a view} \indexi{ \italic{view_GetClass}} \example{struct atomlist *view_GetClass (v) struct view *v;} \leftindent{\bold{Method description.} Returns an \italic{atomlist} that contains a pointer to the name of \italic{v}'s class. } \paragraph{Getting a parameter for a view} \indexi{ \italic{view_GetParameter}} \example{short view_GetParameter (v, name, type, data) struct view *v; struct atomlist *name; struct atom *type; long *data;} \leftindent{\bold{Method description.} Called to get the value for the resource pointed to by the atomlist \italic{name}. The default method makes a call to \italic{GetResource.} The value of the resource is returned by \italic{data}. The value is converted to the type \italic{type} if at all possible. This method need not be overridden. } \paragraph{Getting a resource for a view} \indexi{ \italic{view_GetResource}} \example{short view_GetResource(v, name, class, type, data ) struct view *v; struct atomlist *name; struct atomlist *class; struct atom *type; long * data;} \leftindent{ \bold{Method description.} Called to request a resource. The default method is to make the same request of \italic{v}'s parent after appending the name of the view to the atomlist \italic{name} and the name of the view's class to the atomlist \italic{class}. The value is returned by \italic{data} after being converted, if possible, to the type \italic{type}. This method should be overridden if a view is going to provide its own resource manager. } \begindata{bp,17372768} \enddata{bp,17372768} \view{bpv,17372768,16,0,0} \paragraph{Getting more than one parameter for a view} \indexi{ \italic{view_GetManyParameters}} \example{void view_GetManyParameters(v, resources, name, class) struct view * v; struct resourceList * resources; struct atomlist * name; struct atomlist * class;} \leftindent{ \bold{Method description.} \italic{view_GetManyParameters} provides a mechanism for requesting multiple resources. The parameter \italic{resources} is a list of items containing the \italic{name} and \italic{type} of resource desired, as well as a \italic{data} and \italic{found} which contain the returned value and a flag indicating whether the resource was found. This method is rarely overridden. } \paragraph{Posting a resource for a view} \indexi{ \italic{view_PostResource}} \example{void view_PostResource (v, path, type, data) struct view *v; struct atomlist *path; struct atom *type; long data;} \leftindent{ \bold{Method description.} The method allows a view \italic{v} to post a value for a resource. The default method passes the request up the view tree after adding the name of the view to the \italic{path}. The value of the resource is contained in \italic{data}, with type indicating its \italic{type}. This method is overridden if the view is maintaining its own resource manager. } \paragraph{Getting the interaction manager for a view tree} \indexi{ \italic{view_GetIM}} \indexi{View++Getting interaction manager} \indexi{View tree++Getting *view_GetIM (v) interaction manage}\example{struct im struct view *v;} \leftindent{\bold{Macro method description.} \italic{GetIM} returns the Interaction Manager object that is currently associated with the view \italic{v}. If \italic{v} is not currently linked into a view tree this method returns \smaller{NULL}. \bold{Usage.} This method is used to get the \italic{im} associated with the view when calling an \italic{im} method from code defined by the view. } \begindata{bp,17303288} \enddata{bp,17303288} \view{bpv,17303288,17,0,0} Copyright 1992 Carnegie Mellon University and IBM. All rights reserved. \smaller{\smaller{$Disclaimer: Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the name of IBM not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL ANY COPYRIGHT HOLDER BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. $ }}\enddata{text,17197468}