org.eclipse.rap icon indicating copy to clipboard operation
org.eclipse.rap copied to clipboard

Low resolution on images and canvas

Open mattcasters opened this issue 3 years ago • 13 comments

In the Apache Hop project we're using Eclipse SWT to render our Hop GUI application. It's essentially a data integration IDE. We also have a version of that runs on RAP which looks something like this:

image

It runs off the same user interface source code with minimal exceptions which is pretty cool all by itself.

The main concern in general is that images in toolbars, menu-items and so on have a low resolution which is about half of what we'd expect. We expect that there's a general setting at play since the resolution set on the canvas is also half of what we'd expect.

The question for this issue then is: where in the code is it decided to half the resolution of the whole user interface and how can we change this behavior? We'd be happy to test and create a PR if needed.

Thanks in advance for any tips!

mattcasters avatar Oct 27 '22 06:10 mattcasters

RAP/RWT does not scale the images at all. If some scaling occurs, that's probably comes from the JFace/Workbench code.

There is an old enhancement request here: 529704: Implement support high-res/scaling support for Canvas https://bugs.eclipse.org/bugs/show_bug.cgi?id=529704

Are you using e3 or e4?

ifurnadjiev avatar Oct 27 '22 08:10 ifurnadjiev

Is it possible to demonstrate the issue with a simple standalone RWT snippet (entry point), without jface/workbench? Probably you can create a patch against our Controls demo or test it there.

ifurnadjiev avatar Oct 27 '22 08:10 ifurnadjiev

Ivan, thanks a lot for the quick reply. We're not using any JFace nor Workbench, only pure SWT and we're on 3.22 for RAP. So yes, this devicePixelRatio issue is probably what we're facing. It's not so bad for the toolbar icons. For the SVG that we're rending of our pipelines and workflows it's a bit harder on the eyes.

If we could get the Canvas to not be blurry that would be a fantastic first step. We're doing our own rendering in a bit of JavaScript on top of Canvas. We set data on it so it knows what to draw.

If there's a way for us to change the devicePixelRatio in some way at the start of the application? That would be more than enough. A quick browser tab refresh would be all that's needed to pick up a ratio in that case. Is this something we can set in CSS? Thanks in advance for any tips you might have!

mattcasters avatar Oct 27 '22 09:10 mattcasters

Since Apache Hop is open source, you can try the application yourself with:

docker run -p 8080:8080 apache/hop-web:Development

Then open your browser on http://localhost:8080

mattcasters avatar Oct 27 '22 09:10 mattcasters

Another example of low resolution in my browser (on 4k screen): https://rap.eclipsesource.com/demo/release/controls/#Canvas

mattcasters avatar Oct 28 '22 13:10 mattcasters

Is this what you need? https://developer.mozilla.org/en-US/docs/Web/CSS/@media/-webkit-device-pixel-ratio You can set it as CSS for your application without any RAP framework change.

ifurnadjiev avatar Nov 02 '22 10:11 ifurnadjiev

... and maybe this will help too: https://developer.mozilla.org/en-US/docs/Web/API/Window/devicePixelRatio

ifurnadjiev avatar Nov 02 '22 10:11 ifurnadjiev

Thanks a lot @ifurnadjiev. There are 2 aspects to this really. First, the low resolution of the toolbar icons. They really should be sourced from the original SVG images. That way we don't have to worry about it. The path I'm taking for that is by creating an exception in the code for the RAP GUI (vs the SWT variant) for toolbar icons. In this case I'm using a label with MARKUP_ENABLED as sort of custom toolbar item widget.
I'm uploading the SVG files as resources. After that I have a facade implementation for the label:

// What's the location of the SVG file?
String src = RWT.getResourceManager().getLocation(imageFile);
label.setData(RWT.MARKUP_ENABLED, Boolean.TRUE);
label.setText("<img id='svg-label' width='" + size + "' height='" + size + "' src='" + src + "'/>");

The main concern then is to "disable" this toolbar icon. I'm looking at some JavaScript for that.

The second part is the resolution of the canvas areas. I know about the device/pixel ratio. What I don't know is how to set it or change it in the RAP CSS file that we have, for example.

Any help with both topics would be really nice. It would for example be really nice if we had a way to set the SVG images for enabled/disabled on the ToolbarItem itself:

toolbarItem.setData(RWT.SVG_IMAGE, "somefile.svg");
toolbarItem.setData(RWT.SVG_DISABLED_IMAGE, "somefile-disabled.svg");

The image and disabled image would then be the fallback scenario we already have.

Any tips on how to implement this would be welcome. I'd be happy to create the PR.

mattcasters avatar Nov 02 '22 11:11 mattcasters

To use "standard" (not RWT styling) CSS in your application you have two options:

  1. Add HEAD HTML to the RAP startup page. See example here.
  2. Use org.eclipse.rap.rwt.client.service.ClientFileLoader.requireCss(String) to load CSS file at runtime

ifurnadjiev avatar Nov 02 '22 11:11 ifurnadjiev

In order to set enabled/disabled SVG image on ToolItem you can try to execute a JavaScript with org.eclipse.rap.rwt.client.service.JavaScriptExecutor that sets the image URL on the client directly. See RAP Scripting section in our developers guide here:

  1. Get ToolItem id by String id = WidgetUtil.getId( widget );
  2. Use rwt.remote.ObjectRegistry.getObject( id ).setImage( svgUrl, width, height ); in your JavaScript to set the image

ifurnadjiev avatar Nov 02 '22 11:11 ifurnadjiev

Unfortunately it looks like there's already style, header, meta information being set in rwt-index.html. I'll see if I can play around with this. I have a hard time building the project if I dare to change anything ;-)

mattcasters avatar Nov 02 '22 12:11 mattcasters

So I managed to get the resolution increased, somewhat. Unfortunately this leads to all sorts of side-effects like the cursor hitting some things like buttons but missing mouse operations in general by a factor devicePixelRatio. For changing the image or style of an image (grayscale, make lighter to signal disabled) on a <img> with a known ID I'm still looking for a way. The handleEvent method is only called when there's an event and for setEnabled()/setVisible() there are no events thrown. I think that for the Canvas I also need to look into a custom widget implementation.

mattcasters avatar Nov 02 '22 14:11 mattcasters

We used scale to draw the canvas in double the size and resized with css, that worked quite good, see #232 .

fx-world avatar Sep 24 '24 12:09 fx-world