glisten Dialog resize issue - gluon-mobile

I got a strange layout issue with the gluon dialog class.
I'm creating a new Dialog instance and adding some containers, at the end some simple buttons.
Dialog
- Anchorpane
- VBox
- GridPane
- A Bunch of buttons
So the problem is that the Dialog Container itself is not resized to fit its children. Do you have any hints for me where there might be the problem?
Thank you in advance!

It seems like the Dialog padding is not taken into account. So as a quick workaround you could remove the padding from the dialog and add it to the dialog content node:
//in css
.dialog {
-fx-padding: 0.0;
}
//or
public class DialogTest<T> extends Dialog<T> {
public DialogTest() {
rootNode.setStyle("-fx-padding:0;");
}
}
//...
anchorPane.setPadding(new Insets(top, right, bottom, left));

Related

How to remove the background of a dialog?

I created a custom dialog with my own panes and controls in it. But the dialog has a white border default which I want to remove. Here is an example with a single image:
I tried using ScenicView but couldn't find a way to catch the dialog layer and modify it:
public class MainView extends View {
Image img = new Image("https://i.stack.imgur.com/7bI1Y.jpg", 300, 500, true, true);
public MainView(String name) {
super(name);
Button b = new Button("Pop");
b.setOnAction(e -> {
Dialog<Void> dialog = new Dialog<>();
dialog.setOnShown(e2 -> {
Parent parent = getParent();
Pane p = (Pane) parent.lookup(".dialog");
p.setPadding(new Insets(0));
});
dialog.setGraphic(new ImageView(img));
dialog.showAndWait();
});
setCenter(b);
}
}
Best i got was removing the flowpane child to remove some of the lower part
dialog.setOnShown(e2 -> {
Parent parent = getParent();
Pane p = (Pane) parent.lookup(".dialog");
p.getChildren().removeIf(c -> (c instanceof FlowPane));
System.out.println(p.getChildren());
});
Removing the VBox moves the dialog which i don't want to do and changing its padding also dose nothing.
As you can see with ScenicView, the Dialog has the dialog style class.
One easy way to modify the dialog style is via css. Just add a css file to your view, and set:
.dialog {
-fx-background-color: transparent;
}
That will set the background transparent, instead of the default white color.
If you want to remove the borders instead, then you can play with padding. As you can also see with ScenicView, the dialog has a VBox with style class container for the content in the center, and the flow pane for the buttons at the bottom, with style class dialog-button-bar.
Before anything, just use the setContent method to add the image instead of the setGraphic one:
dialog.setContent(new ImageView(img));
And this will be required to remove all the borders, and let the image take the whole dialog:
.dialog,
.dialog > .container,
.dialog > .dialog-button-bar {
-fx-padding: 0;
}

Horizontally centering a popup window in Vaadin

I have added a popup window to my main UI as follows:
Window component = new Window();
UI.getCurrent().addWindow(component);
Now, I want my popup to be centered horizontally and e.g. 40 pixels from the top of the screen. As far as I can see Vaadin has 4 methods for positioning my window.
component.center()
component.setPosition(x, y)
component.setPositionX(x)
component.setPositionY(y)
None of these are really what I want. I was hoping at first that setPositionY might help me. This does allow me to get the right distance from the top, but the x-position is now set to 0, where I wanted it to be centered.
The setPosition might have helped if I was able to calculate what the x-position should be, but this would require me to know the width of the component in pixels, but component.getWidth just tells me 100%.
Next I tried to use CSS styling on the component, writing and explicit css rule and adding it to the component with addStyleName. It seems though that Vaadin overrides whatever I wrote in my css with its own defaults...
Any ideas how to get my Window component positioned correctly?
I used the methods getBrowserWindowWidth() and getBrowserWindowHeight() from the com.vaadin.server.Page class for this.
I centered my "log" window horizontally in the lower part of the browser window with
myWindow.setHeight("30%");
myWindow.setWidth("96%");
myWindow.setPosition(
(int) (Page.getCurrent().getBrowserWindowWidth() * 0.02),
(int) (Page.getCurrent().getBrowserWindowHeight() * 0.65)
);
Solution 1: Use SizeReporter
Indeed, setPositionY() will reset the window's centered property to false. As the width of your pop-up and that of your browser window are not know before they appear on the screen, the only way I know to get those values is to use the SizeReporter add-on. Its use is quite straightforward:
public class MyUI extends UI {
private Window popUp;
private SizeReporter popUpSizeReporter;
private SizeReporter windowSizeReporter;
#Override
protected void init(VaadinRequest request) {
Button button = new Button("Content button");
VerticalLayout layout = new VerticalLayout(button);
layout.setMargin(true);
popUp = new Window("Pop-up", layout);
popUp.setPositionY(40);
addWindow(popUp);
popUpSizeReporter = new SizeReporter(popUp);
popUpSizeReporter.addResizeListenerOnce(this::centerPopUp);
windowSizeReporter = new SizeReporter(this);
windowSizeReporter.addResizeListenerOnce(this::centerPopUp);
}
private void centerPopUp(ComponentResizeEvent event) {
int popUpWidth = popUpSizeReporter.getWidth();
int windowWidth = windowSizeReporter.getWidth();
if (popUpWidth == -1 || windowWidth == -1) {
return;
}
popUp.setPositionX((windowWidth - popUpWidth) / 2);
}
}
This piece of code will be okay as long as you don't resize the pop-up. If you do, it will not be automatically recentered. If you replace addResizeListenerOnce() by addResizeListener() then it will automatically recenter the pop-up but you'll get some "UI glitches" as the add-on sends resize events almost continually while you're resizing your pop-up...
You could try to do it using CSS, but I personally avoid CSS as much as I can with Vaadin :).
You'll need to recompile the widgetset after you've added the add-on as a dependency.
Solution 2: Use com.vaadin.ui.JavaScript
I won't vouch for the portability of this solution but I guess it will work on most modern browsers.
public class MyUI extends UI {
private Window popUp;
#Override
protected void init(VaadinRequest request) {
Button button = new Button("Content button");
VerticalLayout layout = new VerticalLayout(button);
layout.setMargin(true);
popUp = new Window("Pop-up", layout);
popUp.setPositionY(40);
popUp.addStyleName("window-center");
addWindow(popUp);
// Add a JS function that can be called from the client.
JavaScript.getCurrent().addFunction("centerWindow", args -> {
popUp.setPositionX((int) ((args.getNumber(1) - args.getNumber(0)) / 2));
});
// Execute the function now. In real code you might want to execute the function just after the window is displayed, probably in your enter() method.
JavaScript.getCurrent().execute("centerWindow(document.getElementsByClassName('window-center')[0].offsetWidth, window.innerWidth)");
}
}

Vaadin: How do make a button align to the top right of my page?

I need to align a button to the right of my page in a vertical layout.
Please tell me method to do this.
private Button createBackButton() {
Button bButton = new Button("Back");
bButton.setIcon(FontAwesome.ARROW_LEFT);
bButton.addClickListener(new ClickListener() {
#Override
public void buttonClick(ClickEvent event) {
doSomething();
}
});
return bButton;
}
Null,
In order to align your button to the top-right of your VerticalLayout, use VerticalLayout's setComponentAlignment() method. Also note that the VerticalLayout itself needs to be big enough so that the button can even have some space to move around in there so it looks like it's being aligned to the top-right. By default the VerticalLayout will just get as big as the components inside it. You need to give it a bigger size using setWidth() and setHeight(), or make it take up the whole space as its parent component/layout using setSizeFull() (note that the parent layout, if any, also needs to be big enough so it has space inside it too).
So the code would look like:
VerticalLayout vl = new VerticalLayout();
vl.setSizeFull();
Button backButton = createBackButton();
vl.addComponent(backButton);
vl.setComponentAlignment(backButton,Alignment.TOP_RIGHT);
Hope that helps.

Custom Elements / Shadow Root in DART lang vs Shadow Root in JavaScript

I've the this Shadow Element/root in this example http://jsfiddle.net/fyf6thte/8/ working perfectly with JavaScript, interested to have similar one with DART, so I wrote the below code (using the same html and css file), but I could not see the button it looks theshadow.innerHTML = '<button id="d">click</button>'is not working
the full code is:
import 'dart:html';
void main() {
var thehost = document.querySelector('#host1');
document.registerElement(fonixDiv.tag, fonixDiv);
thehost.append(new fonixDiv());
}
class fonixDiv extends HtmlElement {
static final tag = 'fonix-div';
var shadow;
bool disabled;
factory fonixDiv() => new Element.tag(tag);
fonixDiv.created() : super.created() {
shadow = this.createShadowRoot();
shadow.host.innerHTML = '<button id="d">click</button>';
shadow.host.onClick.listen((e){
this.host.dataset.disabled='true'; // set Attribute to the custom element
});
shadow.children.d.onClick.listen((e){
this.text = "you clicked me :(";
// or shadow.children[0].textContent="Shadow DOM content changed";
this.disabled=true;
// alert("All: button, text and host should be change");
});
}
#override
void attached() {
super.attached();
this.disabled=disabled;
}
}
I'm not sure about the accuracy of the balance of the code, I can check it only after I see the button.
any help.
The error is correct: in Dart 'this' is not bound contextually as in JS and instead we have lexical scoping;
in your dart code you are actually changing the text content of the custom element and not of the target of the event (the button in the shadow root). So basically you have a custom element, you set the text content on it but you also have a shadow root created inside of that same DOM node and it shadows everything else you put inside that custom element and that is why you do not see it and continue to see the shadow root's content - this is how shadow root works by design.
To fix it you need to update the text content (and the disabled property) on the button (for example e.target.text = ...).
Hope this helps.
Seems like the .host should be removed from this line
shadow.host.innerHTML = '<button id="d">click</button>';
shadow.innerHTML = '<button id="d">click</button>';
The jsfiddle doesn't have it and it seems weird. I think with .host you add it basically to this and therefore as child not as content.
I think the main issue is: Use innerHtml instead of innerHTML.
There are a few additional minor things you need to fix:
Remove 'host', as Gunter says, you want to set the innerHtml of the shadow.
Instead of shadow.children.d.onClick, do shadow.querySelector('#d').onClick.
Also, do dataset['disabled'] instead of dataset.disabled.

Dojo dialog, the iPad and the virtual keyboard issue

Recently, I have been working on a project where the interface should work for desktop and tablets (in particular the iPad).
One issue I am coming across is with a Dojo dialog on the iPad when text entry is taking place.
Basically here is what happens:
Load Dojo interface with buttons on iPad - OK
Press button (touch) to show dialog (90% height and width) - OK
Click on text box (touch) like DateTextBox or TimeTextBox - OK, the virtual keyboard is opened
Click the date or time I want in the UI (touch) - OK, but I can't see all of the options since it is longer than the screen size...
Try to scroll down (swipe up with two fingers or click 'next' in the keyboard) - not OK and the dialog repositions itself to have it's top at the top of the viewport area.
Basically, the issue is that the dialog keeps trying to reposition itself.
Am I able to stop dialog resizing and positioning if I catch the window onResize events?
Does anyone else have this issue with the iPad and Dojo dialogs?
Also, I found this StackOverflow topic on detecting the virtual keyboard, but it wasn't much help in this case...
iPad Web App: Detect Virtual Keyboard Using JavaScript in Safari?
Thanks!
I just came across the same issue yesterday and found a hack,
which is not an elegant solution.
If you want to stop the dijit.Dialog from repositioning you can:
1) Set the property ._relativePosition of a dijit.Dialog object
(in this case it's "pop") after calling the method pop.show():
pop.show();
pop._relativePosition = new Object(); //create empty object
Next steps would probably be:
Check browser type&OS: dojo or even better BrowserDetect
Check when the virtual keyboard is activated and disable repositioning
Extend dijit.Dialog with custom class (handle all of the exceptions)
As suggested another way to do this is to override the _position function by extending the object (or maybe relative position, or other method). Here is my solution which only allows the dialog to be positioned in the middle of the screen once. There are probably better ways to change this by playing with the hide and show events but this suits my needs.
dojo.provide("inno.BigDialog");
dojo.require("dijit.Dialog");
dojo.declare("inno.BigDialog",dijit.Dialog,{
draggable:false,
firstPositioned : false,
_position : function() {
if (!dojo.hasClass(dojo.body(), "dojoMove") && !this.firstPositioned) {
this.firstPositioned = true;
var _8 = this.domNode, _9 = dijit.getViewport(), p = this._relativePosition, bb = p ? null
: dojo._getBorderBox(_8), l = Math
.floor(_9.l
+ (p ? p.x : (_9.w - bb.w) / 2)), t = Math
.floor(_9.t
+ (p ? p.y : (_9.h - bb.h) / 2));
if (t < 0) // Fix going off screen
t = 0;
dojo.style(_8, {
left : l + "px",
top : t + "px"
});
}
}
});
You can override the _position function and call the _position function of the superclass only once. (See http://dojotoolkit.org/reference-guide/dojo/declare.html#calling-superclass-methods)
if (!dojo._hasResource["scorll.asset.Dialog"]) {
dojo._hasResource["scorll.asset.Dialog"] = true;
dojo.provide("scorll.asset.Dialog");
dojo.require("dijit.Dialog");
dojo.declare("scorll.asset.Dialog", [dijit.Dialog], {
_isPositioned: false,
_position: function () {
if(this._isPositioned == false) {
// Calls the superclass method
this.inherited(arguments);
this._isPositioned = true;
}
}
})
}

Resources