Best approach to nested visuals using whiletrue or match case

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"/>

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. :smiley:

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>

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!