javafx close window - user-interface

I have a javafx app, and I was able to spawn another window, but I can't seem to find a way to close the the window i started in.
I used this to load the second window
var design = Launcher {};
javafx.stage.Stage
{
title: "Launcher"
scene: design.getDesignScene ()
}

stage.close(), but you would need a variable that references the original stage.

The way it worked for me:
I have the Main.fx where I instante the window I want to see first.
ex:
var mainWind:MainWindow = MainWindow{ };
MainWindow.fx will extend CustomNode and override create() method.
In the create() method I have the stage
ex:
public class MainWindow extends CustomNode{
...
var stage:Stage;
override function create():Node {
var n:Node;
stage = Stage {
width: 300
height: 180
title: "Login"
scene: Scene {
content:[ userText, userTextBox, passwdText, passwdTextBox, btnsBox ]
}
}
return n;
}
}
In MainWindow.fx I have a button with an event where I close this stage and show the other one .
ex:
Button {
text: "Login"
font:Font{ name:"Arial" size: 12}
layoutInfo:LayoutInfo {
width: loginbtn_width
}
blocksMouse: false
//close main window
onMouseClicked: function(e:MouseEvent):Void { stage.close(); }
//open the other window
action: function(){
// the ConnectionSettings will also extend CustomNode and will have its own stage
var conSetWind:ConnectionSettings = ConnectionSettings{ };
}
}
Iulia

Related

Gnome Shell Extension: Resize and position a window on creation

I am trying to write a Gnome Shell extension that resizes and positions a window when it is created. I am using the move_resize_frame method provided by the Meta.Window object to set the window's size and position, and I've also tried move and move_resize_frame. However, while the window is sized correctly, it is not being positioned correctly, and it seems that the window manager is applying some constraints on the window position. The window is not maximized.
Here is the code I am using:
let windowCreatedId, sizeChangedId;
function init() {
}
function enable() {
windowCreatedId = global.display.connect('window-created', onWindowCreated);
}
function disable() {
global.display.disconnect(windowCreatedId);
if (sizeChangedId)
global.display.disconnect(sizeChangedId);
}
function onWindowCreated(display, win) {
sizeChangedId = win.connect('size-changed', onSizeChanged);
resizeWindow(win);
}
function onSizeChanged(win) {
resizeWindow(win);
}
function resizeWindow(win) {
win.move_resize_frame(false, 20, 20, 2000, 2000);
}
What am I missing or what should I change to make this extension work properly?
Instead of the size-changed signal, you need to connect to the first-frame signal, which is triggered when the frame is first drawn on the screen.
Here's a full implementation:
const Meta = imports.gi.Meta;
let windowCreatedId;
function init() {
}
function enable() {
windowCreatedId = global.display.connect('window-created', onWindowCreated);
}
function disable() {
global.display.disconnect(windowCreatedId);
}
function onWindowCreated(display, win) {
const act = win.get_compositor_private();
const id = act.connect('first-frame', _ => {
resizeWindow(win);
act.disconnect(id);
});
}
function resizeWindow(win) {
win.move_resize_frame(false, 20, 20, 2000, 2000);
}
It uses the window's get_compositor_private() method, which feels a little iffy, but it works (and Material Shell uses it too...)

SPFx: How to re-render my WebPart on section layout change

I'm trying to make my WebPart responsive to the column width in my section layout.
I get the width of the bounding rectangle by calling
const width: number = this.domElement.getBoundingClientRect().width;
My render-function looks like this:
public render(): void {
const width: number = this.domElement.getBoundingClientRect().width;
this.domElement.innerHTML = `<div>${width}</div>`;
}
When I insert my WebPart into the SharePoint workbench, the number 736 is shown.
However, if I change the layout of the section from one column to something else, the number doesn't change.
What do I need to do to trigger the render function as soon as the layout (and therefor the width) changes?
To do that you can create an event listener and in your function set the state to re-render your webpart:
private handleWindowSizeChange() {
this.setState({
size: window.innerWidth
});
}
public componentDidMount() {
window.addEventListener('resize', this.handleWindowSizeChange.bind(this));
}
public componentWillUnmount() {
window.removeEventListener('resize', this.handleWindowSizeChange.bind(this));
}
I have used the ResizeObserver api to listen for the layout change in the layout.
The only problem is that it is not supported by IE, Edge, and Safari.
public componentDidMount() {
if(window.ResizeObserver) {
this.resizeObserver = new ResizeObserver(this.handleResize);
this.resizeObserver.observe(this.domElement)
}
}
public componentWillUnmount() {
if(window.ResizeObserver) {
this.resizeObserver.disconnect()
}
}

How do I initialise a NativeScript app fully programmatically (without XML)?

Here's what I have so far. The background goes green (the colour of the Page), but I'd expect a purple ContentView with some text inside to fill the page, too.
Is there anything further I'm missing?
import { on, run, launchEvent } from "tns-core-modules/application";
import { Frame } from "tns-core-modules/ui/frame/frame";
import { ContentView } from "tns-core-modules/ui/content-view/content-view";
import { TextBase } from "tns-core-modules/ui/text-base/text-base";
import { Page } from "tns-core-modules/ui/page/page";
on(launchEvent, (data) => {
const frame = new Frame();
const page = new Page();
page.backgroundColor = "green";
const contentView = new ContentView();
const textBase = new TextBase();
contentView.height = 100;
contentView.width = 100;
contentView.backgroundColor = "purple";
textBase.text = "Hello, world!";
contentView._addView(textBase);
page.bindingContext = contentView;
frame.navigate({ create: () => page });
data.root = page; // Incidentally, should this be the frame or the page?
});
run();
You are almost on track, you just need slight modification on your code.
import { on, run, launchEvent } from 'tns-core-modules/application';
import { Frame } from 'tns-core-modules/ui/frame/frame';
import { ContentView } from 'tns-core-modules/ui/content-view/content-view';
import { TextField } from 'tns-core-modules/ui/text-field';
import { Page } from 'tns-core-modules/ui/page/page';
run({
create: () => {
const frame = new Frame();
frame.navigate({
create: () => {
const page = new Page();
page.backgroundColor = "green";
const contentView = new ContentView();
const textField = new TextField();
contentView.height = 100;
contentView.width = 100;
contentView.backgroundColor = "purple";
textField.text = "Hello, world!";
contentView.content = textField;
page.content = contentView;
return page;
}
});
return frame;
}
});
You don't have to wait for launch event, you could set the root frame in run method itself.
In your code, you were creating the frame but never adding it to root UI element or mark the frame itself as root element
It's recommended to use .content to add child for a ContentView / Page as they are originally designed to hold one child element only.
Use TextField / TextView for input text, TextBase is just a base class.
It seems to me that you try to overcomplicate. You can replace XML with code just by implementing createPage method - Create a page via code.
I just modified default NS + TypeScript Playground template to operate without XML - NS + TypeScript template without XML.
I think you can't leave run as empty as it is expecting an entry to start the app. From {NS} website,
You can use this file to perform app-level initializations, but the
primary purpose of the file is to pass control to the app's root
module. To do this, you need to call the application.run() method and
pass a NavigationEntry with the desired moduleName as the path to the
root module relative to your /app folder.
if you look for run code in "tns-core-modules/application"
function run(entry) {
createRootFrame.value = false;
start(entry);
}
exports.run = run;
and
function start(entry) {
if (started) {
throw new Error("Application is already started.");
}
started = true;
mainEntry = typeof entry === "string" ? { moduleName: entry } : entry;
if (!androidApp.nativeApp) {
var nativeApp = getNativeApplication();
androidApp.init(nativeApp);
}
}

Xamarin - Make rotations with CoreGraphics.CGAffineTransform

I want to make a UI Image rotate while content is downloading and I can't seem to make it rotate.
I have this event:
public override void ViewDidAppear(bool animated)
{
NoConnectionView.Hidden = CheckConnectivityStatus();
Task.Run(async () => await StartSpinningAnimation(true));
}
Which then fires this method:
protected async Task StartSpinningAnimation(bool IsSpinning)
{
do
{
UpdateActiveImage.Transform = CoreGraphics.CGAffineTransform.MakeRotation((float)Math.PI / 4);
}
while (IsSpinning);
return;
}
The page will eventually change after files are downloaded so I just want it to spin forever. It does animate at all. Does anyone have any ideas?
Using C# and Xamarin.iOS to develop iOS is a letter bit different from the Native language, Whenever you want to invoke some UI element in your background thread(like you need make some UI do an animation), you must use:
InvokeOnMainThread(delegate {
//Do something related UI stuff
});
If you add a try catch for it, you will get the exception like that "You are calling a method that can only be invoked in UI thread";
And by the way, you can not just use a do while to make an animation, I write a sample for you, you can take a look:
public partial class ViewController : UIViewController
{
bool needAnimate = true;
int count = 0;
UIView animationView = new UIView();
public ViewController (IntPtr handle) : base (handle)
{
}
public override void ViewDidLoad ()
{
base.ViewDidLoad ();
// Perform any additional setup after loading the view, typically from a nib.
animationView.Frame = new CoreGraphics.CGRect (50, 50, 100, 100);
animationView.BackgroundColor = UIColor.Red;
this.Add (animationView);
this.View.AddGestureRecognizer (new UITapGestureRecognizer (() => {
Task.Run(async () => await StartAnimation());
}));
}
private async Task StartAnimation()
{
do
{
Console.WriteLine ("count = " + count++);
InvokeOnMainThread(delegate {
UIView.Animate(0.25,delegate {
animationView.Transform = CoreGraphics.CGAffineTransform.MakeRotation((float)Math.PI / 4 * (count/4 + 1));
});
});
System.Threading.Thread.Sleep(250);
}
while (needAnimate);
return;
}
public override void DidReceiveMemoryWarning ()
{
base.DidReceiveMemoryWarning ();
// Release any cached data, images, etc that aren't in use.
}
}
The animation is not smoothly, you need to optimize it yourself.
If you still have some questions, just leave here, I will check it latter.
Hope it can help you and welcome to Xamarin.
I would use UIView.AnimateNotify to perform the animation with CoreGraphics and totally avoid spin-loops to do something like this.
Example that spins an image 180 degrees and back repeating forever until stopped:
bool _animateStopping = false;
protected void SpinningAnimation(bool animate)
{
if (_animateStopping) return;
_animateStopping = !animate;
if (animate)
{
UIView.AnimateNotify(1,
() =>
{
image.Transform = CGAffineTransform.MakeRotation((nfloat)(Math.PI)); // in one second, spin 180 degrees
},
(bool finished) =>
{
UIView.AnimateNotify(1,
() =>
{
image.Transform = CGAffineTransform.MakeRotation(0); // in one second, spin it back
},
(bool finished2) =>
{
SpinningAnimation(true);
});
});
}
else {
UIView.AnimateNotify(1,
() =>
{
image.Alpha = 0; // fade away in one second
},
(bool finished) =>
{
image.RemoveFromSuperview();
_animateStopping = false;
}
);}
}
Usage:
image = new UIImageView(new CGRect(100, 100, 100, 100));
image.Image = UIImage.FromFile("wag.png");
Add(image);
SpinningAnimation(true);
await Task.Delay(5000); // simulate performing downloads, when done stop the animiation
SpinningAnimation(false);

I want to combine the FormCode and AutomaticAdvance rotator types

How can I create a rotator with "FormCode" mode while being able to start that rotator automatically when the page loads? In other words, to start the rotator automatically while enabling end user to stop/start/move next/move back.
I need a complete sample code for the call.
I've used the following JavaScript/JQuery code for FormCode management:
<script type ="text/javascript">
//
function
startRotator(clickedButton, rotator, direction)
{
if
(!rotator.autoIntervalID)
{
refreshButtonsState(clickedButton, rotator);
rotator.autoIntervalID = window.setInterval(
function
()
{
rotator.showNext(direction);
}, rotator.get_frameDuration());
}
}
function
stopRotator(clickedButton, rotator)
{
if
(rotator.autoIntervalID)
{
refreshButtonsState(clickedButton, rotator)
window.clearInterval(rotator.autoIntervalID);
rotator.autoIntervalID =
null
}
}
function
showNextItem(clickedButton, rotator, direction)
{
rotator.showNext(direction);
refreshButtonsState(clickedButton, rotator);
}
// Refreshes the Stop and Start buttons
function
refreshButtonsState(clickedButton, rotator)
{
var
jQueryObject = $telerik.$;
var className = jQueryObject(clickedButton).attr("class"
);
switch
(className)
{
case "start"
:
{
// Start button is clicked
jQueryObject(clickedButton).removeClass();
jQueryObject(clickedButton).addClass(
"startSelected"
);
// Find the stop button. stopButton is a jQuery object
var stopButton = findSiblingButtonByClassName(clickedButton, "stopSelected"
);
if
(stopButton)
{
// Changes the image of the stop button
stopButton.removeClass();
stopButton.addClass(
"stop"
);
}
}
break
;
case "stop"
:
{
// Stop button is clicked
jQueryObject(clickedButton).removeClass();
jQueryObject(clickedButton).addClass(
"stopSelected"
);
// Find the start button. startButton is a jQuery object
var startButton = findSiblingButtonByClassName(clickedButton, "startSelected"
);
if
(startButton)
{
// Changes the image of the start button
startButton.removeClass();
startButton.addClass(
"start"
);
}
}
break
;
}
}
// Finds a button by its className. Returns a jQuery object
function
findSiblingButtonByClassName(buttonInstance, className)
{
var
jQuery = $telerik.$;
var ulElement = jQuery(buttonInstance).parent().parent();
// get the UL element
var allLiElements = jQuery("li", ulElement);
// jQuery selector to find all LI elements
for (var
i = 0; i < allLiElements.length; i++)
{
var
currentLi = allLiElements[i];
var currentAnchor = jQuery("A:first", currentLi);
// Find the Anchor tag
if
(currentAnchor.hasClass(className))
{
return
currentAnchor;
}
}
}
//]]>
And the following code for the calls:
<
a href="#" onclick="stopRotator(this, $find('<%= MyRotator.ClientID %>
')); return false;"
class="stopSelected" title="Stop">Stop
'), Telerik.Web.UI.RotatorScrollDirection.Left); return false;"
class="start" title="Start">Start
However, I cannot start the rotator on the page load. Tried to use this code in the in the MyRotator_DataBoud event, but did not work either:
protected void rrMyRotator_DataBound(object sender, EventArgs
e)
{
Page.RegisterClientScriptBlock(
"MyScript", " startRotator(this, $find('<%= MyRotator.ClientID %>'), Telerik.Web.UI.RotatorScrollDirection.Left);"
);
}
There are a couple of examples available in the Telerik online demos for this functionality and they have code you can use. See http://demos.telerik.com/aspnet-ajax/rotator/examples/clientapicontrol/defaultcs.aspx and http://demos.telerik.com/aspnet-ajax/button/examples/slideshow/defaultcs.aspx

Resources