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

Warm Welcome!

… and it goes on…

One challenge managed - the next occurs.

@JustinG Do you have a hint for me how I could achieve the navbar “shrinking” like this?
image

… I think simplest way would be to use https://v5.framework7.io/docs/toolbar-tabbar#hide-on-scroll but it seems not to render the tabbar… Is there a clue?

It really depends on what method you wind up using for the “navbar”. For instance, if you’re using the segmental buttons approach or even just an array of buttons without the segmental structure, I could see a couple of likely options. The first would be to just use a widget variable to determine what the starting button button to display is and a repeater to show only that and the next two buttons. The major advantage to this approach would be that the < and > buttons would be easy because they would simply adjust the starting button variable.

Alternatively, a much more advanced method might be, to put the navbar in it’s own block, set that block overflow to hidden and then use the < and > to set some scrolling of the block. This would be significantly more complicated (including working some javascript into the widget) but likely much prettier and actually allow the buttons to scroll instead of just being rendered in place with each change.

:wave: @JustinG @hmerk @rubenfuser @Nic0205

Hey friends.
Again, I’m not a developer, so excuse any possible wrong thinking.
I want to restore one more time the idea to create a new type of page, based on OH tabbed page, but with more options. Why? Because OH have it all in that page: Navbar - Widgets area - tab bar, scrolling animations etc.
That we have is to -hardly- modify is the existing Nav bar: I mean the mechanism is there, it works perfectly and the end user will be modify the page following OH’s well-structured way.
Can you please find some time to review attached draft?
My question is why this approach is wrong -or why the approach we are following now is better? In my perspective, we have choose a way that consumes time, resources and new knowledge while it’s hard configured both for developer and end users.
I’m remaining extremely open to any feedback!
Thanks.
PS. JustinG informed that there is a process i think called “pull request” in order to create a new page like the above mentioned. Does any one know how this process works?

Create tabbed page with menuv1.pdf (658.2 KB)

  1. Create a GitHub account
  2. File an issue on the openhab-webuis repo explaining what you are doing (see How to file an Issue)
  3. After some discussion, hopefully with the maintainer(s) and concurrence with your approach fork the repo.
  4. In your fork of the repo, create a branch for your change, implement the changes to the code necessary and commit the changes.
  5. Submit a PR containing the changes.
  6. Wait for a review from the maintainer(s) and address any concerns they have with the code.
  7. Once the maintainer(s) are satisfied they will merge the change into baseline.

That’s a high level description of the process. If you are not a developer, you can take this to step 2 and parts of step 3. But you then will have to wait and see when/if someone volunteers to do steps 3-7. That’s often where things fall down. Good ideas are not worth much without someone volunteering to do the work to implement them.

I would say it’s not wrong or better but the approach being followed now is possible using the skills and interests of the people on this thread. I don’t know that many, if any, have the skills and interest in volunteering to pursue implementing this as part of the UI itself. It’s a somewhat different skill set to implement code that creates the code necessary to create a new type of page compared to what is being done here which is using the framework that already exists which is more configuration than coding new (that is not to diminish the work that is being done here which is impressive).

4 Likes

Just to add a little to what Rich said: ‘better’ can mean lots of things.

In this case, I would agree, that contributing code to the UI to create a new page type would be “better” for the end user. However, that is a much more coding intensive process. To do it this way you would have to know Vue (the language that builds the pages) and Javascript (the language that gives the pages much of their specific functonality), plus you would have to fully understand the OH restAPI (the link between OH core and MainUI), the current structure of the MainUI, and a smattering of other things besides (git, oh contribution guidelines, f7 framework, css, your IDE of choice, etc.). I’m sure you’re capable of this, but it would be a much longer road and doesn’t really fit with your initial requirement of being as low-coding as possible.

The process you are currently looking at it a “better” fit for those of you working on the project. You need to only really understand the widget/yaml system and some css.

Note that when I outlined some options for you, I did not suggest creating the entire thing in one widget. This is a good exercise for learning the pieces that you need, but not, I suspect, the best final form for your project. In the end, my guess (and it is only a guess) is that you will want separate widgets for many of the pieces: a top-bar widget, a bottom-bar widget, and a few different page widgets or some breakdown like that. Then you will want to provide some template(s) for how users should combine those on an oh-layout page to create the overall effect of the UI.

2 Likes

How to change CSS class st0 fill property to change colored icon so that this icon shows different colors for different color themes? I’ve added f7 vars to icon’s css, but that didn’t the trick:

style type="text/css">
	.st0{fill=(--var-f7-text-color);stroke=(--var-f7-bars-bg-color);stroke-width:4;stroke-miterlimit:10;}
	.st1{fill:#D42416;}
	.st2{fill:#23C703;}
	.st3{fill:#039BE5;}
	.st4{fill=(--var-f7-bars-bg-color);}
</style>
<g>
	<path class="st0" d="M115.6,230.9c-62.9,0-114-51.2-114-114.1s51.2-114,114-114s114,51.2,114,114S178.5,230.9,115.6,230.9z
		 M115.6,24.7c-50.8,0-92.1,41.3-92.1,92.1s41.3,92.1,92.1,92.1s92.1-41.3,92.1-92.1S166.4,24.7,115.6,24.7z"/>
</g>

Variables in css need to be called with the var() function.

https://www.w3schools.com/cssref/func_var.asp

1 Like

Still that doesn’t work. Element inspection shows correct classes, but they aren’t receiving values (variables greyed out).

Sorry, I just quickly cut and paste your original code into my reply. If you just put var(...) around your original variables, they are still not correct. The f7 variables to not start with the additional var so the properly formed value would be:

fill=(--f7-text-color)

Yes, i did exactly that, and icons seem to not to receive --f7-text-color value.

D’oh! How about fill: var(... instead of fill=var(.... Not sure how I missed that the first time (or first 3 times…).

fill:var(--f7-text-color)

Seems to be correct syntax, but the icon is not receiving values.

The var function can also take a second value which acts as a fallback value in case the variable cannot be found. Try adding some very distinct fallback color, something like:

fill:var(--f7-text-color, #00FFFF);

That will at least tell you if the fill property is being overridden by a different value (which is unlikely) or if the svg just isn’t is the right scope for the f7 variable.

This way icon becomes #00FFFF, not black or white.

Hu Dimitris,
Really nice design. I tried something similar with my limited design and coding skills. But I didn’t get such nice results lile you here in the team of course.
The color schema is nice, too. But maybe you can deliver different sets of color schema :slight_smile: maybe something with blue or green :slight_smile:

1 Like

Thank Jan. Good point - I have spend some time with this in the past.
Here you are:

HOMEUIv2.pdf (201.9 KB)

Themes that includes color schemes is something that I’m thinking of since when Nic and me started this project. For now, we have to deal with the top navbar… One piece at a time!
PS. Will be very happy if you join the Team, no matter what you are capable of :wink:

Well, that’s at least proof positive that the styling format is now correct and being applied. Unfortunately, that means that the problem is that the css variables are not being passed to the svg. As far as I know, really this must mean that when the svg is loaded as a resource (instead of being included inline in the code), it is outside the DOM.

I don’t know, off the top of my head, if there’s a way to deal with that. I’ll have to think about it for a while.

1 Like

i was waiting for the new topic to post widgets based on @Dimitris style, but i’ll post them here.
90% are complete, i’m not a skilled programmer, so i ask to who believe in this project to take these widgets and improve and complete them. please forgive me if in the code there are big mistakes or stupid things, i would like to learn from anyone has better knowns.

image

here is the security widget:

uid: test:Security_V3
tags:
  - MadeByEvil
props:
  parameters:
    - label: Icona
      name: Icon
      required: false
      type: TEXT
    - label: Titolo della card
      name: title
      required: false
      type: TEXT
    - default: Item 1
      label: Item 1 Label
      name: label1
      required: false
      type: TEXT
    - context: item
      label: Item 1
      name: item1
      required: false
      type: TEXT
    - label: Item 2 Label
      name: label2
      required: false
      type: TEXT
    - context: item
      label: Item 2
      name: item2
      required: false
      type: TEXT
    - label: Item 3 Label
      name: label3
      required: false
      type: TEXT
    - context: item
      label: Item 3
      name: item3
      required: false
      type: TEXT
    - label: Item 4 Label
      name: label4
      required: false
      type: TEXT
    - context: item
      label: Item 4
      name: item4
      required: false
      type: TEXT
    - label: Item 5 Label
      name: label5
      required: false
      type: TEXT
    - context: item
      label: Item 5
      name: item5
      required: false
      type: TEXT
  parameterGroups:
    - name: widgetAction
      context: action
      label: Action
      description: Action to perform when the element is clicked
timestamp: Aug 25, 2022, 6:46:53 PM
component: f7-card
config:
  style:
    border-radius: 10px
    height: 320px
    min-height: 320px
slots:
  content:
    - component: oh-icon
      config:
        icon: iconify:bi:shield-check
        color: green
        height: 20px
        style:
          position: absolute
    - component: Label
      config:
        text: Contacts & Alarm
        top: 13px
        style:
          position: absolute
          left: 35%
          font-weight: 500
    - component: oh-icon
      config:
        icon: '=items[props.item1].state == "ON" ? "iconify:akar-icons:square-fill" : "iconify:akar-icons:square"'
        color: green
        height: 10px
        style:
          position: absolute
          top: 40px
          left: 95px
    - component: oh-icon
      config:
        icon: '=items[props.item2].state == "ON" ? "iconify:akar-icons:square-fill" : "iconify:akar-icons:square"'
        color: green
        height: 10px
        style:
          position: absolute
          top: 40px
          left: 115px
    - component: oh-icon
      config:
        icon: '=items[props.item3].state == "ON" ? "iconify:akar-icons:square-fill" : "iconify:akar-icons:square"'
        color: green
        height: 10px
        style:
          position: absolute
          top: 40px
          left: 135px
    - component: oh-icon
      config:
        icon: '=items[props.item4].state == "ON" ? "iconify:akar-icons:square-fill" : "iconify:akar-icons:square"'
        color: green
        height: 10px
        style:
          position: absolute
          top: 40px
          left: 155px
    - component: oh-icon
      config:
        icon: '=items[props.item5].state == "ON" ? "iconify:akar-icons:square-fill" : "iconify:akar-icons:square"'
        color: green
        height: 10px
        style:
          position: absolute
          top: 40px
          left: 175px
    - component: oh-icon
      config:
        icon: '=items[props.item6].state == "ON" ? "iconify:akar-icons:square-fill" : "iconify:akar-icons:square"'
        color: green
        height: 10px
        style:
          position: absolute
          top: 40px
          left: 195px
    - component: oh-icon
      config:
        icon: '=items[props.item7].state == "ON" ? "iconify:akar-icons:square-fill" : "iconify:akar-icons:square"'
        color: green
        height: 10px
        style:
          position: absolute
          top: 40px
          left: 215px
    - component: oh-icon
      config:
        icon: '=items[props.item8].state == "ON" ? "iconify:akar-icons:square-fill" : "iconify:akar-icons:square"'
        color: green
        height: 10px
        style:
          position: absolute
          top: 40px
          left: 235px
    - component: oh-icon
      config:
        icon: iconify:bi:shield-check
        color: '=items[props.item5].state == "ON" ? "green" : items[props.item4].state == "ON" ? "green" : items[props.item3].state == "ON" ? "green" : items[props.item2].state == "ON" ? "green" : items[props.item1].state == "ON" ? "green" : "grey"'
        height: 50px
        style:
          position: absolute
          top: 70px
          left: 4%
    - component: Label
      config:
        text: Stay
        style:
          position: absolute
          top: 125px
          left: 7%
          font-weight: 500
    - component: oh-icon
      config:
        icon: iconify:bi:shield-check
        color: grey
        height: 50px
        style:
          position: absolute
          top: 70px
          left: 43%
    - component: Label
      config:
        text: Off
        style:
          position: absolute
          top: 125px
          left: 48%
          font-weight: 500
    - component: oh-icon
      config:
        icon: iconify:bi:shield-check
        color: '=items[props.item5].state == "OFF" && items[props.item4].state == "OFF" && items[props.item3].state == "OFF" && items[props.item2].state == "OFF" && items[props.item1].state == "OFF" ? "red" : "grey"'
        height: 50px
        style:
          position: absolute
          top: 70px
          left: 81%
    - component: Label
      config:
        text: Arm
        style:
          position: absolute
          top: 125px
          left: 85%
          font-weight: 500
    - component: Label
      config:
        text: =props.label1
        style:
          position: absolute
          top: 180px
          left: 6%
    - component: oh-toggle
      config:
        item: =props.item1
        color: green
        style:
          --f7-toggle-height: 20px
          --f7-toggle-width: 40px
          font-size: 100%
          top: 160px
          left: 250px
    - component: Label
      config:
        visible: '=props.item2 ? "true" : "false"'
        text: =props.label2
        style:
          position: absolute
          top: 205px
          left: 6%
    - component: oh-toggle
      config:
        visible: '=props.item2 ? "true" : "false"'
        item: =props.item2
        color: green
        style:
          --f7-toggle-height: 20px
          --f7-toggle-width: 40px
          top: 185px
          left: 210px
    - component: Label
      config:
        visible: '=props.item3 ? "true" : "false"'
        text: =props.label3
        style:
          position: absolute
          top: 230px
          left: 6%
    - component: oh-toggle
      config:
        visible: '=props.item3 ? "true" : "false"'
        item: =props.item3
        color: green
        style:
          --f7-toggle-height: 20px
          --f7-toggle-width: 40px
          top: 210px
          left: 170px
    - component: Label
      config:
        visible: '=props.item4 ? "true" : "false"'
        text: =props.label4
        style:
          position: absolute
          top: 255px
          left: 6%
    - component: oh-toggle
      config:
        visible: '=props.item4 ? "true" : "false"'
        item: =props.item4
        color: green
        style:
          --f7-toggle-height: 20px
          --f7-toggle-width: 40px
          top: 235px
          left: 130px
    - component: Label
      config:
        visible: '=props.item5 ? "true" : "false"'
        text: =props.label5
        style:
          position: absolute
          top: 280px
          left: 6%
    - component: oh-toggle
      config:
        visible: '=props.item5 ? "true" : "false"'
        item: =props.item5
        color: green
        style:
          --f7-toggle-height: 20px
          --f7-toggle-width: 40px
          top: 260px
          left: 90px
  footer:
    - component: f7-block
      config:
        style:
          top: 125px
          left: 0
          position: absolute

image

and here the rollershutter widget:

uid: Rollershutter Preset
tags:
  - New UI
props:
  parameters:
    - description: Title of the card
      label: Title
      name: Title
      required: false
      type: TEXT
    - context: item
      description: Das Item mit dem die Solltemperatur eingestellt wird
      label: Rollershutter Item
      name: RollerItem
      required: true
      type: TEXT
timestamp: Aug 22, 2022, 11:41:00 PM
component: f7-card
config:
  noShadow: false
  padding: false
  style:
    padding: 0px
    border-radius: 10px
    box-shadow: 5px 5px 15px 1px rgba(0,0,0,0.05)
    --f7-card-header-border-color: transparent
    min-width: 90%
slots:
  default:
    - component: f7-card-header
      config:
        style:
          --f7-card-header-border-color: none
      slots:
        default:
          - component: oh-icon
            config:
              icon: iconify:mdi:window-shutter-alert
              height: 30px
              style:
                margin-top: 3%
                margin-bottom: 3%
    - component: Label
      config:
        text: =props.Title
        style:
          position: absolute
          top: 8%
          left: 17%
    - component: Label
      config:
        text: =items[props.RollerItem].state + "% " + " close"
        style:
          position: absolute
          top: 30%
          left: 17%
          background: gray
          border-radius: 9px
    - component: oh-button
      config:
        iconColor: teal
        iconF7: arrow_up_circle
        iconSize: 30
        action: command
        actionItem: =props.RollerItem
        actionCommand: UP
        style:
          position: absolute
          top: 15%
          right: 20%
          height: 33px
          background: transparent
          z-index: 98
    - component: oh-button
      config:
        iconColor: gray
        iconF7: stop_circle
        iconSize: 30
        action: command
        actionItem: =props.RollerItem
        actionCommand: STOP
        style:
          position: absolute
          top: 15%
          right: 10%
          height: 33px
          background: transparent
          z-index: 98
    - component: oh-button
      config:
        iconColor: teal
        iconF7: arrow_down_circle
        iconSize: 30
        action: command
        actionItem: =props.RollerItem
        actionCommand: DOWN
        style:
          position: absolute
          top: 15%
          right: 0%
          height: 33px
          background: transparent
          z-index: 98
    - component: f7-card-footer
      config:
        style:
          height: 60px
          background: "#B1ACA2"
          border-radius: 0 0 10px 10px
      slots:
        default:
          - component: Label
            config:
              text: "Preset positions:"
              style:
                position: absolute
                top: 5%
                color: white
    - component: oh-button
      config:
        round: true
        text: "0"
        action: command
        actionItem: =(props.RollerItem)
        actionCommand: UP
        class:
          - margin
          - display-flex
          - flex-direction-column
        style:
          position: absolute
          height: 24px
          width: 10px
          top: 63%
          left: 20%
          z-index: 98
          background: '=items[props.RollerItem].state == "0" ? "teal" : "gray"'
          color: white
    - component: oh-button
      config:
        round: true
        text: 50
        action: command
        actionItem: =(props.RollerItem)
        actionCommand: 50
        class:
          - margin
          - display-flex
          - flex-direction-column
        style:
          position: absolute
          height: 24px
          width: 10px
          top: 63%
          left: 33%
          z-index: 98
          background: '=items[props.RollerItem].state == "50" ? "teal" : "gray"'
          color: white
    - component: oh-button
      config:
        round: true
        text: 75
        action: command
        actionItem: =(props.RollerItem)
        actionCommand: 75
        class:
          - margin
          - display-flex
          - flex-direction-column
        style:
          position: absolute
          height: 24px
          width: 10px
          top: 63%
          right: 33%
          z-index: 98
          background: '=items[props.RollerItem].state == "75" ? "teal" : "gray"'
          color: white
    - component: oh-button
      config:
        round: true
        text: 100
        action: command
        actionItem: =(props.RollerItem)
        actionCommand: DOWN
        class:
          - margin
          - display-flex
          - flex-direction-column
        style:
          position: absolute
          height: 24px
          width: 10px
          top: 63%
          right: 20%
          z-index: 98
          background: '=items[props.RollerItem].state == "100" ? "teal" : "gray"'
          color: white

both are missing the function “expandable” and the “hours bars” details of when the item have been modified.
width and weight are perfect for iphone layout.
hope someone can help me/us adding functions and better screen adapt.

bye!

1 Like