Just wondering what approach to take on this button with multiple nested states.
What I try to do here is to have a button with 4 states. It is active / inactive combined with a notification icon or not.
This is my button that is on a tab bar that controls pages.
<Panel Clicked="{gotoNotificationsPage}">
<WhileTrue ux:Name="notificationPageActive" Value="{notificationPageActive}"/>
<Panel ux:Name="notificationIconPanel" Width="42" Margin="6,0,0,0">
<WhileTrue Value="{notificationPageHasUpdates}">
<WhileTrue Value="{notificationPageActive}">
<Kudos.IconsTabBarNotificationsWhiteBadged Alignment="Left" ux:Name="notificationIconActiveHasUpdates" Height="36" Opacity="1"/>
</WhileTrue>
<WhileFalse Value="{notificationPageActive}">
<Kudos.IconsTabBarNotificationsRedBadged Alignment="Left" ux:Name="notificationIconHasUpdates" Height="36"/>
</WhileFalse>
</WhileTrue>
<WhileFalse Value="{notificationPageHasUpdates}">
<WhileTrue Value="{notificationPageActive}">
<Kudos.IconsTabBarNotificationsWhite Alignment="Left" ux:Name="notificationIconActive" Height="36" Opacity="1"/>
</WhileTrue>
<WhileFalse Value="{notificationPageActive}">
<Kudos.IconsTabBarNotificationsRed Alignment="Left" ux:Name="notificationIcon" Height="36"/>
</WhileFalse>
</WhileFalse>
</Panel>
</Panel>
I animate it on WhileActive
state.
<NotificationsPage Name="notificationsPage" router="router">
<WhileActive>
<Scale Target="notificationIconPanel" Factor="0.9" Duration="0.05"/>
<Change notificationPageActive.Value="true"/>
<Scale Target="notificationIconPanel" Factor="1.1" Duration="0.05" Delay="0.1"/>
</WhileActive>
</NotificationsPage>
In the js
file I have two observables connected to this:
var notificationPageHasUpdates = Observable(false);
var notificationPageActive = Observable(false);
Not sure if I would like to use nested WhileTrue
, or if I should use match case. Speed is crucial here during the transitions.
Possible to bind to a WhileTrue
by ux:Name
instead of using the observable as a middle man here?
Right now doing this to update the state doesn’t work. <Change notificationPageActive.Value="true"/>
Uldis
May 10, 2017, 8:49am
2
Hi Christer,
from looking at the code I’d suggest taking a slightly different approach. It seems to me that creating a ux:Class
for the icon would benefit you a lot, since then you can use ux:Property
, which then can be data-bound to whatever Observables as necessary.
Here’s a self-contained mockup of how that kind of a “notification panel” could look like / work:
<App>
<JavaScript>
var Observable = require("FuseJS/Observable");
var hasUpdates = Observable(false);
var pageActive = Observable(false);
module.exports = {
hasUpdates: hasUpdates,
pageActive: pageActive
};
</JavaScript>
<Panel ux:Class="BadgedRedWhiteButton" Width="42" Height="42">
<bool ux:Property="ShowBadge" />
<bool ux:Property="MakeRed" />
<WhileFalse Value="{ReadProperty ShowBadge}">
<Change theBadge.Opacity="0" />
</WhileFalse>
<WhileTrue Value="{ReadProperty MakeRed}">
<Change theIcon.Color="#f00" />
</WhileTrue>
<Text ux:Name="theIcon" Value="\o/" Color="#fff" Alignment="Center" />
<Circle ux:Name="theBadge" Color="#f00" Width="12" Height="12">
<Stroke Width="2" Color="#fff" />
<Translation X="20" Y="20" />
</Circle>
<Rectangle Color="#000" CornerRadius="5" />
</Panel>
<StackPanel Alignment="Center" ItemSpacing="8">
<BadgedRedWhiteButton ShowBadge="true" MakeRed="true" />
<BadgedRedWhiteButton ShowBadge="true" MakeRed="false" />
<BadgedRedWhiteButton ShowBadge="false" MakeRed="true" />
<BadgedRedWhiteButton ShowBadge="{hasUpdates}" MakeRed="{pageActive}" />
</StackPanel>
</App>
Note how on the last instance I’m using the hasUpdates
and pageActive
Observables, while the other three are there to simply test the variations.
The varying states are handled by first having a “rest state”, which is a white icon and a visible badge, and then changing the booleans makes them deviate from it. If needed, you can add animations there, too.
Hope this helps!
Great - thanks for the code snippet. Love this approach to it.
Wondering…
Can I update an observable directly from UX, as an alternative to updating the observable via a Callback Handler
or the code below where isNotificationPageActive
is a WhileTrue
?
<WhileActive>
<Change isNotificationPageActive.Value="true"/>
</WhileActive>
Uldis
May 10, 2017, 11:40am
5
Yeah, you can do something like that, but you’d Change
the Value
of the WhileTrue
, not the “observable”. You can put the Change
wherever you like, also inside of a WhileActive
as you’ve shown.
Updated snippet with a bit of toggling involved:
<App>
<JavaScript>
var Observable = require("FuseJS/Observable");
var hasUpdates = Observable(false);
var pageActive = Observable(false);
module.exports = {
hasUpdates: hasUpdates,
pageActive: pageActive
};
</JavaScript>
<Panel ux:Class="BadgedRedWhiteButton" Width="42" Height="42">
<bool ux:Property="ShowBadge" />
<bool ux:Property="MakeRed" />
<WhileFalse Value="{ReadProperty ShowBadge}">
<Change theBadge.Opacity="0" />
</WhileFalse>
<WhileTrue Value="{ReadProperty MakeRed}">
<Change theIcon.Color="#f00" />
</WhileTrue>
<Text ux:Name="theIcon" Value="\o/" Color="#fff" Alignment="Center" />
<Circle ux:Name="theBadge" Color="#f00" Width="12" Height="12">
<Stroke Width="2" Color="#fff" />
<Translation X="20" Y="20" />
</Circle>
<Rectangle Color="#000" CornerRadius="5" />
</Panel>
<WhileTrue ux:Name="swapStuff">
<Change firstBRWButton.ShowBadge="false" />
<Change firstBRWButton.MakeRed="false" />
</WhileTrue>
<Panel Alignment="Top" Height="56" Margin="16">
<Clicked>
<Toggle Target="swapStuff" />
</Clicked>
<Text Value="Swap Stuff" Color="#fff" Alignment="Center" />
<Rectangle Color="#18f" CornerRadius="2" />
</Panel>
<StackPanel Alignment="Center" ItemSpacing="8">
<BadgedRedWhiteButton ux:Name="firstBRWButton" ShowBadge="true" MakeRed="true" />
<BadgedRedWhiteButton ShowBadge="true" MakeRed="false" />
<BadgedRedWhiteButton ShowBadge="false" MakeRed="true" />
<BadgedRedWhiteButton ShowBadge="{hasUpdates}" MakeRed="{pageActive}" />
</StackPanel>
</App>
Go wild!