TornadoFX (JavaFX):How to perform action when view becomes visible - kotlin

I'm new to TornadoFX and I'm having trouble detecting if a view is visible or not
My scenario is:
I have views with custom menu items, I have already added the framework to ensure these are all added to my main menubar.
What I want to do now is make these visible/invisible if the given view is visible to the user.
My views are (in this instance) part of tabs in a tab pane. similar to...
root = tabpane {
tab {
content = MyView.root
...
I have tried
root.focusedProperty().onChange { state -> menu.isVisible = state }
This works when I click on the view (a list view in this case) but this view is not automatically focussed when I select the tab.
I have also tried
root.visibleProperty().onChange { state -> menu.isVisible = state }
but this property does not change when the view is "Shown" by selecting the tab (I assume this property is only set if I manually show/hide the view)
I could move the logic up to the tab itself but this breaks encapsulation.
The view should not have to know that it's part of a tab and the tab should not have to know that part of its content tree require triggering
Is there a property I can use (or another mechanism) to detect if the user can see the view
i.e. if the view is upper most within the application?
As a separate question, is this the right approach or is there a built in way of achieving the dynamic menus? - This is something I took for granted in .net WPF

Related

View Controllers, Popup buttons, AppDelegates, Status Menus, and headaches

This is kinda long but I want to give as many details as possible.
I have created a status bar app. One of the things I've done is made it to where there is a "Settings" menu item that if you click on, an NSWindow pops up with 5 different buttons -- these buttons are tied to their own custom NSViewController so that if you click them, the View Controller changes, but the window remains the same, just like any other StatusBar app.
On one of the view controllers is a popup button with several user selectable options. If I add a button to the specific VC (view controller) and link that to an ibaction that pulls the selected index of the popup button, it works just fine (i.e. I select item 2, it logs item 2).
Now here's where things get. . . odd. I've created a submenu that would in theory allow the user to quickly change the selected item of the popup linked to my custom view controller. Think of this submenu as being labeled 1-4 and clicking one of those items would change the index of the popup button, however every time I try this and follow it up with a NSLog to ensure the button has changed, it ALWAYS reads zero, in other words, it NEVER changes.
Here's what I tried.
Just like with every other view controller I've ever used, I create a new object of my view controller (alloc, init), and reference the popup button object that i've created as a property. This compiles just fine, but returns only zero no matter what is selected.
I've tried calling the method that I know works (the button that is on the view controller containing the popup), but again, this returns only zero no matter what is selected.
Any advice would be greatly appreciated.
tl;dr: can't change a popupbutton on a view controller from the app delegate or nsstatusmenu item, it just always returns zero.
EDIT: I have found a work around since I can communicate to my app delegate just fine, I created an int property and set it to zero. From there, whenever my popupbutton on my VC changes, I change the value of the app delegate int property and just ensure that whenever the nib launches, it set's the selected item to the app delegate property. I feel there has to be a more straight forward way to just get the value of the popup and change it from the app delegate.
EDIT 2: Some code as requested. I realized I needed to point the the view controller by using initwithnibname from the app delegate and then load the view. Doing so allows me to pull the first object in the popup button, any subsequent changes are not recognized unless I do so via my test button on the view controller itself. Also, I'm adding values to my popup in my awakefromnib in the view controller.
searches_VC = [[Searches_ViewController alloc] initWithNibName:#"Searches_ViewController" bundle:nil];
[searches_VC loadView];
NSLog(#"Selected Title: %#",[[searches_VC profilePopupOutlet] titleOfSelectedItem]);

Questions about creating 'Camera Roll'-esque functionality

I am fairly new to Objective-C so forgive my ignorance ahead of time =] Here is what I have so far:
The application is a tab bar style application
The view, as relevant to this post, contains several buttons that when clicked pull down different types of images
On click of the button an Array is populated with the data returned from the web service
A new view is displayed with a UIImageView inside of it
Now here is what I am hoping to get clarification on (or simply ideas)
As I said the application itself is a tab bar style app but I am having some trouble with the third view I've added. Currently when I click on a button the view loads correctly but it is loading inside of the Tab Bar view area. This isn't optimal and I would like for this new view to be displayed overtop of the Tab Bar thus taking up the entire area on the phone. I am opening this view from inside the View Controller that contains the button (which is a tab view) like this:
UIViewController * browsePictures = [[UIViewController alloc]initWithNibName:#"PictureGalleryViewController" bundle:[NSBundle mainBundle]];
[self.view addSubview:browsePictures.view];
On this third view I have a UIImageView (I am not sure this is the correct view for the app) that needs to be populated via the data that is returned from the web service. Returning binary data, as I found out, is very inefficient via JSON so I am returning URL's which means I will need to make a call out to the web for every image returned. I am ok with this I am just curious if there is a better way to do it.
The functionality I am trying to achieve with this third view is similar to the Camera Roll functionality of the iPhone. In this case when the user gestures to the left or the right it would move the current index of the array up or down one and load the next photo in the array. I am not sure how to implement this functionality.
I think that is all for now. Thanks!

Change what window displays (Mac - Cocoa)

Sorry if this is a really basic question but I'm new to XCode and Mac development in general. I want to know how to get a window to change its contents without having to close and open a new window. For example:
- (IBAction)handlelock:(id)sender {
[_window orderOut:sender];
[_loginwindow makeKeyAndOrderFront:sender];
}
But rather than closing _window and opening _login window, is there a way to make _window display the contents of _login when I click the button?
Or, just swap the window's content views:
- (IBAction)handlelock:(id)sender {
NSView *previousContentView = _window.contentView;
_window.contentView = _loginwindow.contentView;
_loginwindow.contentView = previousContentView; // just store it in the other window
}
Usually you wouldn't need multiple windows for this though, you would just have another view and swap it in.
There are several ways to do this. You could have a separate view in your xib file that contains what you want in your login window, and then call setContentView:loginView on you window, and that will swap out the old view for the new one. You would want to have a property that points to the original view, if you want to be able to switch back to it.
Another way is to use a tab view -- if you don't like the looks of a tab view, there is a tabless tabview that doesn't look like it has tabs --- you would have one view in one tab, and the login view in another.

XCode/Cocoa Mac Changing Views

I'm having trouble figuring out how to change between different custom views in my XCode project.
I have my Main nib file, consisting of 1 main window, and 5 custom views. The main window consists of 5 buttons, all which need to connect to the different views. So for example I click on button 1 and it closes the current menu and loads custom view 1.
I'm having trouble figuring out how this would be done.
I guess I would create IBOutlets for the 5 different buttons and the 5 custom views, and connect them to different methods such as openView1, openView2, where each method would close the current menu and load the custom view?
Could anyone help me code-wise how I would achieve this?
Any help greatly appreciated.
Thanks
So essentially you want a tab view?
You can make an NSTabView in Interface Builder. Set the number of tabs to 5. Then lay out the contents of the views you want inside that.
If you are happy using the standard system provided visual look for your tabs, then you're done. If however you want to have custom buttons that switch tabs, read on.
With your tab view selected, set its style to Tabless:
This makes the tab buttons disappear. That means that switching between views needs to be done through code. First you'll need an IBOutlet that represents your tab view itself: connect that up. Then write an IBAction method for openView1:, that might look something like this:
- (IBAction)openView1:(id)sender
{
[tabView selectTabViewItemAtIndex:0];
}
Make yourself a button (that sits in your window somewhere outside the tab view, otherwise you'd only be able to access it from one tab!) and connect it to this action.
This is probably the easiest way to get going with an interface like this. There's a whole bunch of ways to improve on it depending on how you want to structure your code. For instance, it sounds like you're coming from iOS development, where you'd make a UIViewController for each tab. Well, on the Mac there exists NSViewController, so you can use a similar pattern: but if you do you'll need to write some code that handles getting your view controllers' views into your tab view. It doesn't happen automatically through Interface Builder like it does on iOS. This tutorial should get you started if you choose to go that route.

Problem tabbing to field when adding and removing view

I have an scope bar containing a NSSearchField. The bar can be shown and hidden using a menu item. I generate this bar by creating a new NSViewController (and loading a new view from the XIB). When the bar is shown, I do a addSubview: to the window's contentView; when the bar is hidden, I do removeFromSuperview to the view within the view controller.
If when I launch the app and the bar is already opened, hitting tab toggles between the main view within the window (a table view) and the search field in the scope bar. If I launch the app and the bar isn't already shown, once I do show the bar I can tab from the table view to the search field, but not the other way.
Once I remove the scope bar for the first time, then show it again, I can no longer tab between the search field and the table view, no matter which view is currently selected.
Is there something I need to be doing besides addSubview: and removeFromSuperview? I can't wrap my head around why this won't work, and especially why I get different behaviors if the bar is shown on launch or not.
You need to set the nextKeyView of both views if you want to control what happens when you hit the tab key.
[yourTableView setNextKeyView:yourSearchField];
[yourSearchField setNextKeyView:yourTableView];
However, you need to be careful because you can break the automatically constructed key-view loop. This article has more detail on how to handle this situation.
I was able to get the desired behavior by setting setAutorecalculatesKeyViewLoop: to true on the views' window.