Skip to content

Commit

Permalink
Multi zoom level support for caret
Browse files Browse the repository at this point in the history
This commit scales the caret on a DPI change event on styled text. It
uses the line height of the styled text to set on caret. The
height and width field in the caret are storing data in points now and
not in pixels. We do so to avail the scaling refernece. Also we use
SWT.DEFAULT to ignore setting of width. It is useful when we set the new
height on DPI change since the preferred width of the caret is loadeed
from preferences on the Caret creation.

Contributes to #62 and #127
  • Loading branch information
amartya4256 committed Jun 27, 2024
1 parent f40502d commit 7aff855
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 39 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@


import java.util.*;
import java.util.function.*;
import java.util.stream.*;

import org.eclipse.swt.*;
Expand Down Expand Up @@ -10859,4 +10860,25 @@ void updateSelection(int startOffset, int replacedLength, int newLength) {
setCaretLocations();
}

/**
* The method accepts a StyledText and a callback which takes
* all the carets of the StyledText as the argument and executes it.
* The caret is refreshed after the execution of the callback.
*
* @param styledText the StyledText to get the carets from
* @param consumer the callback which works with the carets
*
* @since 3.127
*/
public static void updateAndRefreshCarets(StyledText styledText, Consumer<Caret> consumer) {
consumer.accept(styledText.getCaret());
consumer.accept(styledText.defaultCaret);
for (Caret caret : styledText.carets) {
consumer.accept(caret);
}
styledText.updateCaretVisibility();
styledText.setCaretLocations();

}

}
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
*******************************************************************************/
package org.eclipse.swt.internal;

import org.eclipse.swt.*;
import org.eclipse.swt.custom.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;

Expand All @@ -31,6 +33,7 @@ public class CommonWidgetsDPIChangeHandlers {

public static void registerCommonHandlers() {
DPIZoomChangeRegistry.registerHandler(CommonWidgetsDPIChangeHandlers::handleItemDPIChange, Item.class);
DPIZoomChangeRegistry.registerHandler(CommonWidgetsDPIChangeHandlers::handleStyledTextDPIChange, StyledText.class);
}

private static void handleItemDPIChange(Widget widget, int newZoom, float scalingFactor) {
Expand All @@ -43,4 +46,15 @@ private static void handleItemDPIChange(Widget widget, int newZoom, float scalin
item.setImage(image);
}
}

private static void handleStyledTextDPIChange(Widget widget, int newZoom, float scalingFactor) {
if (!(widget instanceof StyledText styledText)) {
return;
}

StyledText.updateAndRefreshCarets(styledText, x -> {
DPIZoomChangeRegistry.applyChange(x, newZoom, scalingFactor);
x.setSize(SWT.DEFAULT, styledText.getLineHeight());
});
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ public class Caret extends Widget {
private static Caret currentCaret;

Canvas parent;
int x, y, width, height;
int xInPixels, yInPixels, width, height;
boolean moved, resized;
boolean isVisible;
Image image;
Expand Down Expand Up @@ -127,15 +127,15 @@ public Rectangle getBounds () {
Rectangle getBoundsInPixels () {
if (image != null) {
Rectangle rect = image.getBoundsInPixels ();
return new Rectangle (x, y, rect.width, rect.height);
return new Rectangle (xInPixels, yInPixels, rect.width, rect.height);
}
if (width == 0) {
int [] buffer = new int [1];
if (OS.SystemParametersInfo (OS.SPI_GETCARETWIDTH, 0, buffer, 0)) {
return new Rectangle (x, y, buffer [0], height);
return new Rectangle (xInPixels, yInPixels, buffer [0], getHeightInPixels());
}
}
return new Rectangle (x, y, width, height);
return new Rectangle (xInPixels, yInPixels, getWidthInPixels(), getWidthInPixels());
}

/**
Expand Down Expand Up @@ -189,7 +189,7 @@ public Point getLocation () {
}

Point getLocationInPixels () {
return new Point (x, y);
return new Point (xInPixels, yInPixels);
}

/**
Expand Down Expand Up @@ -230,10 +230,18 @@ Point getSizeInPixels () {
if (width == 0) {
int [] buffer = new int [1];
if (OS.SystemParametersInfo (OS.SPI_GETCARETWIDTH, 0, buffer, 0)) {
return new Point (buffer [0], height);
return new Point (buffer [0], getHeightInPixels());
}
}
return new Point (width, height);
return new Point (getWidthInPixels(), getHeightInPixels());
}

private int getWidthInPixels() {
return DPIUtil.autoScaleUp(width, getZoom());
}

private int getHeightInPixels() {
return DPIUtil.autoScaleUp(height, getZoom());
}

/**
Expand Down Expand Up @@ -293,7 +301,7 @@ void killFocus () {
void move () {
moved = false;
setCurrentCaret(this);
if (!OS.SetCaretPos (x, y)) return;
if (!OS.SetCaretPos (xInPixels, yInPixels)) return;
resizeIME ();
}

Expand Down Expand Up @@ -354,15 +362,15 @@ void resize () {
long hwnd = parent.handle;
OS.DestroyCaret ();
long hBitmap = image != null ? Image.win32_getHandle(image, getZoom()) : 0;
int width = this.width;
if (image == null && width == 0) {
int widthInPixels = this.getWidthInPixels();
if (image == null && widthInPixels == 0) {
int [] buffer = new int [1];
if (OS.SystemParametersInfo (OS.SPI_GETCARETWIDTH, 0, buffer, 0)) {
width = buffer [0];
widthInPixels = buffer [0];
}
}
OS.CreateCaret (hwnd, hBitmap, width, height);
OS.SetCaretPos (x, y);
OS.CreateCaret (hwnd, hBitmap, widthInPixels, getHeightInPixels());
OS.SetCaretPos (xInPixels, yInPixels);
OS.ShowCaret (hwnd);
move ();
}
Expand Down Expand Up @@ -396,15 +404,7 @@ void restoreIMEFont () {
public void setBounds (int x, int y, int width, int height) {
checkWidget();
int zoom = getZoom();
setBoundsInPixels(DPIUtil.autoScaleUp(x, zoom), DPIUtil.autoScaleUp(y, zoom), DPIUtil.autoScaleUp(width, zoom), DPIUtil.autoScaleUp(height, zoom));
}

void setBoundsInPixels (int x, int y, int width, int height) {
boolean samePosition = this.x == x && this.y == y;
boolean sameExtent = this.width == width && this.height == height;
if (samePosition && sameExtent && isCurrentCaret()) return;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
if (sameExtent) {
Expand All @@ -414,6 +414,14 @@ void setBoundsInPixels (int x, int y, int width, int height) {
resized = true;
if (isVisible && hasFocus ()) resize ();
}
setBoundsInPixels(DPIUtil.autoScaleUp(x, zoom), DPIUtil.autoScaleUp(y, zoom), sameExtent);
}

private void setBoundsInPixels (int xInPixels, int yInPixels, boolean sameExtent) {
boolean samePosition = this.xInPixels == xInPixels && this.yInPixels == yInPixels;
if (samePosition && sameExtent && isCurrentCaret()) return;
this.xInPixels = xInPixels;
this.yInPixels = yInPixels;
}

/**
Expand All @@ -431,25 +439,21 @@ void setBoundsInPixels (int x, int y, int width, int height) {
*/
public void setBounds (Rectangle rect) {
if (rect == null) error (SWT.ERROR_NULL_ARGUMENT);
setBoundsInPixels(DPIUtil.autoScaleUp(rect, getZoom()));
}

void setBoundsInPixels (Rectangle rect) {
setBoundsInPixels (rect.x, rect.y, rect.width, rect.height);
setBounds(rect.x, rect.y, rect.width, rect.height);
}

void setFocus () {
long hwnd = parent.handle;
long hBitmap = 0;
if (image != null) hBitmap = Image.win32_getHandle(image, getZoom());
int width = this.width;
if (image == null && width == 0) {
int widthInPixels = this.getWidthInPixels();
if (image == null && widthInPixels == 0) {
int [] buffer = new int [1];
if (OS.SystemParametersInfo (OS.SPI_GETCARETWIDTH, 0, buffer, 0)) {
width = buffer [0];
widthInPixels = buffer [0];
}
}
OS.CreateCaret (hwnd, hBitmap, width, height);
OS.CreateCaret (hwnd, hBitmap, widthInPixels, getHeightInPixels());
move ();
setIMEFont ();
if (isVisible) OS.ShowCaret (hwnd);
Expand Down Expand Up @@ -543,9 +547,9 @@ public void setLocation (int x, int y) {
setLocationInPixels(DPIUtil.autoScaleUp(x, zoom), DPIUtil.autoScaleUp(y, zoom));
}

void setLocationInPixels (int x, int y) {
if (this.x == x && this.y == y && isCurrentCaret()) return;
this.x = x; this.y = y;
private void setLocationInPixels (int xInPixels, int yInPixels) {
if (this.xInPixels == xInPixels && this.yInPixels == yInPixels && isCurrentCaret()) return;
this.xInPixels = xInPixels; this.yInPixels = yInPixels;
moved = true;
if (isVisible && hasFocus ()) move ();
}
Expand Down Expand Up @@ -590,12 +594,11 @@ public void setLocation (Point location) {
*/
public void setSize (int width, int height) {
checkWidget();
setSizeInPixels(DPIUtil.autoScaleUp(width, getZoom()), DPIUtil.autoScaleUp(height, getZoom()));
}

void setSizeInPixels (int width, int height) {
if (this.width == width && this.height == height && isCurrentCaret()) return;
this.width = width; this.height = height;
if(width != SWT.DEFAULT) {
this.width = width;
}
this.height = height;
resized = true;
if (isVisible && hasFocus ()) resize ();
}
Expand All @@ -617,7 +620,7 @@ public void setSize (Point size) {
checkWidget();
if (size == null) error (SWT.ERROR_NULL_ARGUMENT);
size = DPIUtil.autoScaleUp(size, getZoom());
setSizeInPixels(size.x, size.y);
setSize(size.x, size.y);
}

/**
Expand Down

0 comments on commit 7aff855

Please sign in to comment.