How to set own image for the cursor for drag operation - eclipse-rap

It is possible to set/change the image for the cursor for a drag-operatio this way:
Listener listener = new Listener() {
public void handleEvent(Event event) {
switch (event.type) {
case SWT.MouseDown:
moveComposite.setCursor(Display.getCurrent().getSystemCursor(SWT.CURSOR_WAIT));
...
}
...
moveComposite.addListener(SWT.MouseDown, listener);
But in this case only standard cursors can be set.
Is it possible to set an own image for a cursor for a drag operation?
Either in a CSS for a named Control, programmatically for a named Control or as an alternative globally changing the standard cursors.

As a workaround for the missing API (see RĂ¼diger's answer), you could try to set a custom variant while dragging:
moveComposite.setData(RWT.CUSTOM_VARIANT, "dragging");
and configure a custom cursor for this variant in CSS like this:
.dragging {
cursor: url(resources/dragging.gif)
}

I have solved this now with the help of a ClientListener. Because SWT.DragDetect is not supported I have to use SWT.MouseMove
final private String scriptCodeMouseMove =
"var handleEvent = function(event) {\n"
+ " if(window.event.which==1) {"
+ " document.body.style.cursor = 'url(...url to image...),, auto';\n"
+ " } else {"
+ " document.body.style.cursor = 'auto';\n"
+ " }"
+ "}";
composite.addListener(SWT.MouseMove, new ClientListener(scriptCodeMouseMove));
Not really nice, but it works for me.
This way the cursor also changes if the Mouse-Button is pressed without doing a drag-Operation.
I'm really no JavaScript developer, so I'm sure there is much better JavaScript-Code which can do the same stuff.
Btw.: I wanted to use event.button from the ClientScrpting API, but it always returned 1, also if no mouse button was pressed (or 3 doing a right click).

SWT/Desktop has Cursor constructors that accept ImageData like
Cursor( Device device, ImageData source, ... )
but RWT does not provide this API and hence cannot display custom cursors.
See also this open enhancement request: Bug 295806 - Cursor constructor with ImageData is missing
EDIT:
Without having tired myself, you may be able to work around this limitation with CSS and custom variants.
Define a CSS rule which matches all widgets with a custom variant customCursor and changes the cursor to the desired one:
.customCursor {
cursor: url( ... );
}
Now you can assign the custom variant to the outermost shell (assuming that there is a maximized shell that covers the entire display).
Shell outermostShell = ...
outermostShell.setData( SWT.CUSTOM_VARIANT, "customCursor" );
If CSS cursor aren't inherited from parent to child controls, you may need to iterate over the widget hierarchy and set the custom variant explicitly for all controls that should show the custom cursor.

Related

Changing image source attribute in Vue.js + TypeScript

So I have a simple img tag:
<img #error="replaceByDefaultImage" :src="urls.photos_base_url_small.jpg'"/>
And replaceByDefaultImage function looks like this:
replaceByDefaultImage(e: HTMLImageElement) {
e.src = '/img/default.png';
}
Now in case the photos_base_url_small is missing, the replaceByDefaultImage fires but it doesn't change the image source. Or at least it doesn't change on the HTML itself. Although it works if I use target like e.target.src = '/img/default.png'; but if I want to use target, I have to set any type to the event variable e and I prefer not to use this type. Any ideas?
replaceByDefaultImage(e: Event) {
(e.target as HTMLImageElement).src = '/img/default.png';
}
Found this solution. Looks fine I guess. Variable e is a type of event so we can't use it like image itself. We have to get the target element first.

*ngIf or [hidden] not working correctly

I'm trying to allow for hiding of certain sections of the project I'm working on via user toggle. It saves in the database and gets pulled when the page is loaded in the constructor using the following code
this.http.get(`api/section/get/${this.id}`, this.id).subscribe(res => {
this.section = res.json()[0];
this.sect = res.json();
console.log(this.section);
this.hideIntro = this.sect[0].hideIntro;
this.hideMainVideo = this.sect[0].hideMainVideo;
this.hideHandout = this.sect[0].hideHandout;
this.hideQuiz = this.sect[0].hideQuiz;
console.log("Hide Intro = " + this.hideIntro);
console.log("Hide Main = " + this.hideMainVideo);
console.log("Hide Handout = " + this.hideHandout);
console.log("Hide Quiz = " + this.hideQuiz);
});
The HTML is as follows...
<div class="row classMainBackground col-md-12" *ngIf="!hideIntro">
...content...
</div>
For some reason, no matter what I do, whether I change it to *ngIf="hideIntro == false" or even use [hidden]="hideIntro", it is not working.
Even the console logs in the .ts file show up correctly. Is there a reason why this is not working for me? I've used it in other positions and it works fine there...
Does it have something to do with assigning it in the constructor or something?
Thanks in advance!
Angular change detection runs in response to use interaction with the component. If values are updated outside of that event handling (such as after an HTTP request), you need to manually tell the component that it has changed.
constructor(private changeDetector: ChangeDetectorRef){}
this.http.get(`api/section/get/${this.id}`, this.id).subscribe(res => {
[...]
this.changeDetector.markForCheck();
})
More in depth reading: https://blog.thoughtram.io/angular/2016/02/22/angular-2-change-detection-explained.html
I ended up solving the problem by using {{!section.hideIntro}} in the HTML instead of trying to define a new variable to pass that boolean to.
I believe the answer was a combination of what #Vlad274 and #ConnorsFan were mentioning.
the HTML was returning an [object object] for {{hideIntro}} and it seems like there's a delay between the assigning the new value data from the GET response before the DOM actually loads.
Grabbing the data right from the GET respone variable ended up doing the trick.

element.addEventListener not adding listener

So I have an array of strings that will turn into buttons,
//At start
function acceptSuggestion() {
console.log(`clicked`)
console.log(this.textContent);
}
//Else where
suggestions.couldBe.innerHTML = ``;
list.suggestions.forEach(function (item) {
let button = document.createElement(`button`);
button.textContent = item;
button.addEventListener(`click`, acceptSuggestion);//before append
button.style = `text-align:center; width:50%`;
suggestions.couldBe.appendChild(button);
button.addEventListener(`click`, acceptSuggestion);//after append
suggestions.couldBe.innerHTML+=`<br>`;
});
It creates the buttons fine
But clicking them does nothing.
Why is this? I know I have the event right cuz of this: https://www.w3schools.com/js/js_htmldom_eventlistener.asp
If it matters, I am using electron.js to create an webpage like application, and not a browser.
The reason this is happening is because of this line:
suggestions.couldBe.innerHTML+="<br>";
What is happening is your Browser element is generating all new fresh HTML each loop because of the += on the innerHTML.
Basically in pseudo code:
var temp = suggestions.couldBe.innerHTML + "<br>;
suggestions.couldBe.innerHTML = temp;
This causes your element that was added via the suggestions.couldBe.appendChild(button); to be converted to html, then re-parsed and all new elements created from HTML each iteration of the loop. Because your Button event handler was created in JS; it is lost when it recreated the button from the HTML version.
You want to do this either all via JS; not mixing it. So my suggestion would be to change this line:
suggestions.couldBe.innerHTML+="<br>";
to
suggestions.couldBe.appendChild(document.createElement('br'));

Outer container 'null' not found.

used jssor slider , i have some pages with same jssor slider , some pages are working fine , but some pages comes Outer container 'null' not found. bug , can any one help on this ?
I had a similar problem, so did some digging to see what the issue was.
The setup starts with the initial call, here's the snippet from the demo site
http://www.jssor.com/development/index.html
var jssor_slider1 = new $JssorSlider$("slider1_container", options);
which, among setting up all kinds of utility functions- more importantly does this
function JssorSlider(elmt, options) {
var _SelfSlider = this;
...
// bunch of other functions
...
$JssorDebug$.$Execute(function () {
var outerContainerElmt = $Jssor$.$GetElement(elmt);
if (!outerContainerElmt)
$JssorDebug$.$Fail("Outer container '" + elmt + "' not found.");
});
}
so at this point, it's trying to collect the string you passed, which is the elmt variable- which is for what? Well let's take a look at that $GetElement function in jssor.js
_This.$GetElement = function (elmt) {
if (_This.$IsString(elmt)) {
elmt = document.getElementById(elmt);
}
return elmt;
};
So, really, what it comes down to is this line for finding the element.
elmt = document.getElementById(elmt);
So the base of this error is
"We tried to use your string to find a matching ID tag on the page and it didn't give us a valid value"
This could be a typo, or another line of code modifying/removing the DOM.
Note that there are some scripts try to remove or modify element in your page.
Please right click on your page and click 'Inspect Element' menu item in the context menu.
Check if the 'outer container' is still there in the document. And check if there is another element with the same id.
Check if "Slider1_Container" is present or Used.
In my case, I didn't have it in my html, but still I had added the js.
Removing js resolved my issue.

Flex 4 TextArea: automatic character escaping in HTML/TextFlow links

I'm using the Spark's TextArea that contains links like this:
#hashtag
As you can see, this is a link to the Twitter search page for the specific hashtag. The hash-sign must be escaped in the query string. But, I have a problem here: when I click the link, the '%' symbol gets escaped automatically and the URL becomes corrupted (...search?q=%2523hashtag). Can I turn off this automatic escaping?
The '#' sign, if used in the URL, does not become escaped, and therefore the Twitter page does not open correctly in this case. So I cannot use neither '#' nor '%23' in the URL.
I would appreciate any solution for this.
Thank you.
Ok... so far, I couldn't find a way to turn off the automatic escaping of the URL when it's clicked. But I've found the workaround instead.
Basically, I add a custom click handler to all the link elements inside the TextFlow and open the links manually when clicked (instead of a built-in TLF behavior). Like this:
public function addLinkHandler( textFlowOrGroupElement: FlowGroupElement ): void
{
// scan the flow elements
for ( var f1: int = 0; f1 < textFlowOrGroupElement.numChildren; f1 ++ ) {
// found element
var curFlowGroupElement: FlowElement = textFlowOrGroupElement.getChildAt( f1 );
// if this is the link element, add the click event listener
if ( curFlowGroupElement is LinkElement ) {
( curFlowGroupElement as LinkElement ).addEventListener( FlowElementMouseEvent.CLICK, onLinkClick );
}
// if this is another flow group
else if ( curFlowGroupElement is FlowGroupElement ) {
// scan this group in turn, recursively
addLinkHandler( curFlowGroupElement as FlowGroupElement );
}
}
}
and here is the click handler for the links:
public function onLinkClick( e: FlowElementMouseEvent ): void
{
e.stopImmediatePropagation();
e.preventDefault();
var linkElement: LinkElement = e.flowElement as LinkElement;
navigateToURL( new URLRequest( linkElement.href ), '_blank' );
}
So in the end to make the Twitter-hashtag links work correctly in the TextArea, I do this:
addLinkHandler( textArea.textFlow );
P.S. The algorithm of adding the click handlers is based on this post, but optimized.