phronmophobic / membrane

A Simple UI Library That Runs Anywhere
Apache License 2.0
564 stars 19 forks source link

Non-Ubuntu Linux usage #2

Open refset opened 4 years ago

refset commented 4 years ago

I was initially unable to get anything running due to the Ubuntu-specific font usage here: https://github.com/phronmophobic/membrane/blob/266ad8542805bb2f941976a1a7f706218df97687/src/membrane/ui.cljc#L18

As an Arch user I got things working like so:

# Download & extract https://assets.ubuntu.com/v1/0cef8205-ubuntu-font-family-0.83.zip linked from https://design.ubuntu.com/font/
mkdir -p /usr/share/fonts/truetype/ubuntu/
sudo cp Downloads/ubuntu-font-family-0.83/ubuntu-font-family-0.83/Ubuntu-R.ttf /usr/share/fonts/truetype/ubuntu/
sudo chown <user> /usr/share/fonts/truetype/ubuntu/Ubuntu-R.ttf

I don't have an opinion on a real solution but I wanted to file my workaround somewhere :)

Thank you for this really interesting project!

UPDATE: personal experience report

I have battled away trying to create a full-window background color with centered elements but the centering seemed problematic. Perhaps there's an obvious user error:

    (defn center [elem [width height]]
      (let [[ewidth eheight] (ui/bounds elem)]
        (ui/translate (int (- (/ width 2)
                              (/ ewidth 2)))
                      (int (- (/ height 2)
                              (/ eheight 2)))
                   elem)))
    (defn counter [num]
      (let [window (skia/get-framebuffer-size (:window skia/*window*))
            [window-x window-y] window]
        (ui/on :mouse-down (fn [[mouse-x mouse-y]]
                             (swap! counter-state inc)
                             nil)
               [(ui/with-color
                  [0 0 0]
                  (apply ui/rectangle window))
                (center
                 (ui/with-color
                   [1 1 1]
                   (ui/horizontal-layout
                    (ui/button (str "more!" num))
                    (ui/spacer 5 0)
                    (ui/label num (ui/font nil 19))))
                 window)])))

In any case, I had experienced the REPL dying every so often due to ~user error (which is inconvenient but tolerable) but unfortunately my latest experience resulted in a core dump of the underlying Chromium process and completely locked up my machine...so I will park this exploration for the time being, but it was a fun ride!

phronmophobic commented 4 years ago

Hey, thanks for giving membrane a shot!

Using a hardcoded path that's only valid on Ubuntu is definitely an issue. Making the default font configurable has been on my todo list for a while. The underlying graphics library (skia) also has their own implementation for loading a default system font which I should probably use rather than a hardcoded path.

Regarding your example, I was able to get it to work using following code:

(defn center [elem [width height]]
  (let [[ewidth eheight] (ui/bounds elem)]
    (ui/translate (int (- (/ width 2)
                          (/ ewidth 2)))
                  (int (- (/ height 2)
                          (/ eheight 2)))
                  elem)))

(def counter-state (atom 0))
(def window-size (atom [400 400]))
(defn -reshape [window window-handle width height]
  (try
    (let [[xscale yscale :as content-scale] (skia/get-window-content-scale-size window-handle)
          width (/ width xscale)
          height (/ height yscale)]
      (reset! window-size [width height]))
    (catch Exception e
      (println e))
    (finally
      (skia/-reshape window window-handle width height))))

(defn counter [[window-width window-height :as window-size] num]
  (ui/on :mouse-down (fn [[mouse-x mouse-y]]
                       (swap! counter-state inc)
                       nil)
         [(ui/with-color
            [0 0 0]
            (apply ui/rectangle window-size))
          (center
           (ui/with-color
             [1 1 1]
             (ui/horizontal-layout
              (ui/button (str "more!" num))
              (ui/spacer 5 0)
              (ui/label num (ui/font nil 19))))
           window-size)]))

(comment
  ;; run use the following
  (let [[window-width window-height] @window-size]
    (skia/run #(counter @window-size @counter-state)
      {:handlers {:reshape -reshape}
       :window-start-width window-width
       :window-start-height window-height})))

Getting the size of the top level container is something that should be much easier than it currently is.

In any case, I had experienced the REPL dying every so often due to ~user error (which is inconvenient but tolerable) but unfortunately my latest experience resulted in a core dump of the underlying Chromium process and completely locked up my machine...so I will park this exploration for the time being, but it was a fun ride!

Crashing the repl is certainly not user error! It's either a bug, documentation error, or an interface that needs improvement.

The framebuffer size probably generally isn't what you want since it will give the wrong results on displays that don't have a content-scale of 1 (ie. High DPI displays). The skia namespace has a lot of c interop code that is difficult to get right and isn't always thread safe.

The only functions in skia that are meant to be used by library users are membrane.skia/run, membrane.skia/run-sync, and membrane.skia/draw-to-image!. This should be better documented and I hope this didn't slow you down too much.

Hopefully, sticking to those functions should avoid hard crashes of the repl. If not, please let me know.

Thanks again for checking out membrane and taking the time to make an issue! Please don't hesitate to make any issues in future. I'm also available on the clojurians slack in the #membrane channel if you need any help.

phronmophobic commented 4 years ago

I've marked most membrane.skia/* functions as private to avoid tempting people to call them and inadvertently crash their jvm: https://github.com/phronmophobic/membrane/commit/09dcb4f3bfa7c96160cbbfeb44d7f01fd8914bd6

phronmophobic commented 4 years ago

I've also changed how the default system font is loaded so that membrane can work out of the box on non ubuntu linux: https://github.com/phronmophobic/membrane/commit/6a28fd9c9f395a1d78382e42867ddeec397cad4b . Still needs to be tested before releasing.