qooxdoo virtual tree as menu - menu

I have a function, which creates layout with widgets. The problem is what one of the widget is virtual tree (on left side of layout) and the second widget on the right side depends on clicked row on left side. Virtual tree works like menu, which should return value of row name to the right widget and recreate it on right side with provided data. However currently it is not recreating, but adding a new widget to the old one. How to recreate widget on the right side not adding it to the existing one (interface is similar to qooxdoo demobrowser view with tests)?
_createLayout : function()
{
// Create main layout
var dockLayout = new qx.ui.layout.Dock();
var dockLayoutComposite = new qx.ui.container.Composite(dockLayout);
this.getRoot().add(dockLayoutComposite, {edge:0});
// Create header
this.__header = new bank.view.Header();
dockLayoutComposite.add(this.__header, {edge: "north"});
// Create toolbar
this.__toolBarView = new bank.view.ToolBar(this);
dockLayoutComposite.add(this.__toolBarView, {edge: "north"});
// Create the tree view, which should create dockLayout below, when user clicks with Row value
dockLayoutComposite.add(this.getTreeView(), {edge: "west"});
// This layout should be created and recreated with clicked row value
dockLayoutComposite.add(bank.InvoiceListBuilder.createList("Tree_returned_value"), {edge: "center"});
},
getTreeView : function()
{
var hBox = new qx.ui.container.Composite(new qx.ui.layout.HBox(20));
var tree = new qx.ui.treevirtual.TreeVirtual("Tree");
tree.setColumnWidth(0, 170);
tree.setAlwaysShowOpenCloseSymbol(true);
var dataModel = tree.getDataModel();
var te2 = dataModel.addBranch(null, "Folders", true);
dataModel.addBranch(te2, "Incoming", false);
dataModel.addBranch(te2, "Outgoing", false);
dataModel.addBranch(te2, "Drafts", false);
dataModel.setData();
hBox.add(tree);
var foldercontent = bank.InvoiceListBuilder.createList("incoming");
tree.addListener("changeSelection",
function(e)
{
// this function should return row value to function: bank.InvoiceListBuilder.createList("Tree_returned_value") and create/recreate dockLayout with newly created widget from bank.InvoiceListBuilder.createList function
});
return hBox;
},

you are using a old virtual tree implementation (qx.ui.treevirtual.TreeVirtual), I would suggest to use the qx.ui.tree.VirtualTree implementation.
The next step is to use something like a controller for your view, which listen to the selection and creates widgets when the selection changed. The controller should know the container for adding widgets.
When your left side is just a list. You can also use the virtual list (qx.ui.list.List) and use a set of the tree model.
Cheers,
Chris

Related

How to add an absolute element in a NativeScript page

I want to be able to just place a View component (plugin) into the page through code and have it appear at some X\Y on the page... but I'm a bit stumped.
Any attempt to add via page.content kinda adds it to the layout\render pass so it occupies space.
So this would get injected into "any" page at "any" time, I have no control over the markup this would be used in (know what I mean?) There is no XML for it and unfortunately the answer can't just be wrap everything in an AbsoluteLayout because one can't mandate that on users apps\layouts.
Thoughts, even possible?
Basically the simplest way to do this is to dynamically and be fully cross platform compatible is to create a AbsoluteLayout item in your JavaScript code, and dynamically insert your item and the AL into the page container.
Code would be something like this:
var AbsoluteLayout = require('ui/layouts/absolute-layout').AbsoluteLayout;
var myAL = new AbsoluteLayout();
var myItem = new myPluginItem();
// Set you left, right, top, bottom coords.
myItem.top = x;
// Add our item to the AbsoluteItem
myAL.addChild(myItem);
var frame = require('ui/frame');
var page = frame.topmost().currentPage;
var LayoutBase = require('ui/layouts/layout-base').LayoutBase;
page._eachChildView(function(view) {
if (view instanceof LayoutBase) {
view.addChild(myAL);
return false;
}
return true;
});
However, if you don't want to do this the really simple way; the only other way is to actually go a bit lower level. You can natively access the iOS view controller (page._ios.view) and the android view (page._nativeView), and then manually add it to the view by using things like addView (https://developer.android.com/reference/android/view/ViewManager.html) or addSubview (https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIView_Class/).
I would like to add you can set the Top and Left properties in TypeScript by importing AbsoluteLayout like so
import {AbsoluteLayout} from 'ui/layouts/absolute-layout';
and then using the exposed functions setLeft or setTop
AbsoluteLayout.setLeft(YourItem, LeftValue);
or
AbsoluteLayout.setTop(YourItem, TopValue);

JAVAFX imageview allow user to add tag

I am making an image gallery using javafx, i wish to have the feature which allow the user to add some tag(for human faces) to the imageview when the user is onclick at the imageview, it should grab the position of the mouse pointed and prompt a dialog for user to enter the name for the face and save it to database.
Is this achievable by using javafx?
If yes, how should i do that?
Your help is appreciated.
Sample output of my application below:
Sure it's possible. I created this simple example for a single Image that adds a button to the scene which adds a circle where the image was clicked. This should demonstrate the approach.
#Override
public void start(Stage primaryStage) {
ImageView imageView = new ImageView(...);
imageView.setPreserveRatio(true);
imageView.setFitHeight(200);
StackPane pane = new StackPane();
StackPane.setAlignment(imageView, Pos.TOP_LEFT);
pane.getChildren().add(imageView);
VBox box = new VBox(pane);
pane.setOnMouseClicked(evt -> {
if (evt.getButton() == MouseButton.PRIMARY) {
// create node(s) that uses the click data
Button button = new Button("Show point");
button.setOnAction(e -> {
// do something with the data on user interaction
box.getChildren().remove(button);
Circle circle = new Circle(evt.getX(), evt.getY(), 5, Color.RED);
Pane circlePane = new Pane(circle);
StackPane.setAlignment(circlePane, Pos.TOP_LEFT);
pane.getChildren().add(circlePane);
});
box.getChildren().add(button);
}
});
Scene scene = new Scene(box, 200, 300);
primaryStage.setScene(scene);
primaryStage.show();
}
For your application you would:
Create a different event handler that creates and/or initializes the UI according to your needs or shows a dialog. You also would register the listener to the ImageView directly (unless you need to add some elements on top of it, like I do)
Calculate the real click position in image coordinates using evt.getX() * imageView.getImage().getWidth() / imageView.getLayoutBounds().getWidth() (absolute position) or evt.getX() / imageView.getLayoutBounds().getWidth() (relative position); procede accordingly for y position. Do this calculation directly in the click handler, not when the user submits the entered information, since you may want the user to be able to resize the image. Also if you use the viewport property, you need to modify the calculations accordingly.
Create a different thread that sends the information to the database, when the user submits his/her edits. Of course you also need to store some information about the image currently shown in the ImageView somewhere.

Famo.us Menu - Click - Is there another way?

I have been going over the examples and demos of Famo.us, in particular the menus. In the examples such as taasky, timbre etc. the side menu is made up of MenuItemViews. Each MenuItemView comprises of a background, icon and title - each one a surface.
In order to make each menu item 'clickable' do I have to add an .click to each of the 3 surfaces that make up the MenuItemView and emit an event handler?
Or is there an easier way to make each menu item 'clickable'?
Thanks for your help in advance :)
Yes, what you want to do is pipe your surface events to the Views _eventOutput handler. This way the click event only needs to be defined on the view itself.
In this example there are two surfaces that each pipe all events to _eventOutput of view. When we click either surface, the views click event is triggered
Hope this helps!
var Engine = require('famous/core/Engine');
var Surface = require('famous/core/Surface');
var View = require('famous/core/View');
var context = Engine.createContext();
var view = new View();
var surface1 = new Surface({
size:[400,400],
properties:{
backgroundColor:'green'
}
});
surface1.pipe(view._eventOutput);
view.add(surface1);
var surface2 = new Surface({
size:[200,200],
properties:{
backgroundColor:'red'
}
});
surface2.pipe(view._eventOutput);
view.add(surface2);
view.on('click',function(evt){
console.log("View Clicked!");
})
context.add(view);

How to use Maki svg icons with Snap.svg?

I'm experimenting with Snap in order to use svg and need to be able to use the Maki icons defined in https://github.com/mapbox/maki.
My plan is to load the svg's I need, and then instantiate them for particular icons on a piece of Snap paper. But in order for this to work, I need to place the icon at a particular place on the paper, but I can't get translation to work. Neither one of the translation techniques below works; the code works as is, but always places the icon at the top left.
What am I missing? There's not enough documentation on Snap, and I don't know if the problem is with the way the Maki icon svg is defined, or my use of Snap.
var icon = Snap.load("maki/bicycle-24.svg", function(f) {
var g = f.select("g").clone();
// var g = f.select("#layer1").clone(); // also works
// g.transform("t120,120");
// var t = new Snap.Matrix();
// t.translate(120,120);
// g.transform(t);
paper.append(g);
});
The cloning needs to happen after the append, as when loading an svg in Snap its just a fragment.
So you will need to do something like...
paper.append(f);
var element = paper.select('#someId').clone();
element.transform( myTransform );
Thank you! That did the trick! And since Snap is so poorly documented, I'm going to insert the code here that allows a general solution.
// Base set from which markers are constructed
var iconSet = paper.group();
iconSet.attr({ class: 'hide' });
// Instantiations of icons
var markers = paper.g();
// Now, create SVG shape
var icon = Snap.load("maki/bicycle-24.svg", function(icon) {
// Add it to the icon set
iconSet.append(icon);
// Instantiate it and remove from main view
var element = paper.select('#svg4460'); // Copies it!
// var element = paper.select('#base'); // Selects something but doesn't work
// var element = paper.select('#layer1'); // Selects something but doesn't work
// var element = paper.select('#bicycle-24'); // Silent fail
element = element.clone();
element.remove();
// Clone this icon and move it
var t = new Snap.Matrix();
t.translate(10,120);
element.transform(t);
// Insert into main document view (markers)
markers.add(element);
});

Change UIBarButton Identifier on runtime

i want to change the Identifier of my UIBarButton when the value from my slider has changed. I tried it that way:
var button = new UIBarButtonItem(UIBarButtonSystemItem.Save);
this.Pad_btnClose = null;
this.Pad_btnClose = button;
But it doesnt work. I also tried it that way:
this.Pad_btnClose = new UIBarButtonItem(UIBarButtonSystemItem.Save);
doesn´t work too.
Setting that variable (or outlet, you don't say which) isn't going to remove the UIBarButtonItem from the screen.
In order to do that, you must create an outlet for the UIToolbar, then call:
yourToolbar.Items = new UIBarButtonItem[] { yourNewButtonItem };
Or if you want it to animate:
yourToolbar.SetItems(new UIBarButtonItem[] { yourNewButtonItem }, true);
This will overwrite the list of button items in the toolbar on the screen.

Resources