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