[OH3] Main UI - New „main_widget“ - development and testing [deprecated]

Take a look at:

Justin was as usual very helpful.

Maybe you can add your use case to the Git Issue to try get some traction?

From what I have seen the variable is not really set, just a default value used till it is set.

Nothing is set. The OR statement simply chooses the variable value if it exists, and if not, it chooses the secondary value you provide. There is no way to set a variable that is not one of the widget variable actions.

Nope. Assignment statements are just not supported by the expression parser.

That’s why I said you will have to make your expressions a little more complicated. You simply have to replace every instance of “vars.buttonIndex” with (vars.buttonIndex || 0). There are other expressions that will achieve the same thing, but this is the cleanest.

cc @Dimitris

Hi guys, I played a bit with the f7-swiper in combination with the oh-repeater and found a more dynamic solution, as I think.
Only prerequisit is to set a tag “Floor” to the floor group items and a tag with the floor group name to the rooms accordingly.

here is the code snippet:

uid: widget_DynamicNavbar
tags: []
props:
  parameters:
    - description: Dynamic NavBar V0.1
      required: false
  parameterGroups: []
timestamp: Sep 1, 2022, 3:43:39 PM
component: f7-card
config:
  expandable: false
  swipeToClose: true
  style:
    --f7-theme-color: var(--f7-text-color)
    background-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"
slots:
  default:
    - component: f7-card-content
      slots:
        default:
          - component: f7-block
            slots:
              default:
                - component: f7-swiper
                  config:
                    init: true
                    class:
                      - padding-top
                      - padding-bottom
                    params:
                      initialSlide: 0
                      observer: true
                      observeSlideChildren: true
                      updateOnWindowResize: true
                      mousewheel: true
                      keyboard: true
                      slidesPerView: 3
                    style:
                      --swiper-navigation-size: 20px
                      --swiper-navigation-color: gray
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          fetchMetadata: semantics,uiSemantics
                          for: i
                          fragment: true
                          itemTags: Floor
                          sourceType: itemsWithTags
                        slots:
                          default:
                            - component: f7-swiper-slide
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      text: =loop.i.label
                                      action: variable
                                      actionVariable: floor
                                      actionVariableValue: =loop.i.name
                                      style:
                                        --f7-button-bg-color: orange
                                        --f7-button-hover-bg-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"
                                        --f7-button-pressed-bg-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"
          - component: f7-block
            slots:
              default:
                - component: f7-swiper
                  config:
                    init: true
                    class:
                      - padding-top
                      - padding-bottom
                    params:
                      initialSlide: 0
                      observer: true
                      observeSlideChildren: true
                      updateOnWindowResize: true
                      mousewheel: true
                      keyboard: true
                      slidesPerView: 3
                    style:
                      --swiper-navigation-size: 20px
                      --swiper-navigation-color: gray
                  slots:
                    default:
                      - component: oh-repeater
                        config:
                          fetchMetadata: semantics, uiSemantics
                          for: i
                          fragment: true
                          itemTags: =vars.floor
                          sourceType: itemsWithTags
                        slots:
                          default:
                            - component: f7-swiper-slide
                              slots:
                                default:
                                  - component: oh-button
                                    config:
                                      text: =loop.i.label
                                      style:
                                        --f7-button-bg-color: orange
                                        --f7-button-hover-bg-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"
                                        --f7-button-pressed-bg-color: "=themeOptions.dark === 'light' ? 'white' : 'black'"

I have not added styles for selected buttons or any other fancy stuff, just wanted to show a poc…

Edit : If you want to have shorte Names for the buttons, you can use additional metadata (uiSemantics) and add a shortname…

1 Like

I hope that, in addition to having this published to the Marketplace, that some effort is being made to capture what has been learned in this thread to build a tutorial, augment the official docs, etc. There is a lot of great effort and new ground being broken here and I’d hate for it to remain hard to find.

6 Likes

@hmerk Merci Monsieur! Hope that @Nic0205 will find some time to investigate deeper.
I have strong inerest only for

Fancy stuff and me = :melting_face:

Thank you!

If I find some time, I will try to combine @Nic0205 s last approach with mine…

1 Like

Dear @rlkoshak ,
What we do obviously belongs to the community. I’m sure that @Nic0205 agree on that.
From my side, the final design with the graphical description of all the functions will be published here in the form of a manual: Many of them have already been posted and I’ll continue to post all their updates. Nic does the same with coding.

But I think that even as a plan or development we are looking for our steps and it is still early to “officially” post the project…

The structure we follow consists of two areas:


1. Navigation
NavBar (Header)
Tabs (footer)


2. Widgets

a. Lights
On-off Light
+Brightness
+Ambience
+Color
Mayby 4 Widgets: Will be under investigation if we can create a “smart” that will cover all cases:

b. Rollers
+Venetian Blinds

c. HVAC

d. Security

e. Weather

f. Scenes


On the design side, I dare say we are very close to the first version in both areas.

When Nic is finished, and if he agrees, I commit to create a combined guide (Programming + Design) and post it in the format you indicate.

I want to say here that the important thing is the work that Nic is doing -with the tremendous help and guidance of @JustinG @hmerk - and not mine, without wanting to downplay the design part.
Thank you for your post!

@JustinG
Hmm. I tried it - but with this:

  filter: (loop.HomeMenu_idx >= (vars.buttonIndex || 0)) && (loop.HomeMenu_idx <= (vars.buttonIndex || 0)+2 ) )

in my above posted code the filter does not work.
I thought with the filter like I described I would limit the HomeMenu to 3 (0,1,2) but all HomeMenu-Entries are shown.

if I replace it with a fix number:

  filter: (loop.HomeMenu_idx >= (vars.buttonIndex || 0)) && (loop.HomeMenu_idx <= 2 )

It filters correct. But not with the variable…

Very cool - it would be great to see things coming together!

1 Like

cc @rlkoshak

I totally agree with Dimitris!

As a noob in all these things I know now how hard it is to start - of course we and I will share the experience. I think we are part of the community !

1 Like

Already working on it :wink:

3 Likes

As promised, I tried to combine both approches to get it more dynamic.
Prerequisits:
My model is based on a floor/room/equipment structure. All floors groups (gAttic, gGroundFloor, gFirstFloor and gBasement) have a tag "Floor. Rooms within the floor (gAttic has Office (gOffice) and Guestroom (gGuest), have a tag with the floor groop (Office has tag gAttic).

Therefore, I removed the array configuration and hardcoded the top level menu array to Home, Floors and Rooms.

Here is the result:

uid: demo:responsive_navbar1
tags: []
props:
  parameterGroups: []
timestamp: Sep 2, 2022, 11:05:52 AM
component: f7-block
config:
  style:
    display: flex
    flex-direction: column
    height: calc(100vh - var(--f7-toolbar-height) - var(--f7-safe-area-bottom) - var(--f7-navbar-height) - var(--f7-safe-area-top))
    justify-content: space-between
    margin: 0
    padding: 0
    widht: 100vh
slots:
  default:
    - component: f7-block
      config:
        style:
          flex: 0 0 auto
          overflow: scroll
      slots:
        default:
          - component: f7-segmented
            config:
              style:
                flex: 1 1 auto
            slots:
              default:
                - component: oh-repeater
                  config:
                    fragment: true
                    for: baseMenu
                    sourceType: array
                    in:
                      - name: Home
                      - name: Floors
                      - name: Rooms
                    map: loop.baseMenu.name
                  slots:
                    default:
                      - component: oh-button
                        config:
                          action: variable
                          actionVariable: selectSection
                          actionVariableValue: ="SECTION" + loop.baseMenu_idx
                          large: true
                          style:
                            color: '=vars.selectSection=="SECTION" + loop.baseMenu_idx ? "black" : "#8C8C8C"'
                            font-size: 30px
                            font-weight: 200
                            text-decoration: underline
                            text-decoration-color: '=vars.selectSection=="SECTION" + loop.baseMenu_idx ? "#F8BB00" : "transparent"'
                            text-underline-offset: 4px
                          text: =loop.baseMenu
          - component: f7-segmented
            config:
              visible: =!!(vars.selectSection == "SECTION0")
            slots:
              default:
                - component: oh-button
                  config:
                    text: <
                    style:
                      width: 1vh
                      color: "#F8BB00"
                - component: oh-repeater
                  config:
                    fragment: true
                    for: HomeMenu
                    sourceType: array
                    in: =props.hArray
                    filter: (loop.HomeMenu_idx >= 0) && (loop.HomeMenu_idx <= (0 +5))
                  slots:
                    default:
                      - component: oh-button
                        config:
                          action: variable
                          actionVariable: selectDivision
                          actionVariableValue: ="DIV" + loop.HomeMenu_idx
                          large: true
                          style:
                            color: '=vars.selectDivision=="DIV" + loop.HomeMenu_idx ? "black" : "#8C8C8C"'
                            text-decoration: underline
                            text-decoration-color: '=vars.selectDivision=="DIV" + loop.HomeMenu_idx ? "#F8BB00" : "transparent"'
                            text-underline-offset: 4px
                          text: =loop.HomeMenu
                - component: oh-button
                  config:
                    text: ">"
                    style:
                      width: 1vh
                      color: "#F8BB00"
          - component: f7-segmented
            config:
              visible: =!!(vars.selectSection == "SECTION1")
            slots:
              default:
                - component: oh-repeater
                  config:
                    fetchMetadata: semantics,uiSemantics
                    fragment: true
                    for: FloorMenu
                    itemTags: Floor
                    sourceType: itemsWithTags
                  slots:
                    default:
                      - component: oh-button
                        config:
                          action: variable
                          actionVariable: floor
                          actionVariableValue: =loop.FloorMenu.name
                          large: true
                          style:
                            color: '=vars.floor ==loop.FloorMenu.name ? "black" : "#8C8C8C"'
                            text-decoration: underline
                            text-decoration-color: '=vars.floor ==loop.FloorMenu.name ? "#F8BB00" : "transparent"'
                            text-underline-offset: 4px
                          text: =loop.FloorMenu.label
          - component: f7-segmented
            config:
              visible: =!!(vars.selectSection == "SECTION2")
            slots:
              default:
                - component: oh-repeater
                  config:
                    fetchMetadata: semantics, uiSemantics
                    fragment: true
                    for: RoomMenu
                    itemTags: =vars.floor
                    sourceType: itemsWithTags
                  slots:
                    default:
                      - component: oh-button
                        config:
                          action: variable
                          actionVariable: selectDivision
                          actionVariableValue: ="DIV" + loop.RoomMenu_idx
                          large: true
                          style:
                            color: '=vars.selectDivision=="DIV" + loop.RoomMenu_idx ? "black" : "#8C8C8C"'
                            text-decoration: underline
                            text-decoration-color: '=vars.selectDivision=="DIV" + loop.RoomMenu_idx ? "#F8BB00" : "transparent"'
                            text-underline-offset: 4px
                          text: =loop.RoomMenu.label
    - component: f7-block
      config:
        style:
          flex: 1 1 auto
          overflow: scroll
      slots:
        default:
          - component: f7-card
            config:
              content: With some stuff
              title: The middle content
          - component: widget:Temp_Control
            config:
              style:
                flex: 1 1 auto
                overflow-y: auto
                position: relative
              visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Climate")
              widgettrend: HeizungWohnzimmer_Temperature
          - component: widget:Temp_Control
            config:
              style:
                flex: 1 1 auto
                overflow-y: auto
                position: relative
              visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Climate")
              widgettrend: HeizungWohnzimmer_Temperature
          - component: widget:Temp_Control
            config:
              style:
                flex: 1 1 auto
                overflow-y: auto
                position: relative
              visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Climate")
              widgettrend: HeizungWohnzimmer_Temperature
          - component: widget:Temp_Control
            config:
              style:
                flex: 1 1 auto
                overflow-y: auto
                position: relative
              visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Climate")
              widgettrend: HeizungWohnzimmer_Temperature
          - component: widget:Temp_Control
            config:
              style:
                flex: 1 1 auto
                overflow-y: auto
                position: relative
              visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Climate")
              widgettrend: HeizungWohnzimmer_Temperature
          - component: oh-cell
            config:
              icon: f7:lightbulb
              style:
                flex: 1 1 auto
                overflow-y: auto
                position: relative
              subtitle: only for testing
              title: I am a light card in the Bedroom
              visible: =!!(vars.selectSection + vars.selectDivision + vars.selectThing == "SECTION2DIV2Lights")
          - component: oh-cell
            config:
              icon: f7:lightbulb
              style:
                flex: 1 1 auto
                overflow-y: auto
                position: relative
              subtitle: only for testing
              title: I am a light card in the Home
              visible: =!!(vars.selectSection == "SECTION1")
          - component: Label
            config:
              style:
                flex: 1 1 auto
                overflow-y: auto
                position: relative
              text: =vars.selectSection + vars.selectDivision
          - component: Label
            config:
              style:
                flex: 1 1 auto
                overflow-y: auto
                position: relative
              text: =vars.SecDiv
    - component: f7-block
      config:
        style:
          flex: 0 0 auto
          overflow: scroll
      slots:
        default:
          - component: f7-segmented
            config:
              class:
                - segmented-strong
              style:
                --f7-segmented-strong-between-buttons: 0px
                --f7-segmented-strong-bg-color: transparent
                --f7-segmented-strong-button-font-weight: 300
                --f7-segmented-strong-button-hover-bg-color: rgba(255, 255, 255, 0.15)
                --f7-segmented-strong-padding: 0px
            slots:
              default:
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: selectThing
                    actionVariableValue: Lights
                    class:
                      - padding-top-half
                      - display-flex
                      - flex-direction-column
                    fill: '=vars.selectThing=="Lights" ? true : false'
                    icon-f7: lightbulb
                    iconColor: black
                    iconSize: 20
                    style:
                      --f7-button-bg-color: '=vars.selectThing=="Lights" ? "#F8BB00" : "transparent"'
                      --f7-button-border-radius: 15px
                      --f7-button-hover-bg-color: '=vars.selectThing=="Lights" ? "F8BB00" : "transparent"'
                      --f7-button-padding-horizontal: 0px
                      --f7-button-padding-vertical: 0px
                      --f7-button-text-color: '=vars.selectThing=="Lights" ? "#6A6A6A" : "#8C8C8C"'
                      font-size: 12px
                      height: auto
                    text: Lights
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: selectThing
                    actionVariableValue: Climate
                    class:
                      - padding-top-half
                      - display-flex
                      - flex-direction-column
                    fill: '=vars.selectThing=="Climate" ? true : false'
                    icon-f7: snow
                    iconColor: black
                    iconSize: 20
                    style:
                      --f7-button-bg-color: '=vars.selectThing=="Climate" ? "#F8BB00" : "transparent"'
                      --f7-button-border-radius: 15px
                      --f7-button-hover-bg-color: '=vars.selectThing=="Climate" ? "F8BB00" : "transparent"'
                      --f7-button-padding-horizontal: 0px
                      --f7-button-padding-vertical: 0px
                      --f7-button-text-color: '=vars.selectThing=="Climate" ? "#6A6A6A" : "#8C8C8C"'
                      font-size: 12px
                      height: auto
                    text: Climate
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: selectThing
                    actionVariableValue: Rollers
                    class:
                      - padding-top-half
                      - display-flex
                      - flex-direction-column
                    fill: '=vars.selectThing=="Rollers" ? true : false'
                    icon-f7: archivebox
                    iconColor: black
                    iconSize: 20
                    style:
                      --f7-button-bg-color: '=vars.selectThing=="Rollers" ? "#F8BB00" : "transparent"'
                      --f7-button-border-radius: 15px
                      --f7-button-hover-bg-color: '=vars.selectThing=="Rollers" ? "F8BB00" : "transparent"'
                      --f7-button-padding-horizontal: 0px
                      --f7-button-padding-vertical: 0px
                      --f7-button-text-color: '=vars.selectThing=="Rollers" ? "#6A6A6A" : "#8C8C8C"'
                      font-size: 12px
                      height: auto
                    text: Rollers
                - component: oh-button
                  config:
                    action: variable
                    actionVariable: selectThing
                    actionVariableValue: Security
                    class:
                      - padding-top-half
                      - display-flex
                      - flex-direction-column
                    fill: '=vars.selectThing=="Security" ? true : false'
                    icon-f7: camera
                    iconColor: black
                    iconSize: 20
                    style:
                      --f7-button-bg-color: '=vars.selectThing=="Security" ? "#F8BB00" : "transparent"'
                      --f7-button-border-radius: 15px
                      --f7-button-hover-bg-color: '=vars.selectThing=="Security" ? "F8BB00" : "transparent"'
                      --f7-button-padding-horizontal: 0px
                      --f7-button-padding-vertical: 0px
                      --f7-button-text-color: '=vars.selectThing=="Security" ? "#6A6A6A" : "#8C8C8C"'
                      font-size: 12px
                      height: auto
                    text: Security




And here is a little screencast :

2 Likes

Wow. This is on a other level. Congrats to Nic to have achieved this challenge.
Great help also from other guys involved in this!

1 Like

Wow - looks cool and makes the code much “cleaner”.

But to be sure - the posted code is without the swiper approach.

@All: Should we integrate the swiper or go further with this great state after solving the “variable Index” challenge?

@Hmerk: I agree with Ruben! That’s really the next level!

No, I did not clean that much in the code, just a few lines. But removed the array configs.

No, still the segmented approach. But we can try this with the swiper approach as well. Benefit would be that it could handle long names better, as I was wrong, uiSemantics can not be set on group items, so no easy way to get short names lige EG, FF, SF and so on…

Thanks, glad I can help :wink:

on my device (iphone x) when i click floors or rooms, sub menu is not shown.
for floors i only have “scale” sub menu.
i think this is normal in this version, but i would like just to report in case is not known …

Did you add the tags as decribed to your floor / room groups ? If not, the code does not work…

yes, but sure i’m missing something.

Taverna (gTaverna) is member of gCasa.
Taverna is set as Floor as Semantic Class.
Taverna is shown as Floor in widget.

Taverna has 2 memebers: Bagno Taverna (gBagnoTaverna) and Tunnel Taverna (gTunnelTaverna).
Both defined as Room as Semantic Class.
Both not shown in widget.

what’s missing?

You need to add a tag “gTaverna” to Bagno Taverna and Tunnel Taverna.

I failed :cry: