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 #include <h/text.h>
38 
39 static status	fontTextCursor(TextCursor c, FontObj font);
40 static status	styleTextCursor(TextCursor c, Name style);
41 
42 static status
initialiseTextCursor(TextCursor c,FontObj font)43 initialiseTextCursor(TextCursor c, FontObj font)
44 { initialiseGraphical(c, ZERO, ZERO, ZERO, ZERO);
45 
46   if ( notDefault(font) )
47     return fontTextCursor(c, font);
48   else
49     return styleTextCursor(c, getClassVariableValueObject(c, NAME_style));
50 }
51 
52 
53 static status
RedrawAreaTextCursor(TextCursor c,Area a)54 RedrawAreaTextCursor(TextCursor c, Area a)
55 { int x, y, w, h;
56 
57   initialiseDeviceGraphical(c, &x, &y, &w, &h);
58 
59   if ( c->style == NAME_arrow )
60   { int cx = x+w/2;			/* TBD: consider r_caret()! */
61     ipoint pts[3];
62 
63     r_thickness(1);
64     r_dash(NAME_none);
65     r_line(cx, y, cx, y+h-1);
66 
67     pts[0].x = x;
68     pts[0].y = y+h;
69     pts[1].x = x + w;
70     pts[1].y = y+h;
71     pts[2].x = cx;
72     pts[2].y = y + h - (h+2)/3;
73 
74     r_fillpattern(c->active == ON ? BLACK_IMAGE : GREY50_IMAGE,
75 		  NAME_foreground);
76     r_fill_polygon(pts, 3);
77   } else if ( c->style == NAME_image )
78   { r_image(c->image, 0, 0, x, y, w, h, ON);
79   } else if ( c->style == NAME_openLook )
80   { if ( c->active == ON )
81     { int cx = x + w/2;
82       Any colour = getDisplayColourGraphical((Graphical)c);
83 
84       r_fillpattern(colour ? colour : (Any) BLACK_IMAGE, NAME_foreground);
85       r_fill_triangle(cx, y, x, y+h, x+w, y+h);
86     } else
87     { ipoint pts[4];
88       int cx = x + w/2;
89       int cy = y + h/2;
90       int i = 0;
91 
92       pts[i].x = cx;  pts[i].y = y;   i++;
93       pts[i].x = x;   pts[i].y = cy;  i++;
94       pts[i].x = cx;  pts[i].y = y+h; i++;
95       pts[i].x = x+w; pts[i].y = cy;  i++;
96 
97       r_fillpattern(GREY50_IMAGE, NAME_foreground);
98       r_fill_polygon(pts, i);
99     }
100   } else /*if ( c->style == NAME_block )*/
101   { if ( c->active == ON )
102       r_complement(x, y, w, h);
103     else
104       r_box(x, y, w, h, 0, NIL);
105   }
106 
107   succeed;
108 }
109 
110 
111 static status
fontTextCursor(TextCursor c,FontObj font)112 fontTextCursor(TextCursor c, FontObj font)
113 { Int h = getHeightFont(font);
114   Int w = getExFont(font);
115   Name style = getClassVariableValueObject(c, getFixedWidthFont(font) == ON ?
116 				      		NAME_fixedFontStyle :
117 						NAME_proportionalFontStyle);
118 
119   geometryGraphical(c, DEFAULT, DEFAULT, w, h);
120 
121   if ( style )
122     return styleTextCursor(c, style);
123 
124   fail;
125 }
126 
127 
128 /* - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
129 Set the  text_cursor; (x,y) is  the top-right corner  of the character
130 after which the insertion point is.  h is the height  of the line, y+b
131 is  the  baseline  of the line.   w is the width   of the font  of the
132 character.
133 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
134 
135 #define OL_CURSOR_SIZE	9
136 
137 status
setTextCursor(TextCursor c,Int x,Int y,Int w,Int h,Int b)138 setTextCursor(TextCursor c, Int x, Int y, Int w, Int h, Int b)
139 { if ( c->style == NAME_arrow )
140     return geometryGraphical(c, dif(x, w), y, w, h);
141   if ( c->style == NAME_image )
142     return geometryGraphical(c,
143 			     sub(x, c->hot_spot->x),
144 			     sub(add(y, b), c->hot_spot->y),
145 			     c->image->size->w, c->image->size->h);
146   if ( c->style == NAME_openLook )
147     return geometryGraphical(c,
148 			     sub(x, toInt(OL_CURSOR_SIZE/2)),
149 			     sub(add(y, b), ONE),
150 			     toInt(OL_CURSOR_SIZE),
151 			     toInt(OL_CURSOR_SIZE));
152   return geometryGraphical(c, x, y, w, h);
153 }
154 
155 		/********************************
156 		*           ATTRIBUTES		*
157 		********************************/
158 
159 
160 static status
styleTextCursor(TextCursor c,Name style)161 styleTextCursor(TextCursor c, Name style)
162 { Int w = DEFAULT;
163   Int h = DEFAULT;
164 
165   if ( style == NAME_image &&
166        (isNil(c->image) || isNil(c->hot_spot)) )
167     return errorPce(c, NAME_needImageAndHotSpot);
168 
169   if ( style == NAME_openLook )
170     w = h = toInt(OL_CURSOR_SIZE);
171 
172   CHANGING_GRAPHICAL(c,
173 		     geometryGraphical(c, DEFAULT, DEFAULT, w, h);
174 		     assign(c, style, style);
175 		     changedEntireImageGraphical(c));
176 
177   succeed;
178 }
179 
180 
181 static status
imageTextCursor(TextCursor c,Image image,Point hot)182 imageTextCursor(TextCursor c, Image image, Point hot)
183 { CHANGING_GRAPHICAL(c,
184 	assign(c, image,    image);
185 	assign(c, hot_spot, hot);
186 	assign(c, style,    NAME_image);
187 	changedEntireImageGraphical(c));
188 
189   succeed;
190 }
191 
192 
193 		 /*******************************
194 		 *	 CLASS DECLARATION	*
195 		 *******************************/
196 
197 /* Type declarations */
198 
199 static char *T_set[] =
200         { "x=int", "y=int", "width=int", "height=int", "baseline=int" };
201 
202 /* Instance Variables */
203 
204 static vardecl var_textCursor[] =
205 { SV(NAME_style, "{arrow,image,block,open_look}", IV_GET|IV_STORE,
206      styleTextCursor,
207      NAME_appearance, "How the text_cursor object is visualised"),
208   SV(NAME_image, "image*", IV_GET|IV_STORE, imageTextCursor,
209      NAME_appearance, "Image when <->style is image"),
210   IV(NAME_hotSpot, "point*", IV_GET,
211      NAME_appearance, "The `hot-spot' of the image")
212 };
213 
214 /* Send Methods */
215 
216 static senddecl send_textCursor[] =
217 { SM(NAME_initialise, 1, "for=[font]", initialiseTextCursor,
218      DEFAULT, "Create for specified font"),
219   SM(NAME_font, 1, "font", fontTextCursor,
220      NAME_appearance, "Set ->style according to font"),
221   SM(NAME_set, 5, T_set, setTextCursor,
222      NAME_area, "Set x, y, w, h and baseline")
223 };
224 
225 /* Get Methods */
226 
227 #define get_textCursor NULL
228 /*
229 static getdecl get_textCursor[] =
230 {
231 };
232 */
233 
234 /* Resources */
235 
236 static classvardecl rc_textCursor[] =
237 { RC(NAME_fixedFontStyle, "name", "open_look",
238      "->style for fixed fonts"),
239   RC(NAME_proportionalFontStyle, "name", "open_look",
240      "->style for proportional fonts"),
241   RC(NAME_style, NULL, "open_look", NULL),
242   RC(NAME_colour, RC_REFINE, "when(@colour_display, red, black)", NULL),
243   RC(NAME_inactiveColour, RC_REFINE, "black", NULL)
244 };
245 
246 /* Class Declaration */
247 
248 static Name textCursor_termnames[] = { NAME_style };
249 
250 ClassDecl(textCursor_decls,
251           var_textCursor, send_textCursor, get_textCursor, rc_textCursor,
252           1, textCursor_termnames,
253           "$Rev$");
254 
255 status
makeClassTextCursor(Class class)256 makeClassTextCursor(Class class)
257 { declareClass(class, &textCursor_decls);
258   setRedrawFunctionClass(class, RedrawAreaTextCursor);
259 
260   succeed;
261 }
262 
263