FABMenuController to share FAB across view controllers - cosmicmind

I am following the CardTableView demo code and its way of embedding view controllers so that the FABMenuController is on top. For some reason, the following code works, until I try to add the FABController:
let tabs = AppPageTabBarController(viewControllers:[InvitedViewController(), CoordinatingViewController(), PastViewController()])
let toolbar = AppToolbarController(rootViewController: tabs)
let root = MyTeeUpsViewController(rootViewController: toolbar, leftViewController: NavDrawerContainerController())
let snackBarController = AppSnackbarController(rootViewController: root)
let fabMenuController = AppFABMenuController(rootViewController: snackBarController)
self.present(fabMenuController, animated: true)
I have implemented the AppFABMenuController just as the demo code has, and it exists, and inherits from the FABMenuController from MaterialSwift. I can't understand why I get the error: fatal error: unexpectedly found nil while unwrapping an Optional value
Regarding the view hierarchy I think it makes more sense to embed the SnackbarController last, but even if i do this it still fails on the line that declares let fabMenuController=...

I would approach your setup like so:
let tabs = AppPageTabBarController(viewControllers:[InvitedViewController(), CoordinatingViewController(), PastViewController()])
let toolbar = AppToolbarController(rootViewController: tabs)
let fabMenuController = AppFABMenuController(rootViewController: toolbar)
let snackBarController = AppSnackbarController(rootViewController: fabMenuController)
let navDrawer = MyTeeUpsViewController(rootViewController: snackBarController, leftViewController: NavDrawerContainerController())
self.present(navDrawer, animated: true)
Basically, the NavigationDrawerController should always be the lowest level, or root of your view stack. If you were to set this up with a login, you could setup the NavigationDrawerController as your AppDelegates rootViewController, and disable the side panels. When the user successfully logs in, you could call navigationDrawerController?.transition(to: MyNewVC) and then enable the side panels. This way the login view controller is off the stack and everything is setup. I put the ToolbarController as a child of the FABMenuController so that you can switch between controllers and either add an entirely new top navigation controller or remove it completely. The look and feel of Material usually covers everything on the screen when the FABMenu is displayed. The Snackbar could go above or below the FABMenu, but that is really up to you, visually, it shouldn't ever make a difference.
As a note, in the latest Material 2.9.*, you no longer need to cast the rootViewController types and you no longer need to search in child view controllers only for the transitioning controller. Meaning, from anywhere, you could now call toolbarController?.transition ... etc.
Hope this helps :)

Related

#material material-component-web Invalid tab component given as activeTab

firstly let my say that the mdc documentation is difficult for non-pros like me.
I'm using Elixir Phoenix and Brunch.
I import and everything is fine.
import {MDCTab, MDCTabFoundation} from '#material/tabs'; import
{MDCTabBar, MDCTabBarFoundation} from '#material/tabs'; import
{MDCTabBarScroller, MDCTabBarScrollerFoundation} from
'#material/tabs';
I manually instantiate the tab bar in a separate function that I export
export var Tabbable = {
run: function(MDCTabBar, el){
var myDynamicTabBar = window.myDynamicTabBar = new MDCTabBar(document.querySelector('#' + el));
Which is following the documentation like this
const tabBar = new MDCTabBar(document.querySelector('#my-mdc-tab-bar'));
but is slightly different to the documentation's use of the tab bar in their code snippet
var dynamicTabBar = window.dynamicTabBar = new mdc.tabs.MDCTabBar(document.querySelector('#dynamic-tab-bar'));
But, whenever I try to use mdc I get a 'not defined' error. Therefore, I'm not using it :-)
Now, when the user clicks the tab bar I capture that like this:
myDynamicTabBar.listen('MDCTabBar:change', function ({detail: tabs}) {
var nthChildIndex = tabs.activeTabIndex;
updatePanel(nthChildIndex);
});
The subtle difference is that my myDynamicTabBar is MDCTabBar but the documentation's dynamicTabBar is mdc.tabs.MDCTabBar
My tab control works, but it throws an error only visible in the console:
Uncaught Error: Invalid tab component given as activeTab: Tab not
found within this component's tab list
which is likely because I'm not using mdc.tabs? The documentation notes the change event happens on the MDCTabBar.
Therefore, how do I get rid of this annoying error in the console?
And why can I not access the global mdc? I have tried this in my Brunch file
globals: { mdc: "#material"}
But no good.
I'm right behind you on this! I'm frustrated with the docs too :(
You answered your own question in this Elixir thread which is very informative.
I found the real solution in this thread https://github.com/hyperapp/hyperapp/issues/546
MDCTabBar automatically initiates its children. So initiating tabs will result in that error.
The fix is to just initiate MDCTabBar

NavigationManager's startNavigation() has blank map

I'm trying to use turn by turn navigation using SKNavigationManager's startNavigation(navigationSettings). Interestingly it works flawless in 'Simulation' mode but when I switch to 'Real' mode there is no map on the screen. It's just that the map is not drawn on screen, but the rest like annotations and other stuff are populated and working fine.
I've used SKToolsNavigatoinManager and it works fine, but I don't want to use it as it has a lot of UI interfaces which are not useful for my application.
Any help is appreciated.
Here is the settings and the navigationManager code I'm using
SKNavigationSettings navigationSettings = new SKNavigationSettings();
SKNavigationManager navigationManager = SKNavigationManager.getInstance();
navigationSettings.setNavigationType(SKNavigationSettings.SKNavigationType.REAL);
navigationSettings.setNavigationMode(SKNavigationSettings.SKNavigationMode.PEDESTRIAN);
navigationManager.setMapView(navMapView);
navigationManager.startNavigation(navigationSettings);
If i don't use the navigationManager.setMapView(navMapView); I get a different view.
1. This is how the screen looks like after I start navigation
2. This is how the screen looks like before navigation
The map is drawn to the screen its just centered at the point [0,0] which is in the middle of the Atlantic ocean therefore the screen is blue. To have the camera follow the current location you must do the following 2 steps:
Set follow positions to true on your SKMapView object: navMapView.getMapSettings().setFollowPositions(true);
Create a SKCurrentPositionProvider and set the SKCurrentPositionListener
SKCurrentPositionProvider positionProvider = new SKCurrentPositionProvider(activity);
positionProvider.setCurrentPositionListener(new SKCurrentPositionListener(){
#Override
public void onCurrentPositionUpdate(SKPosition currentPosition) {
SKPositionerManager.getInstance().reportNewGPSPosition(currentPosition);
}
});
positionProvider.requestLocationUpdates(true, true, false);

COMException^ on FilePicker PickSingleFileAsync() call

I'm trying to make a game (Universal DX11 application) and at some point I need access to image library to allow user to select avatar. But for some reason call of PickSingleFileAsync on picker rises an exception.
Windows::Storage::Pickers::FileOpenPicker^ openPicker = ref new Windows::Storage::Pickers::FileOpenPicker();
openPicker->SuggestedStartLocation = Windows::Storage::Pickers::PickerLocationId::PicturesLibrary;
openPicker->ViewMode = Windows::Storage::Pickers::PickerViewMode::Thumbnail;
// Filter to include a sample subset of file types.
auto filters = openPicker->FileTypeFilter;
filters->Clear();
filters->Append(".png");
openPicker->PickSingleFileAsync();// same exception with create_task(...);
Seems like the sample works only if I put it into UI thread. How can I use picker from my own thread?
UPD: HRESULT:0x80004005
Ok, I just decided to call dipatcher's RunAsync to execute this code. But I still have no idea why I cannot open picker inside non-UI thread.

How to use "standardized track listings" in Spotify apps

The Spotify UI guidelines for Spotify apps (at https://developer.spotify.com/technologies/apps/guidelines/design/) say "When listing tracks in your app, use our standardized track listings". I cannot find any examples in the documentation on how to use these "standardized track listings". By using the Inspector I have found classes in list.css (such as sp-list and sp-item) which it looks like I need to use but have not been able to work out quite how to use these to recreate the look of the Spotify track listings.
The Billboard Top Charts app appears to use track listings like I need, but I can't find ay way to see how they are doing this as the Inspector only works for your own apps as far as I can tell.
Does anybody have any advice or examples?
Some examples
sp = getSpotifyApi(1);
var m = sp.require("sp://import/scripts/api/models");
var v = sp.require("sp://import/scripts/api/views");
// Example 1
var tpl = new m.Playlist();
var tempList = new v.List(tpl);
tpl.add(m.Track.fromURI("spotify:track:4z4t4zEn4ElVPGmDWCzRQf"));
tpl.add(m.Track.fromURI("http://open.spotify.com/track/7E8JGVhbwWgAQ1DtfatQEl"));
tpl.add(m.Track.fromURI("spotify:track:40YBc3mR3yyqyYvtesQOMj"));
tpl.add(m.Track.fromURI("spotify:local:Rolling+Stones:A+Bigger+Bang:Rain+Fall+Down:293"));
document.body.appendChild(tempList.node);
// Example 2
var pl = m.Playlist.fromURI("spotify:user:username:playlist:424km2k4m24");
var list = new v.List(pl);
document.body.appendChild(list.node);
// Example 3
var album = m.Album.fromURI("spotify:album:1vWnB0hYmluskQuzxwo25a");
var albumList = new v.List(album);
albumList.node.classList.add("album");
document.body.appendChild(albumList.node);
Thanks for asking, I had exactly the same question too!
I too get the issue where i get no actual content added - just the wrapper div. Not including api.css makes it work, but the list is obviously not styled. Including css/list.css directly breaks it too. Creating my own copy and selectively commenting out list.css I found the offending rule to be:
.sp-list > div {
if you change this to be
.sp-list {
then it renders fine. No idea what is going on. Obviously this solution is not idea because I've just duplicated what's meant to be a common resource...

How to attach mouse event listeners to embedded nsIWebBrowser in C++

I've embedded an nsIWebBrowser in my application. Because I'm just generating HTML for it on the fly, I'm using OpenStream, AppendToStream, and CloseStream to add content. What I need is to add event listeners for mouse movement over the web browser as well as mouse clicks. I've read documentation and tried lots of different things, but nothing I have tried has worked. For instance, the code below would seem to do the right thing, but it does nothing:
nsCOMPtr<nsIDOMWindow> domWindow;
mWebBrowser->GetContentDOMWindow(getter_AddRefs(domWindow));
if (!mEventTarget) {
mEventTarget = do_QueryInterface(domWindow);
if (mEventTarget)
mEventTarget->AddEventListener(NS_LITERAL_STRING("mouseover"), (nsIDOMEventListener *)mEventListener, PR_FALSE);
}
Perhaps it isn't working because this is run during initialization, but before any content is actually added. However, if I add it during AppendStream, or CloseStream, it segfaults.
Please tell me a straightforward way to do this.
Well, here's the answer:
nsCOMPtr<nsIDOMEventTarget> cpEventTarget;
nsCOMPtr<nsIDOMWindow> cpDomWin;
m_pWebBrowser->GetContentDOMWindow (getter_AddRefs(cpDomWin));
nsCOMPtr<nsIDOMWindow2> cpDomWin2 (do_QueryInterface (cpDomWin));
cpDomWin2->GetWindowRoot(getter_AddRefs(cpEventTarget));
rv = cpEventTarget->AddEventListener(NS_LITERAL_STRING("mousedown"),
m_pBrowserImpl, PR_FALSE);

Resources