Exchange part of view using TornadoFX - user-interface

I'm working on a Fitness App and try to create something like a menubar which exchanges the container to the right depending on the currently selected menu item. The solution I've come up with until now is that I derive every view that is bound to a menu item from the main view and exchange the container using the replaceWith<ExcerciseEditor>() function. It works but I figure there must be a better solution to this.
// MainView.kt
open class MainView : View("Fit App"){
protected val container: StackPane by fxid()
override val root: AnchorPane by fxml("/view/MainView.fxml")
fun createExercise(){
replaceWith<ExerciseEditor>()
}
// [...]
}
// ExerciseEditor.kt
class ExerciseEditor : MainView(){
init {
container.children += loadFXML<AnchorPane>("/view/ExerciseEditor.fxml")
}
// [...]
}
The app looks like this. The root of this view is a HBox containing two panes: to the left the menu bar and to the right a stack pane containing the other views.

Related

Vaadin Flow #Route annotation with layout set breaks layout style

I'm using Vaadin 12.0.3 and I'm trying to create a top menu bar using an AppLayout. Therefore I added the AppLayout, which contains the Menu to my main view - the DashboardView (which extends RouterLayout). This view should be the parent view for the MonitoringView which displays some data. Therefore I'm setting the #Route annotation to the MonitoringView like this: #Route(Monitoring.route, layout = DashboardView::class).
The problem is if I add layout = DashboardView::class to the annotation all styling of the MonitoringView is gone. This means texts are not displayed, (background-)colors and shadows are gone and so one. When I remove the layout part from the annotation everything looks fine but then I can't see the menu bar on top.
Here's the code for the mentioned classes:
The DashboardView, which should be the parent for the other view and contains the menu (AppLayout):
#UIScope
#SpringComponent
#Route("dashboard")
#PageTitle("Dashboard")
class DashboardView() : VerticalLayout(), BeforeEnterObserver, RouterLayout {
init {
val appLayout = AppLayout()
val menu = appLayout.createMenu()
menu.addMenuItems(
AppLayoutMenuItem("Page 1", "monitoring"),
AppLayoutMenuItem("Page 2")
)
add(appLayout)
}
}
The MonitoringView that shows monitoring data and should be displayed below the menu bar when the user clicks on "Page 1":
#UIScope
#SpringComponent
#Route("monitoring", layout = DashboardView::class)
class MonitoringView() : VerticalLayout(), BeforeEnterObserver {
...
}
Maybe the #Route property layout needs the java class instead of the Kotlin class?
Try layout = DashboardView::class.java.
See https://kotlinlang.org/docs/reference/reflection.html
Note that a Kotlin class reference is not the same as a Java class
reference. To obtain a Java class reference, use the .java property on
a KClass instance.

Navigation Drawer back button Xamarin

I am using this binding for this awesome Material Drawer Library by MikePenz.
I have implemented the Navigation Drawer with this library and I have also managed to change the hamburger menu to the back arrow when I go level deep. Now I have some problems to get the back arrow to work correctly. When I click on the back arrow, rather than going back to the previous page, it opens up the navigation drawer.
After looking into the original library, I have identified, the following code is responsible to manage the back arrow button. I would appreciate , if someone can help me a bit to write this listener code in C#.
.withOnDrawerNavigationListener(new Drawer.OnDrawerNavigationListener() {
#Override
public boolean onNavigationClickListener(View clickedView) {
//this method is only called if the Arrow icon is shown. The hamburger is automatically managed by the MaterialDrawer
//if the back arrow is shown. close the activity
AdvancedActivity.this.finish();
//return true if we have consumed the event
return true;
}
})
Here is the binding libray that I use : MaterialDrawer-Xamarin
And this is the link to the original Library : MaterialDrawer
Try something like this:
var result = new DrawerBuilder()
.WithActivity(this)
.AddDrawerItems(
//Add some items here
new DividerDrawerItem()
)
.WithOnDrawerNavigationListener(this);
and implement Drawer.IOnDrawerNavigationListener in your activity like this:
public bool OnNavigationClickListener(View clickedView)
{
this.Finish();
return true;
}

Add Context Menu to a dialogue in e4 rcp

I want to add a context menu to a dialogue. I want it in such a way that when clicked anywhere where it is empty a deafaul context menu appears. I have seen example of context menu added to table and tree but not a dialogue as a whole any snippets or examples will be greatly appreciated.
This is what I have tried.
import org.eclipse.jface.action.MenuManager;
#Override
protected Control createDialogArea(Composite parent) {
Composite container = (Composite) super.createDialogArea(parent);
GridLayout layout = new GridLayout(4, false);
layout.marginRight = 5;
layout.marginLeft = 10;
container.setLayout(layout);
MenuManager menuMgr = new MenuManager();
menuMgr.setRemoveAllWhenShown(true);
menuMgr.add(new Action("New Thing") {
/* (non-Javadoc)
* #see org.eclipse.jface.action.Action#run()
*/
#Override
public void run() {
System.out.println("came in options");
}
});
parent.setMenu(menuMgr.createContextMenu(parent));
productListTreeCheckBox(parent);
return super.createDialogArea(parent);
}
Try creating the menu in a similar way to the table/tree menu, but using to top level Composite for the dialog. Using a menu manager that might be something like:
Control topLevelComposite = ... get top level composite
MenuManager menuMgr = new MenuManager();
menuMgr.setRemoveAllWhenShown(true);
menuMgr.addMenuListener(... you menu listener....);
final Menu menu = menuMgr.createContextMenu(topLevelComposite);
topLevelComposite.setMenu(menu);
You will then have to call setMenu on every Composite and control in the dialog which you want to use this menu. You can just use:
control.setMenu(parent.getMenu());
for this (as long as you do it on everything starting from the children of topLevelComposite).

Create a Sizeable Draggable Pane in JavaFX 8

I am attempting to create a "workspace" where users can open several containers to display distinct information. These need to be moveable and sizeable (ScrollPane for example).
I have successfully created the majority of the functionality - however one thing is really causing me issues and I am not able to figure out the issue.
I created the following class:
public class WorkspaceMoveableSizeablePane extends Pane
public WorkspaceMoveableSizeablePane(Node view) {
getChildren().add(view);
init();
}
private void init() {
...set up the event handlers....
I attempt to use this pane by wrapping an existing pane like so in my WorkspaceController:
#FXML private openSampleWorkspaceNode() {
FXMLLoader loader = new FXMLLoader();
Parent node = loader.load(
this.getClass().getResource("MyView.fxml").openStream());
WorkspaceMoveableSizeablePane dn = new WorkspaceMoveableSizeablePane(node);
pane.getChildren().add(dn);
}
When I open it this way - I can size my Pane and drag it, however the children on the "node" which is an anchor pane stay in their current positions rather than get hidden.
To correct this issue, I wrapped the AnchorPane in a ScrollPane in the FXML file. This allowed the resize to happen - and as expected the portions out of bounds were not visible and the scrollbars appeared, however the drag stopped. When I attempted to track the mouse dragged event, it actually didn't fire unless I was resizing the WorkspaceMoveableSizeablePane.
//Event Listener for MouseDragged
onMouseDraggedProperty().set(event -> {
System.out.println("You are in the Mouse Dragged Event");
if(isTopSelected){
dragPaneToNewLocation(event);
}else if(isResizingHeight) {
handleResizeHeight(event);
}else if(isResizingWidth) {
handleResizeWidth(event);
}
});
I reverted my FXML to AnchorPane and changed the WorkspaceMoveableSizeablePane as follows to see if that would help:
public class WorkspaceMoveableSizeablePane extends ScrollPane
public WorkspaceMoveableSizeablePane(Node view) {
setContent(view);
init();
}
private void init() {
...set up the event handlers....
As before the resize worked, but the drag didn't. The mouse dragged event never fired. Additionally, my scroll pane was blank with nothing in it.
So I am at a loss on how to proceed with this attempt.
Is there a limitation on the event handlers of the ScrollPane? Is there a different event I should be listening for? Thanks!!
The issue was that the ScrollPane was trapping the MouseDragged event.
Added an Event Filter and all is good...
addEventFilter(MouseEvent.MOUSE_DRAGGED, event -> {
if(isTopSelected){
dragPaneToNewLocation(event);
}else if(isResizingHeight) {
handleResizeHeight(event);
}else if(isResizingWidth) {
handleResizeWidth(event);
}
});

How to make a new window open inside main view in griffon?

I use new version of griffon, 1.2.0.
Is there a way to open new window (second view) inside the main app window by clicking button or something?
Assuming the secondary View defines a top level Window container like the following
application(id: 'secondaryWindow', ...) { /* content */ }
and the application's configuration file (Application.groovy) contains an MVC group definition identified by 'secondary' then any controller may popup the window like this
import griffon.transform.Threading
class SomeController {
#Threading(Threading.Policy.INSIDE_UITHREAD_ASYNC)
def showSecondary = {
def group = createMVCGroup('secondary')
app.windowManager.show('secondaryWindow')
}
}

Resources