1 /*  Part of XPCE --- The SWI-Prolog GUI toolkit
2 
3     Author:        Jan Wielemaker and Anjo Anjewierden
4     E-mail:        jan@swi.psy.uva.nl
5     WWW:           http://www.swi.psy.uva.nl/projects/xpce/
6     Copyright (c)  1985-2002, University of Amsterdam
7     All rights reserved.
8 
9     Redistribution and use in source and binary forms, with or without
10     modification, are permitted provided that the following conditions
11     are met:
12 
13     1. Redistributions of source code must retain the above copyright
14        notice, this list of conditions and the following disclaimer.
15 
16     2. Redistributions in binary form must reproduce the above copyright
17        notice, this list of conditions and the following disclaimer in
18        the documentation and/or other materials provided with the
19        distribution.
20 
21     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
22     "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
23     LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
24     FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
25     COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
26     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
27     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
28     LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
29     CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
30     LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
31     ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
32     POSSIBILITY OF SUCH DAMAGE.
33 */
34 
35 #include <h/kernel.h>
36 #include <h/graphics.h>
37 
38 static status arrowsJoint(Joint, Name);
39 
40 status
initialiseJoint(Joint jt,Int x,Int y,Int w,Int h,Name arrows)41 initialiseJoint(Joint jt, Int x, Int y, Int w, Int h, Name arrows)
42 { initialiseGraphical(jt, x, y, w, h);
43 
44   if ( notDefault(arrows) )
45     arrowsJoint(jt, arrows);
46 
47   succeed;
48 }
49 
50 
51 status
copyJoint(Joint jt1,Joint jt2)52 copyJoint(Joint jt1, Joint jt2)
53 { copyGraphical(jt1, jt2);
54 
55   return setArrowsJoint(jt1, jt2->first_arrow, jt2->second_arrow);
56 }
57 
58 
59 		/********************************
60 		*            ARROWS		*
61 		********************************/
62 
63 static Graphical
getDefaultArrowJoint(Joint jt)64 getDefaultArrowJoint(Joint jt)
65 { answer(newObject(ClassArrow, EAV));
66 }
67 
68 
69 status
setArrowsJoint(Joint jt,Graphical first,Graphical second)70 setArrowsJoint(Joint jt, Graphical first, Graphical second)
71 { if ( isDefault(first)  ) first  = jt->first_arrow;
72   if ( isDefault(second) ) second = jt->second_arrow;
73 
74   if ( jt->first_arrow == first && jt->second_arrow == second )
75     succeed;
76 
77   CHANGING_GRAPHICAL(jt,
78 		     assign(jt, first_arrow, first);
79 		     assign(jt, second_arrow, second);
80 		     requestComputeGraphical(jt, DEFAULT);
81 		     changedEntireImageGraphical(jt));
82 
83   succeed;
84 }
85 
86 
87 static status
firstArrowJoint(Joint jt,Graphical arrow)88 firstArrowJoint(Joint jt, Graphical arrow)
89 { return setArrowsJoint(jt, arrow, DEFAULT);
90 }
91 
92 
93 static status
secondArrowJoint(Joint jt,Graphical arrow)94 secondArrowJoint(Joint jt, Graphical arrow)
95 { return setArrowsJoint(jt, DEFAULT, arrow);
96 }
97 
98 
99 static Graphical
initArrowJoint(Joint jt)100 initArrowJoint(Joint jt)
101 { Any rval;
102 
103   if ( !(rval = qadGetv(jt, NAME_defaultArrow, 0, NULL)) )
104     rval = NIL;
105 
106   return rval;
107 }
108 
109 
110 static status
arrowsJoint(Joint jt,Name arrows)111 arrowsJoint(Joint jt, Name arrows)
112 { Graphical first, second;
113 
114   if ( equalName(arrows, NAME_none) )
115   { first  = NIL;
116     second = NIL;
117   } else if ( arrows == NAME_first )
118   { first = (notNil(jt->first_arrow) ? jt->first_arrow : initArrowJoint(jt));
119     second = NIL;
120   } else if ( arrows == NAME_second )
121   { first = NIL;
122     second = (notNil(jt->second_arrow) ? jt->second_arrow
123 				       : initArrowJoint(jt));
124   } else if ( arrows == NAME_both )
125   { first = (notNil(jt->first_arrow) ? jt->first_arrow : initArrowJoint(jt));
126     second = (notNil(jt->second_arrow) ? jt->second_arrow
127 	      			       : initArrowJoint(jt));
128   } else
129     fail;
130 
131   return setArrowsJoint(jt, first, second);
132 }
133 
134 
135 static Name
getArrowsJoint(Joint jt)136 getArrowsJoint(Joint jt)
137 { if ( notNil(jt->first_arrow) )
138   { if ( notNil(jt->second_arrow) )
139       return NAME_both;
140     else
141       return NAME_first;
142   } else
143   { if ( notNil(jt->second_arrow) )
144       return NAME_second;
145     else
146       return NAME_none;
147   }
148 }
149 
150 		 /*******************************
151 		 *	      SELECTED		*
152 		 *******************************/
153 
154 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
155 The selection blobs of joints often exceed the area.  Enlarge it.
156 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
157 
158 static status
selectedJoint(Joint jt,BoolObj selected)159 selectedJoint(Joint jt, BoolObj selected)
160 { if ( jt->selected != selected )
161   { CHANGING_GRAPHICAL(jt,
162 		       assign(jt, selected, selected);
163 		       requestComputeGraphical(jt, DEFAULT);
164 		       changedEntireImageGraphical(jt));
165   }
166 
167   succeed;
168 }
169 
170 
171 		 /*******************************
172 		 *	 CLASS DECLARATION	*
173 		 *******************************/
174 
175 /* Type declarations */
176 
177 static char *T_initialise[] =
178         { "x=[int]", "y=[int]", "width=[int]",
179 	  "height=[int]", "arrows=[{none,first,second,both}]" };
180 
181 /* Instance Variables */
182 
183 static vardecl var_joint[] =
184 { SV(NAME_firstArrow, "graphical*", IV_GET|IV_STORE, firstArrowJoint,
185      NAME_appearance, "Arrow on start-point"),
186   SV(NAME_secondArrow, "graphical*", IV_GET|IV_STORE, secondArrowJoint,
187      NAME_appearance, "Arrow on end-point")
188 };
189 
190 /* Send Methods */
191 
192 static senddecl send_joint[] =
193 { SM(NAME_initialise, 5, T_initialise, initialiseJoint,
194      DEFAULT, "Create joint with bounding-box and arrows"),
195   SM(NAME_arrows, 1, "arrows={none,first,second,both}", arrowsJoint,
196      NAME_appearance, "Default arrows on {none,first,second,both}"),
197   SM(NAME_selected, 1, "bool", selectedJoint,
198      NAME_selection, "If @on, I'm selected")
199 };
200 
201 /* Get Methods */
202 
203 static getdecl get_joint[] =
204 { GM(NAME_arrows, 0, "arrows={none,first,second,both}", NULL, getArrowsJoint,
205      NAME_appearance, "Which arrows are defined"),
206   GM(NAME_defaultArrow, 0, "graphical", NULL, getDefaultArrowJoint,
207      NAME_appearance, "Create default arrow for ->arrows")
208 };
209 
210 /* Resources */
211 
212 #define rc_joint NULL
213 /*
214 static classvardecl rc_joint[] =
215 {
216 };
217 */
218 
219 /* Class Declaration */
220 
221 static Name joint_termnames[] = { NAME_arrows };
222 
223 ClassDecl(joint_decls,
224           var_joint, send_joint, get_joint, rc_joint,
225           1, joint_termnames,
226           "$Rev$");
227 
228 
229 status
makeClassJoint(Class class)230 makeClassJoint(Class class)
231 { return declareClass(class, &joint_decls);
232 }
233