]> gerrit.simantics Code Review - simantics/platform.git/blob - bundles/org.eclipse.swt.win32.win32.x86_64/src/org/eclipse/swt/widgets/Caret.java
Remove invalid SHA-256-Digests
[simantics/platform.git] / bundles / org.eclipse.swt.win32.win32.x86_64 / src / org / eclipse / swt / widgets / Caret.java
1 /*******************************************************************************
2  * Copyright (c) 2000, 2019 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *     IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.swt.widgets;
15
16
17 import org.eclipse.swt.*;
18 import org.eclipse.swt.graphics.*;
19 import org.eclipse.swt.internal.*;
20 import org.eclipse.swt.internal.win32.*;
21
22 /**
23  * Instances of this class provide an i-beam that is typically used
24  * as the insertion point for text.
25  * <dl>
26  * <dt><b>Styles:</b></dt>
27  * <dd>(none)</dd>
28  * <dt><b>Events:</b></dt>
29  * <dd>(none)</dd>
30  * </dl>
31  * <p>
32  * IMPORTANT: This class is <em>not</em> intended to be subclassed.
33  * </p>
34  *
35  * @see <a href="http://www.eclipse.org/swt/snippets/#caret">Caret snippets</a>
36  * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: ControlExample, Canvas tab</a>
37  * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
38  * @noextend This class is not intended to be subclassed by clients.
39  */
40 public class Caret extends Widget {
41         Canvas parent;
42         int x, y, width, height;
43         boolean moved, resized;
44         boolean isVisible;
45         Image image;
46         Font font;
47         LOGFONT oldFont;
48
49 /**
50  * Constructs a new instance of this class given its parent
51  * and a style value describing its behavior and appearance.
52  * <p>
53  * The style value is either one of the style constants defined in
54  * class <code>SWT</code> which is applicable to instances of this
55  * class, or must be built by <em>bitwise OR</em>'ing together
56  * (that is, using the <code>int</code> "|" operator) two or more
57  * of those <code>SWT</code> style constants. The class description
58  * lists the style constants that are applicable to the class.
59  * Style bits are also inherited from superclasses.
60  * </p>
61  *
62  * @param parent a composite control which will be the parent of the new instance (cannot be null)
63  * @param style the style of control to construct
64  *
65  * @exception IllegalArgumentException <ul>
66  *    <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
67  * </ul>
68  * @exception SWTException <ul>
69  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
70  *    <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
71  * </ul>
72  *
73  * @see SWT
74  * @see Widget#checkSubclass
75  * @see Widget#getStyle
76  */
77 public Caret (Canvas parent, int style) {
78         super (parent, style);
79         this.parent = parent;
80         createWidget ();
81 }
82
83 void createWidget () {
84         isVisible = true;
85         if (parent.getCaret () == null) {
86                 parent.setCaret (this);
87         }
88 }
89
90 long defaultFont () {
91         long hwnd = parent.handle;
92         long hwndIME = OS.ImmGetDefaultIMEWnd (hwnd);
93         long hFont = 0;
94         if (hwndIME != 0) {
95                 hFont = OS.SendMessage (hwndIME, OS.WM_GETFONT, 0, 0);
96         }
97         if (hFont == 0) {
98                 hFont = OS.SendMessage (hwnd, OS.WM_GETFONT, 0, 0);
99         }
100         if (hFont == 0) return parent.defaultFont ();
101         return hFont;
102 }
103
104 /**
105  * Returns a rectangle describing the receiver's size and location
106  * relative to its parent (or its display if its parent is null).
107  *
108  * @return the receiver's bounding rectangle
109  *
110  * @exception SWTException <ul>
111  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
112  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
113  * </ul>
114  */
115 public Rectangle getBounds () {
116         checkWidget();
117         return DPIUtil.autoScaleDown(getBoundsInPixels());
118 }
119
120 Rectangle getBoundsInPixels () {
121         if (image != null) {
122                 Rectangle rect = image.getBoundsInPixels ();
123                 return new Rectangle (x, y, rect.width, rect.height);
124         }
125         if (width == 0) {
126                 int [] buffer = new int [1];
127                 if (OS.SystemParametersInfo (OS.SPI_GETCARETWIDTH, 0, buffer, 0)) {
128                         return new Rectangle (x, y, buffer [0], height);
129                 }
130         }
131         return new Rectangle (x, y, width, height);
132 }
133
134 /**
135  * Returns the font that the receiver will use to paint textual information.
136  *
137  * @return the receiver's font
138  *
139  * @exception SWTException <ul>
140  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
141  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
142  * </ul>
143  */
144 public Font getFont () {
145         checkWidget();
146         if (font == null) {
147                 long hFont = defaultFont ();
148                 return Font.win32_new (display, hFont);
149         }
150         return font;
151 }
152
153 /**
154  * Returns the image that the receiver will use to paint the caret.
155  *
156  * @return the receiver's image
157  *
158  * @exception SWTException <ul>
159  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
160  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
161  * </ul>
162  */
163 public Image getImage () {
164         checkWidget();
165         return image;
166 }
167
168 /**
169  * Returns a point describing the receiver's location relative
170  * to its parent (or its display if its parent is null).
171  *
172  * @return the receiver's location
173  *
174  * @exception SWTException <ul>
175  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
176  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
177  * </ul>
178  */
179 public Point getLocation () {
180         checkWidget();
181         return DPIUtil.autoScaleDown(getLocationInPixels());
182 }
183
184 Point getLocationInPixels () {
185         return new Point (x, y);
186 }
187
188 /**
189  * Returns the receiver's parent, which must be a <code>Canvas</code>.
190  *
191  * @return the receiver's parent
192  *
193  * @exception SWTException <ul>
194  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
195  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
196  * </ul>
197  */
198 public Canvas getParent () {
199         checkWidget();
200         return parent;
201 }
202
203 /**
204  * Returns a point describing the receiver's size.
205  *
206  * @return the receiver's size
207  *
208  * @exception SWTException <ul>
209  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
210  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
211  * </ul>
212  */
213 public Point getSize () {
214         checkWidget();
215         return DPIUtil.autoScaleDown(getSizeInPixels());
216 }
217
218 Point getSizeInPixels () {
219         if (image != null) {
220                 Rectangle rect = image.getBoundsInPixels ();
221                 return new Point (rect.width, rect.height);
222         }
223         if (width == 0) {
224                 int [] buffer = new int [1];
225                 if (OS.SystemParametersInfo (OS.SPI_GETCARETWIDTH, 0, buffer, 0)) {
226                         return new Point (buffer [0], height);
227                 }
228         }
229         return new Point (width, height);
230 }
231
232 /**
233  * Returns <code>true</code> if the receiver is visible, and
234  * <code>false</code> otherwise.
235  * <p>
236  * If one of the receiver's ancestors is not visible or some
237  * other condition makes the receiver not visible, this method
238  * may still indicate that it is considered visible even though
239  * it may not actually be showing.
240  * </p>
241  *
242  * @return the receiver's visibility state
243  *
244  * @exception SWTException <ul>
245  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
246  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
247  * </ul>
248  */
249 public boolean getVisible () {
250         checkWidget();
251         return isVisible;
252 }
253
254 boolean hasFocus () {
255         return parent.handle == OS.GetFocus ();
256 }
257
258 boolean isFocusCaret () {
259         return parent.caret == this && hasFocus ();
260 }
261
262 /**
263  * Returns <code>true</code> if the receiver is visible and all
264  * of the receiver's ancestors are visible and <code>false</code>
265  * otherwise.
266  *
267  * @return the receiver's visibility state
268  *
269  * @exception SWTException <ul>
270  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
271  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
272  * </ul>
273  *
274  * @see #getVisible
275  */
276 public boolean isVisible () {
277         checkWidget();
278         return isVisible && parent.isVisible () && hasFocus ();
279 }
280
281 void killFocus () {
282         OS.DestroyCaret ();
283         restoreIMEFont ();
284 }
285
286 void move () {
287         moved = false;
288         if (!OS.SetCaretPos (x, y)) return;
289         resizeIME ();
290 }
291
292 void resizeIME () {
293         if (!OS.IsDBLocale) return;
294         POINT ptCurrentPos = new POINT ();
295         if (!OS.GetCaretPos (ptCurrentPos)) return;
296         long hwnd = parent.handle;
297         long hIMC = OS.ImmGetContext (hwnd);
298         IME ime = parent.getIME ();
299         if (ime != null && ime.isInlineEnabled ()) {
300                 Point size = getSizeInPixels ();
301                 CANDIDATEFORM lpCandidate = new CANDIDATEFORM ();
302                 lpCandidate.dwStyle = OS.CFS_EXCLUDE;
303                 lpCandidate.ptCurrentPos = ptCurrentPos;
304                 lpCandidate.rcArea = new RECT ();
305                 OS.SetRect (lpCandidate.rcArea, ptCurrentPos.x, ptCurrentPos.y, ptCurrentPos.x + size.x, ptCurrentPos.y + size.y);
306                 OS.ImmSetCandidateWindow (hIMC, lpCandidate);
307         } else {
308                 RECT rect = new RECT ();
309                 OS.GetClientRect (hwnd, rect);
310                 COMPOSITIONFORM lpCompForm = new COMPOSITIONFORM ();
311                 lpCompForm.dwStyle = OS.CFS_RECT;
312                 lpCompForm.x = ptCurrentPos.x;
313                 lpCompForm.y = ptCurrentPos.y;
314                 lpCompForm.left = rect.left;
315                 lpCompForm.right = rect.right;
316                 lpCompForm.top = rect.top;
317                 lpCompForm.bottom = rect.bottom;
318                 OS.ImmSetCompositionWindow (hIMC, lpCompForm);
319         }
320         OS.ImmReleaseContext (hwnd, hIMC);
321 }
322
323 @Override
324 void releaseParent () {
325         super.releaseParent ();
326         if (parent != null && this == parent.caret) {
327                 if (!parent.isDisposed()) parent.setCaret (null);
328                 else parent.caret = null;
329         }
330 }
331
332 @Override
333 void releaseWidget () {
334         super.releaseWidget ();
335         parent = null;
336         image = null;
337         font = null;
338         oldFont = null;
339 }
340
341 void resize () {
342         resized = false;
343         long hwnd = parent.handle;
344         OS.DestroyCaret ();
345         long hBitmap = image != null ? image.handle : 0;
346         int width = this.width;
347         if (image == null && width == 0) {
348                 int [] buffer = new int [1];
349                 if (OS.SystemParametersInfo (OS.SPI_GETCARETWIDTH, 0, buffer, 0)) {
350                         width = buffer [0];
351                 }
352         }
353         OS.CreateCaret (hwnd, hBitmap, width, height);
354         OS.SetCaretPos (x, y);
355         OS.ShowCaret (hwnd);
356         move ();
357 }
358
359 void restoreIMEFont () {
360         if (!OS.IsDBLocale) return;
361         if (oldFont == null) return;
362         long hwnd = parent.handle;
363         long hIMC = OS.ImmGetContext (hwnd);
364         OS.ImmSetCompositionFont (hIMC, oldFont);
365         OS.ImmReleaseContext (hwnd, hIMC);
366         oldFont = null;
367 }
368
369 /**
370  * Sets the receiver's size and location to the rectangular
371  * area specified by the arguments. The <code>x</code> and
372  * <code>y</code> arguments are relative to the receiver's
373  * parent (or its display if its parent is null).
374  *
375  * @param x the new x coordinate for the receiver
376  * @param y the new y coordinate for the receiver
377  * @param width the new width for the receiver
378  * @param height the new height for the receiver
379  *
380  * @exception SWTException <ul>
381  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
382  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
383  * </ul>
384  */
385 public void setBounds (int x, int y, int width, int height) {
386         checkWidget();
387         setBoundsInPixels(DPIUtil.autoScaleUp(x), DPIUtil.autoScaleUp(y), DPIUtil.autoScaleUp(width), DPIUtil.autoScaleUp(height));
388 }
389
390 void setBoundsInPixels (int x, int y, int width, int height) {
391         boolean samePosition = this.x == x && this.y == y;
392         boolean sameExtent = this.width == width && this.height == height;
393         if (samePosition && sameExtent) return;
394         this.x = x;
395         this.y = y;
396         this.width = width;
397         this.height = height;
398         if (sameExtent) {
399                 moved = true;
400                 if (isVisible && hasFocus ()) move ();
401         } else {
402                 resized = true;
403                 if (isVisible && hasFocus ()) resize ();
404         }
405 }
406
407 /**
408  * Sets the receiver's size and location to the rectangular
409  * area specified by the argument. The <code>x</code> and
410  * <code>y</code> fields of the rectangle are relative to
411  * the receiver's parent (or its display if its parent is null).
412  *
413  * @param rect the new bounds for the receiver
414  *
415  * @exception SWTException <ul>
416  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
417  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
418  * </ul>
419  */
420 public void setBounds (Rectangle rect) {
421         if (rect == null) error (SWT.ERROR_NULL_ARGUMENT);
422         setBoundsInPixels(DPIUtil.autoScaleUp(rect));
423 }
424
425 void setBoundsInPixels (Rectangle rect) {
426         setBoundsInPixels (rect.x, rect.y, rect.width, rect.height);
427 }
428
429 void setFocus () {
430         long hwnd = parent.handle;
431         long hBitmap = 0;
432         if (image != null) hBitmap = image.handle;
433         int width = this.width;
434         if (image == null && width == 0) {
435                 int [] buffer = new int [1];
436                 if (OS.SystemParametersInfo (OS.SPI_GETCARETWIDTH, 0, buffer, 0)) {
437                         width = buffer [0];
438                 }
439         }
440         OS.CreateCaret (hwnd, hBitmap, width, height);
441         move ();
442         setIMEFont ();
443         if (isVisible) OS.ShowCaret (hwnd);
444 }
445
446 /**
447  * Sets the font that the receiver will use to paint textual information
448  * to the font specified by the argument, or to the default font for that
449  * kind of control if the argument is null.
450  *
451  * @param font the new font (or null)
452  *
453  * @exception IllegalArgumentException <ul>
454  *    <li>ERROR_INVALID_ARGUMENT - if the font has been disposed</li>
455  * </ul>
456  * @exception SWTException <ul>
457  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
458  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
459  * </ul>
460  */
461 public void setFont (Font font) {
462         checkWidget();
463         if (font != null && font.isDisposed ()) {
464                 error (SWT.ERROR_INVALID_ARGUMENT);
465         }
466         this.font = font;
467         if (hasFocus ()) setIMEFont ();
468 }
469
470 /**
471  * Sets the image that the receiver will use to paint the caret
472  * to the image specified by the argument, or to the default
473  * which is a filled rectangle if the argument is null
474  *
475  * @param image the new image (or null)
476  *
477  * @exception IllegalArgumentException <ul>
478  *    <li>ERROR_INVALID_ARGUMENT - if the image has been disposed</li>
479  * </ul>
480  * @exception SWTException <ul>
481  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
482  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
483  * </ul>
484  */
485 public void setImage (Image image) {
486         checkWidget();
487         if (image != null && image.isDisposed ()) {
488                 error (SWT.ERROR_INVALID_ARGUMENT);
489         }
490         this.image = image;
491         if (isVisible && hasFocus ()) resize ();
492 }
493
494 void setIMEFont () {
495         if (!OS.IsDBLocale) return;
496         long hFont = 0;
497         if (font != null) hFont = font.handle;
498         if (hFont == 0) hFont = defaultFont ();
499         long hwnd = parent.handle;
500         long hIMC = OS.ImmGetContext (hwnd);
501         /* Save the current IME font */
502         if (oldFont == null) {
503                 oldFont = new LOGFONT ();
504                 if (!OS.ImmGetCompositionFont (hIMC, oldFont)) oldFont = null;
505         }
506         /* Set new IME font */
507         LOGFONT logFont = new LOGFONT ();
508         if (OS.GetObject (hFont, LOGFONT.sizeof, logFont) != 0) {
509                 OS.ImmSetCompositionFont (hIMC, logFont);
510         }
511         OS.ImmReleaseContext (hwnd, hIMC);
512 }
513
514 /**
515  * Sets the receiver's location to the point specified by
516  * the arguments which are relative to the receiver's
517  * parent (or its display if its parent is null).
518  *
519  * @param x the new x coordinate for the receiver
520  * @param y the new y coordinate for the receiver
521  *
522  * @exception SWTException <ul>
523  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
524  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
525  * </ul>
526  */
527 public void setLocation (int x, int y) {
528         checkWidget();
529         setLocationInPixels(DPIUtil.autoScaleUp(x), DPIUtil.autoScaleUp(y));
530 }
531
532 void setLocationInPixels (int x, int y) {
533         if (this.x == x && this.y == y) return;
534         this.x = x;  this.y = y;
535         moved = true;
536         if (isVisible && hasFocus ()) move ();
537 }
538
539 /**
540  * Sets the receiver's location to the point specified by
541  * the argument which is relative to the receiver's
542  * parent (or its display if its parent is null).
543  *
544  * @param location the new location for the receiver
545  *
546  * @exception SWTException <ul>
547  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
548  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
549  * </ul>
550  */
551 public void setLocation (Point location) {
552         checkWidget();
553         if (location == null) error (SWT.ERROR_NULL_ARGUMENT);
554         location = DPIUtil.autoScaleUp(location);
555         setLocationInPixels(location.x, location.y);
556 }
557
558 /**
559  * Sets the receiver's size to the point specified by the arguments.
560  *
561  * @param width the new width for the receiver
562  * @param height the new height for the receiver
563  *
564  * @exception SWTException <ul>
565  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
566  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
567  * </ul>
568  */
569 public void setSize (int width, int height) {
570         checkWidget();
571         setSizeInPixels(DPIUtil.autoScaleUp(width), DPIUtil.autoScaleUp(height));
572 }
573
574 void setSizeInPixels (int width, int height) {
575         if (this.width == width && this.height == height) return;
576         this.width = width;  this.height = height;
577         resized = true;
578         if (isVisible && hasFocus ()) resize ();
579 }
580
581 /**
582  * Sets the receiver's size to the point specified by the argument.
583  *
584  * @param size the new extent for the receiver
585  *
586  * @exception IllegalArgumentException <ul>
587  *    <li>ERROR_NULL_ARGUMENT - if the point is null</li>
588  * </ul>
589  * @exception SWTException <ul>
590  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
591  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
592  * </ul>
593  */
594 public void setSize (Point size) {
595         checkWidget();
596         if (size == null) error (SWT.ERROR_NULL_ARGUMENT);
597         size = DPIUtil.autoScaleUp(size);
598         setSizeInPixels(size.x, size.y);
599 }
600
601 /**
602  * Marks the receiver as visible if the argument is <code>true</code>,
603  * and marks it invisible otherwise.
604  * <p>
605  * If one of the receiver's ancestors is not visible or some
606  * other condition makes the receiver not visible, marking
607  * it visible may not actually cause it to be displayed.
608  * </p>
609  *
610  * @param visible the new visibility state
611  *
612  * @exception SWTException <ul>
613  *    <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
614  *    <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
615  * </ul>
616  */
617 public void setVisible (boolean visible) {
618         checkWidget();
619         if (visible == isVisible) return;
620         isVisible = visible;
621         long hwnd = parent.handle;
622         if (OS.GetFocus () != hwnd) return;
623         if (!isVisible) {
624                 OS.HideCaret (hwnd);
625         } else {
626                 if (resized) {
627                         resize ();
628                 } else {
629                         if (moved) move ();
630                 }
631                 OS.ShowCaret (hwnd);
632         }
633 }
634
635 }