1 /* Copyright (C) 1999, 2000 Guido Masarotto
2 Copyright (C) 2004, The R Foundation
3
4 Generalized version of widgets in buttons.c
5
6
7 This file is part of GraphApp, a cross-platform C graphics library.
8
9 GraphApp is free software; you can redistribute it and/or modify it
10 under the terms of the GNU Library General Public License.
11 GraphApp is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY.
13
14 See the file COPYLIB.TXT for details.
15 */
16
17 #include "internal.h"
18
19 /* Win32 style scrollbars */
20 void
gchangescrollbar(scrollbar obj,int which,int where,int max,int pagesize,int disablenoscroll)21 gchangescrollbar(scrollbar obj, int which, int where, int max, int pagesize,
22 int disablenoscroll)
23 {
24 HWND hwnd;
25 SCROLLINFO si;
26
27 if (! obj) return;
28 hwnd = obj->handle;
29 switch (which) {
30 case HWINSB:
31 obj->xmax = max;
32 obj->xsize = pagesize;
33 which = SB_HORZ;
34 break;
35 case VWINSB:
36 obj->max = max;
37 obj->size = pagesize;
38 which = SB_VERT;
39 break;
40 default:
41 obj->max = max;
42 obj->size = pagesize;
43 which = SB_CTL;
44 break;
45 }
46 si.cbSize = sizeof(si);
47 si.fMask = disablenoscroll ? (SIF_ALL | SIF_DISABLENOSCROLL) : SIF_ALL;
48 si.nMin = 0;
49 si.nMax = max;
50 si.nPage = pagesize;
51 si.nPos = where;
52 SetScrollInfo(hwnd, which, &si, 1);
53 }
54
gsetcursor(drawing d,cursor c)55 void gsetcursor(drawing d, cursor c)
56 {
57 POINT pt;
58
59 decrease_refcount(d->drawstate->crsr);
60 d->drawstate->crsr = c;
61 increase_refcount(c);
62 /* ensure new cursor is shown */
63 GetCursorPos(&pt);
64 SetCursorPos(pt.x, pt.y);
65 }
66
newtoolbar(int height)67 control newtoolbar(int height)
68 {
69 window c = current_window;
70 if (!ismdi() || !c || (c==MDIFrame)) return NULL;
71 addto(MDIFrame);
72 c->toolbar = newwindow("TOOLBAR", rect(0, 0, 100, height),
73 ChildWindow | Border);
74 if (c->toolbar) {
75 DWORD wcol = GetSysColor(COLOR_MENU);
76 hide(c->toolbar);
77 setbackground(c->toolbar,
78 rgb( (wcol >> 0) & 0x000000FFL,
79 (wcol >> 8) & 0x000000FFL,
80 (wcol >> 16) & 0x000000FFL));
81 }
82 addto(c);
83 return (control) c->toolbar;
84 }
85
86 /* Fix background color for image on the toolbar.
87 Designed to work with image in stdimc.c:
88 (a) background is pixel (0,0);
89 (b) image depth is 8 bits;
90 (c) image is changed not copied.
91 */
newtoolbutton(image img,rect r,actionfn fn)92 button newtoolbutton(image img, rect r, actionfn fn) {
93 DWORD wcol = GetSysColor(COLOR_MENU);
94 rgb col = rgb( (wcol >> 0) & 0x000000FFL,
95 (wcol >> 8) & 0x000000FFL,
96 (wcol >> 16) & 0x000000FFL);
97 img->cmap[img->pixels[0]] = col;
98 return newimagebutton(img, r, fn);
99 }
100
101
scrolltext(textbox c,int lines)102 void scrolltext(textbox c, int lines)
103 {
104 int linecount = sendmessage(c->handle, EM_GETLINECOUNT, 0, 0);
105 sendmessage(c->handle, EM_LINESCROLL, 0, linecount - lines);
106 }
107
108
ggetkeystate()109 int ggetkeystate()
110 {
111 int k = 0;
112 if (GetKeyState(VK_CONTROL)&0x8000)
113 k |= CtrlKey;
114 if (GetKeyState(VK_MENU)&0x8000)
115 k |= AltKey;
116 if (GetKeyState(VK_SHIFT)&0x8000)
117 k |= ShiftKey;
118 return k;
119 }
120
121
122 /* Extra text editing functions for R, Chris Jackson */
123 #include <richedit.h>
124
125 /* Move the editor caret position lines down.
126 If lines is negative moves caret up.
127 Stops at the top or the bottom if lines is too big or small.
128 */
129
scrollcaret(textbox t,int lines)130 void scrollcaret(textbox t, int lines)
131 {
132 long currentline, charindex;
133 int linecount = sendmessage(t->handle, EM_GETLINECOUNT, 0, 0);
134 currentline = sendmessage(t->handle, EM_LINEFROMCHAR, -1, 0);
135 lines = (currentline + lines > linecount - 1 ? linecount - currentline - 1 : lines);
136 lines = (currentline + lines < 0 ? - currentline : lines);
137 charindex = sendmessage(t->handle, EM_LINEINDEX, currentline + lines, 0);
138 sendmessage(t->handle, EM_SETSEL, charindex, charindex);
139 }
140
141 /* Modification flags for the text editor */
142
gsetmodified(textbox t,int modified)143 void gsetmodified(textbox t, int modified)
144 {
145 sendmessage(t->handle, EM_SETMODIFY, (WPARAM) modified, 0);
146 }
147
ggetmodified(textbox t)148 int ggetmodified(textbox t)
149 {
150 return sendmessage(t->handle, EM_GETMODIFY, 0, 0);
151 }
152
153 /* Get the length of the current line in an editing control */
154
getlinelength(textbox t)155 int getlinelength(textbox t)
156 {
157 long charindex = sendmessage(t->handle, EM_LINEINDEX, -1, 0);
158 return sendmessage(t->handle, EM_LINELENGTH, charindex, 0);
159 }
160
161 /* Copy the current line in the editor to a buffer */
162
getcurrentline(textbox t,char * line,int length)163 void getcurrentline(textbox t, char *line, int length)
164 {
165 long currentline = sendmessage(t->handle, EM_LINEFROMCHAR, -1, 0);
166 *((LPWORD) line) = length*sizeof(WCHAR)+2; /* set first word of buffer to line length in TCHARs as required by EM_GETLINE */
167 sendmessage(t->handle, EM_GETLINE, currentline, line);
168 /* line[length] = 0; */
169 }
170
171 /* Copy the current selection in the editor to a buffer */
172
getseltext(textbox t,char * text)173 void getseltext(textbox t, char *text)
174 {
175 sendmessage(t->handle, EM_GETSELTEXT, 0, text);
176 }
177
178 /* Change the maximum number of characters (in bytes) allowed in an editor */
179
setlimittext(textbox t,long limit)180 void setlimittext(textbox t, long limit)
181 {
182 sendmessage(t->handle, EM_EXLIMITTEXT, 0, limit);
183 }
184
getlimittext(textbox t)185 long getlimittext(textbox t)
186 {
187 return sendmessage(t->handle, EM_GETLIMITTEXT, 0, 0);
188 }
189
190 /* Test whether the text limit needs to be increased to accommodate
191 some new text of length n. If so increase it by required amount
192 plus 32K. */
193
checklimittext(textbox t,long n)194 void checklimittext(textbox t, long n)
195 {
196 long limit = getlimittext(t);
197 long len = GetWindowTextLength(t->handle);
198 if (len + n >= limit)
199 setlimittext(t, len + n + 0x8000);
200 }
201
202 /* Length of text in the clipboard */
203
getpastelength()204 long getpastelength()
205 {
206 HGLOBAL hglb;
207 char *text;
208 long pastelen;
209 if ( OpenClipboard(NULL) &&
210 (hglb = GetClipboardData(CF_TEXT)) &&
211 (text = (char *)GlobalLock(hglb))) {
212 pastelen = strlen(text);
213 GlobalUnlock(hglb);
214 CloseClipboard();
215 } else pastelen = 0;
216 return pastelen;
217 }
218
219 /* Modification of the text selection functions in buttons.c to work
220 with the EX messages used in rich edit controls. The selection
221 messages without EX cannot handle more than 64K of text */
222
textselectionex(control obj,long * start,long * end)223 void textselectionex(control obj, long *start, long *end)
224 {
225 CHARRANGE sel;
226 if (! obj)
227 return;
228 if ((obj->kind != FieldObject) && (obj->kind != TextboxObject))
229 return;
230 sendmessage(obj->handle, EM_EXGETSEL, 0, &sel);
231 *start = sel.cpMin;
232 *end = sel.cpMax;
233 }
234
selecttextex(control obj,long start,long end)235 void selecttextex(control obj, long start, long end)
236 {
237 CHARRANGE sel;
238 long length;
239
240 if (! obj)
241 return;
242 if ((obj->kind != FieldObject) && (obj->kind != TextboxObject))
243 return;
244 length = GetWindowTextLength(obj->handle);
245 sel.cpMin = (start < 0) ? length : start;
246 sel.cpMax = (end < 0) ? length : end;
247 sendmessage(obj->handle, EM_EXSETSEL, 0, &sel);
248 }
249