elkowar / eww

ElKowars wacky widgets
https://elkowar.github.io/eww
MIT License
9.38k stars 382 forks source link

[FEATURE] loops in overlays #539

Open DavidLyhedDanielsson opened 2 years ago

DavidLyhedDanielsson commented 2 years ago

Description of the requested feature

I'd like this defwidget to work:

(defvar hicores "[0]")

(defwidget coreusage []
  (box
    :width 140
    (overlay
      (for entry in hicores
        (circular-progress
          :value {EWW_CPU.cores[entry].usage / 100.0 * 16.0}
          :start-at {100.0 / 6.0 * entry}
          :thickness 5
          :clockwise true
        )
      )
    )
  )
)

But it gives me this error:

error: This widget can only be used as a child of some container widget such as box
   ┌─ /home/david/.config/eww/eww.yuck:23:7
   │  
23 │ ╭       (for entry in hicores
24 │ │         (circular-progress
25 │ │           :value {EWW_CPU.cores[entry].usage / 100.0 * 16.0}
26 │ │           :start-at {100.0 / 6.0 * entry}
   · │
29 │ │         )
30 │ │       )
   │ ╰───────^
   │  
   → Hint: try wrapping this in a `box`

If I manually write out the circular-progress widgets it works fine

Proposed configuration syntax

No response

Additional context

No response

viandoxdev commented 2 years ago

The current codebase doesn't really allow for that at the moment, the overlay widget is not a GtkContainer (can contain any number of children), but a GtkBin (only one children) that has a special method to add overlayed widgets. The way this is implemented in eww means that the overlay widget needs to know its children while building. But eww handles special widgets differently: The parent is built first and then given children through GtkContainer.add. My guess is that we would need either a workaround for overlay widget (pretty easy but kinda ugly, I could implement that), or a refractor to allow widget to have custom children logic (cleaner, but would only be used by 1 or 2 widget, i.e overlay and centerbox, not worth it imo).

Otherwise maybe a different syntax for overlay altogether could be an option, I remember @elkowar not being satisfied with the current api.

DavidLyhedDanielsson commented 2 years ago

Thanks for the very detailed response! I had a look at the code but I am not familiar enough with GTK to fix it myself. I think I also spotted the workaround you're mentioning, but didn't want to put time and effort into a PR before hearing more.

At least I can reduce some code duplication with a parameterizeddefwidget:

(defwidget coreusage []
  (box
    :width 140
    (overlay
      (core :entry 0)
      (core :entry 1)
      ...
    )
  )
)