Put the top bar back to words
The icon run in the top bar read worse than what it replaced. Restore the earlier top bar — pane words, new, open ▾, undo ▾ redo, the edit menu, snapshots ▾, title, status, export… — and its CSS. The stage bar's overlay switches, the palette chooser and `menu/popover` stay. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
f238ff4f62
commit
208dddee07
7 changed files with 168 additions and 207 deletions
|
|
@ -121,26 +121,21 @@
|
||||||
:on-pointer-cancel (fn [_] (reset! sizing nil))}]))
|
:on-pointer-cancel (fn [_] (reset! sizing nil))}]))
|
||||||
|
|
||||||
(defn panes
|
(defn panes
|
||||||
"Which panes are open, as three switches at the left of the top bar, each a
|
"Which panes are open, as a segmented control in the top bar. In the top bar
|
||||||
picture of the window with its pane filled in. In the top bar because a shut
|
because a shut pane has no head left to carry its own handle, and because on a
|
||||||
pane has no head left to carry its own handle, and because on a narrow screen
|
narrow screen this is the whole of the navigation."
|
||||||
this is the whole of the navigation."
|
|
||||||
[]
|
[]
|
||||||
(let [{:keys [shut]} @(rf/subscribe [::state])]
|
(let [{:keys [shut]} @(rf/subscribe [::state])]
|
||||||
[:div.icons.panes {:aria-label "panes"}
|
[:div.seg.panes {:aria-label "panes"}
|
||||||
(doall
|
(doall
|
||||||
(for [[k label strip] [[:pool "media pool" {:x 1.5 :y 2.5 :width 4 :height 11}]
|
(for [[k label] [[:pool "pool"] [:params "inspector"] [:time "timeline"]]]
|
||||||
[:time "timeline" {:x 1.5 :y 9.5 :width 13 :height 4}]
|
|
||||||
[:params "inspector" {:x 10.5 :y 2.5 :width 4 :height 11}]]]
|
|
||||||
(let [open? (not (contains? shut k))]
|
(let [open? (not (contains? shut k))]
|
||||||
^{:key k}
|
^{:key k}
|
||||||
[:button.ico {:class (when open? "on")
|
[:button {:class (when open? "on")
|
||||||
:aria-pressed open? :aria-label label
|
:aria-pressed open?
|
||||||
:title (str (if open? "hide the " "show the ") label)
|
:title (str (if open? "hide the " "show the ") label)
|
||||||
:on-click #(rf/dispatch [::toggle k])}
|
:on-click #(rf/dispatch [::toggle k])}
|
||||||
[:svg {:view-box "0 0 16 16"}
|
label])))]))
|
||||||
[:rect.frame {:x 1.5 :y 2.5 :width 13 :height 11 :rx 1}]
|
|
||||||
[:rect (assoc strip :rx 0.5)]]])))]))
|
|
||||||
|
|
||||||
(defn- stepped [k z out?]
|
(defn- stepped [k z out?]
|
||||||
;; Geometric steps work below 100% as well as above it.
|
;; Geometric steps work below 100% as well as above it.
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,9 @@
|
||||||
(:require [arthur.db :as db]
|
(:require [arthur.db :as db]
|
||||||
[arthur.events.playback :as pb]
|
[arthur.events.playback :as pb]
|
||||||
[arthur.events.project :as project]
|
[arthur.events.project :as project]
|
||||||
[re-frame.core :as rf]))
|
[arthur.subs.playback :as playback]
|
||||||
|
[re-frame.core :as rf]
|
||||||
|
[reagent.core :as r]))
|
||||||
|
|
||||||
(defn- when-said
|
(defn- when-said
|
||||||
"The ISO stamp the server sends, as a date. Truncated rather than formatted:
|
"The ISO stamp the server sends, as a date. Truncated rather than formatted:
|
||||||
|
|
@ -33,12 +35,26 @@
|
||||||
label
|
label
|
||||||
(when sub [:span.sub sub])])
|
(when sub [:span.sub sub])])
|
||||||
|
|
||||||
(defn panel
|
(defn view []
|
||||||
"The list, under the top bar's file menu. `close!` shuts it."
|
(r/with-let [open? (r/atom false)]
|
||||||
[close!]
|
|
||||||
(let [{:keys [items loading?]} @(rf/subscribe [::project/listing])
|
(let [{:keys [items loading?]} @(rf/subscribe [::project/listing])
|
||||||
choose! (fn [event] (close!) (rf/dispatch event))]
|
busy? (:busy? @(rf/subscribe [::playback/project]))
|
||||||
[:div.menu.menu-left
|
choose! (fn [event] (reset! open? false) (rf/dispatch event))]
|
||||||
|
[:div.menu-wrap
|
||||||
|
[:button {:disabled busy?
|
||||||
|
:class (when @open? "on")
|
||||||
|
:on-click (fn []
|
||||||
|
(when-not @open? (rf/dispatch [::project/list]))
|
||||||
|
(swap! open? not))}
|
||||||
|
"open ▾"]
|
||||||
|
(when @open?
|
||||||
|
[:<>
|
||||||
|
;; A full-page catcher behind the panel, so clicking anywhere else
|
||||||
|
;; dismisses it. Cheaper and more predictable than a document-level
|
||||||
|
;; listener that has to be added, removed and told to ignore the click
|
||||||
|
;; that opened the menu.
|
||||||
|
[:div.menu-scrim {:on-click #(reset! open? false)}]
|
||||||
|
[:div.menu
|
||||||
[:h2 "projects"]
|
[:h2 "projects"]
|
||||||
(cond
|
(cond
|
||||||
loading? [:div.dim "…"]
|
loading? [:div.dim "…"]
|
||||||
|
|
@ -59,4 +75,4 @@
|
||||||
:on-click #(choose! [::pb/select-clip id])}]))
|
:on-click #(choose! [::pb/select-clip id])}]))
|
||||||
[item {:label "8625 stage study" :example? true
|
[item {:label "8625 stage study" :example? true
|
||||||
:sub "composed from a locally saved project"
|
:sub "composed from a locally saved project"
|
||||||
:on-click #(choose! [::project/load-stage])}]]))
|
:on-click #(choose! [::project/load-stage])}]]])])))
|
||||||
|
|
|
||||||
|
|
@ -7,13 +7,19 @@
|
||||||
[re-frame.core :as rf]
|
[re-frame.core :as rf]
|
||||||
[reagent.core :as r]))
|
[reagent.core :as r]))
|
||||||
|
|
||||||
(defn panel
|
(defn view []
|
||||||
"Named versions, under the top bar's file menu. `close!` shuts it."
|
(r/with-let [open? (r/atom false)
|
||||||
[close!]
|
draft (r/atom "")]
|
||||||
(r/with-let [draft (r/atom "")]
|
|
||||||
(let [{:keys [can-edit?]} @(rf/subscribe [::playback/project])
|
(let [{:keys [can-edit?]} @(rf/subscribe [::playback/project])
|
||||||
rows @(rf/subscribe [::collab/snapshot-list])
|
rows @(rf/subscribe [::collab/snapshot-list])
|
||||||
editable? (not (false? can-edit?))]
|
editable? (not (false? can-edit?))]
|
||||||
|
[:div.menu-wrap
|
||||||
|
[:button {:class (when @open? "on")
|
||||||
|
:on-click (fn [] (when-not @open? (rf/dispatch [::collab/snapshots]))
|
||||||
|
(swap! open? not))}
|
||||||
|
"snapshots ▾"]
|
||||||
|
(when @open?
|
||||||
|
[:<> [:div.menu-scrim {:on-click #(reset! open? false)}]
|
||||||
[:div.menu.menu-left
|
[:div.menu.menu-left
|
||||||
(when editable?
|
(when editable?
|
||||||
[:form.row {:on-submit (fn [e]
|
[:form.row {:on-submit (fn [e]
|
||||||
|
|
@ -33,6 +39,6 @@
|
||||||
[:div.menu-item.static
|
[:div.menu-item.static
|
||||||
[:span name [:span.sub (str author " · " (subs (str created) 0 16))]]
|
[:span name [:span.sub (str author " · " (subs (str created) 0 16))]]
|
||||||
(when editable?
|
(when editable?
|
||||||
[:button.link {:on-click (fn [] (close!)
|
[:button.link {:on-click (fn [] (reset! open? false)
|
||||||
(rf/dispatch [::collab/restore row]))}
|
(rf/dispatch [::collab/restore row]))}
|
||||||
"restore"])])))])))
|
"restore"])])))]])])))
|
||||||
|
|
|
||||||
|
|
@ -1,20 +1,18 @@
|
||||||
(ns arthur.ui.topbar
|
(ns arthur.ui.topbar
|
||||||
"The strip across the top: everything you do to the whole document, on the
|
"The strip across the top: what document this is, and the three things you can
|
||||||
surface rather than in menus, and as pictures rather than words so there is
|
do to the whole of it.
|
||||||
room for all of it. Each group is a run of the same plain icon button — panes,
|
|
||||||
file, history, clipboard, versions — then the document's name in the middle,
|
|
||||||
then export and the people on the right. Every icon says what it is on hover.
|
|
||||||
|
|
||||||
Open, snapshots and undo history are lists, so they drop from their button;
|
Save, open and export are here rather than in a pane because none of them is a
|
||||||
only one of them is open at a time."
|
property of a selection — they act on the document, and the document is the
|
||||||
|
window."
|
||||||
(:require [arthur.events.collab :as collab]
|
(:require [arthur.events.collab :as collab]
|
||||||
[arthur.events.export :as export]
|
[arthur.events.export :as export]
|
||||||
[arthur.events.history :as history]
|
|
||||||
[arthur.events.project :as project]
|
[arthur.events.project :as project]
|
||||||
[arthur.events.ui :as ui]
|
[arthur.events.ui :as ui]
|
||||||
[arthur.subs.playback :as playback]
|
[arthur.subs.playback :as playback]
|
||||||
[arthur.subs.ui :as sub]
|
[arthur.subs.ui :as sub]
|
||||||
[arthur.ui.layout :as layout]
|
[arthur.ui.layout :as layout]
|
||||||
|
[arthur.ui.menu :as menu]
|
||||||
[arthur.ui.openmenu :as openmenu]
|
[arthur.ui.openmenu :as openmenu]
|
||||||
[arthur.ui.share :as share]
|
[arthur.ui.share :as share]
|
||||||
[arthur.ui.snapshots :as snapshots]
|
[arthur.ui.snapshots :as snapshots]
|
||||||
|
|
@ -26,6 +24,7 @@
|
||||||
(let [{:keys [target zoom busy? done total]} @(rf/subscribe [::export/state])
|
(let [{:keys [target zoom busy? done total]} @(rf/subscribe [::export/state])
|
||||||
targets @(rf/subscribe [::export/targets])]
|
targets @(rf/subscribe [::export/targets])]
|
||||||
[:<>
|
[:<>
|
||||||
|
[:button {:disabled busy? :on-click #(reset! open? true)} "export…"]
|
||||||
(when @open?
|
(when @open?
|
||||||
[:<> [:div.export-scrim {:on-click #(when-not busy? (reset! open? false))}]
|
[:<> [:div.export-scrim {:on-click #(when-not busy? (reset! open? false))}]
|
||||||
[:section.export-dialog {:role "dialog" :aria-modal true :aria-label "Export"}
|
[:section.export-dialog {:role "dialog" :aria-modal true :aria-label "Export"}
|
||||||
|
|
@ -49,53 +48,16 @@
|
||||||
(if busy? (str "rendering " done "/" total) "start export")]
|
(if busy? (str "rendering " done "/" total) "start export")]
|
||||||
[:button {:disabled busy? :on-click #(reset! open? false)} "close"]]]])]))
|
[:button {:disabled busy? :on-click #(reset! open? false)} "close"]]]])]))
|
||||||
|
|
||||||
(defn- icon
|
|
||||||
"A 16-unit glyph, stroked in the button's own colour."
|
|
||||||
[& paths]
|
|
||||||
(into [:svg {:view-box "0 0 16 16"}] paths))
|
|
||||||
|
|
||||||
(def ^:private glyphs
|
|
||||||
{:new (icon [:path {:d "M4 1.5h5.5L12.5 4.5V14.5H4Z"}] [:path {:d "M8.25 7v5M5.75 9.5h5"}])
|
|
||||||
:open (icon [:path {:d "M1.5 3.5h4.5l1.5 1.5h7v8.5h-13Z"}])
|
|
||||||
:undo (icon [:path {:d "M5.5 3 2.5 6l3 3"}] [:path {:d "M2.5 6h7a4 4 0 0 1 0 8H6"}])
|
|
||||||
:redo (icon [:path {:d "M10.5 3l3 3-3 3"}] [:path {:d "M13.5 6h-7a4 4 0 0 0 0 8H10"}])
|
|
||||||
:history (icon [:path {:d "M4.5 6.5 8 10l3.5-3.5"}])
|
|
||||||
:cut (icon [:circle {:cx 4.5 :cy 12 :r 2}] [:circle {:cx 11.5 :cy 12 :r 2}]
|
|
||||||
[:path {:d "M5.8 10.5 11.5 2M10.2 10.5 4.5 2"}])
|
|
||||||
:copy (icon [:rect {:x 2 :y 2 :width 8 :height 8 :rx 1}] [:rect {:x 6 :y 6 :width 8 :height 8 :rx 1}])
|
|
||||||
:paste (icon [:path {:d "M5.5 2.5h-2v12h9v-12h-2"}] [:rect {:x 5.5 :y 1.5 :width 5 :height 2.5 :rx 0.5}])
|
|
||||||
:duplicate (icon [:rect.fill {:x 2 :y 2 :width 8 :height 8 :rx 1}] [:rect {:x 6 :y 6 :width 8 :height 8 :rx 1}])
|
|
||||||
:unique (icon [:rect.fill {:x 2 :y 2 :width 8 :height 8 :rx 1}]
|
|
||||||
[:rect {:x 6 :y 6 :width 8 :height 8 :rx 1 :stroke-dasharray "2 1.5"}])
|
|
||||||
:snapshots (icon [:path {:d "M4 1.5h8v13l-4-3-4 3Z"}])
|
|
||||||
:export (icon [:path {:d "M8 10V1.5M4.5 5 8 1.5 11.5 5"}] [:path {:d "M2 9.5v5h12v-5"}])})
|
|
||||||
|
|
||||||
(defn- btn [glyph title attrs]
|
|
||||||
[:button.ico (merge {:title title :aria-label title} attrs) (glyphs glyph)])
|
|
||||||
|
|
||||||
(defn- dropper
|
|
||||||
"An icon button with a list hanging from it: projects, snapshots, undo steps."
|
|
||||||
[panel k glyph title on-open body & [disabled?]]
|
|
||||||
[:div.menu-wrap
|
|
||||||
[btn glyph title {:class (when (= k @panel) "on") :disabled disabled?
|
|
||||||
:on-click (fn [] (if (= k @panel)
|
|
||||||
(reset! panel nil)
|
|
||||||
(do (on-open) (reset! panel k))))}]
|
|
||||||
(when (= k @panel)
|
|
||||||
[:<> [:div.menu-scrim {:on-click #(reset! panel nil)}]
|
|
||||||
[body #(reset! panel nil)]])])
|
|
||||||
|
|
||||||
(defn view []
|
(defn view []
|
||||||
(r/with-let [renaming? (r/atom false)
|
(r/with-let [renaming? (r/atom false)
|
||||||
draft (r/atom "")
|
draft (r/atom "")
|
||||||
panel (r/atom nil)
|
|
||||||
export-open? (r/atom false)]
|
export-open? (r/atom false)]
|
||||||
(let [{project-name :name project-seq :seq :keys [busy? status]} @(rf/subscribe [::playback/project])
|
(let [{project-name :name project-seq :seq :keys [busy? status]} @(rf/subscribe [::playback/project])
|
||||||
{footage-status :status} @(rf/subscribe [::playback/footage])
|
{footage-status :status} @(rf/subscribe [::playback/footage])
|
||||||
{export-status :status export-busy? :busy?} @(rf/subscribe [::export/state])
|
{export-status :status} @(rf/subscribe [::export/state])
|
||||||
{:keys [done undone]} @(rf/subscribe [::history/steps])
|
selections @(rf/subscribe [::sub/selections])
|
||||||
selected? (boolean (seq @(rf/subscribe [::sub/selections])))
|
|
||||||
clipboard @(rf/subscribe [::sub/clipboard])
|
clipboard @(rf/subscribe [::sub/clipboard])
|
||||||
|
selected? (boolean (seq selections))
|
||||||
title (or project-name "untitled")
|
title (or project-name "untitled")
|
||||||
commit! (fn []
|
commit! (fn []
|
||||||
(rf/dispatch [::project/rename @draft])
|
(rf/dispatch [::project/rename @draft])
|
||||||
|
|
@ -107,31 +69,24 @@
|
||||||
;; this strip scrolls, and which panes are open is the one control that
|
;; this strip scrolls, and which panes are open is the one control that
|
||||||
;; must not be the thing off the end of it.
|
;; must not be the thing off the end of it.
|
||||||
[layout/panes]
|
[layout/panes]
|
||||||
[:span.sep]
|
[:button {:disabled busy? :on-click #(rf/dispatch [::collab/create])} "new"]
|
||||||
[:div.icons
|
[openmenu/view]
|
||||||
[btn :new "new project" {:disabled busy? :on-click #(rf/dispatch [::collab/create])}]
|
[undo/view]
|
||||||
[dropper panel :open :open "open a project" #(rf/dispatch [::project/list]) openmenu/panel]]
|
[menu/view
|
||||||
[:span.sep]
|
{:label "edit" :title "selection and clipboard"
|
||||||
[:div.icons
|
:items [{:label "copy" :sub "Copy selection · ⌘/Ctrl C"
|
||||||
[btn :undo (if (seq done) (str "undo " (first done) " (⌘Z)") "nothing to undo")
|
:disabled? (not selected?) :on-click #(rf/dispatch [::ui/copy])}
|
||||||
{:disabled (empty? done) :on-click #(rf/dispatch [::history/undo])}]
|
{:label "cut" :sub "Cut selection · ⌘/Ctrl X"
|
||||||
[dropper panel :history :history "undo history" identity undo/panel (empty? done)]
|
:disabled? (not selected?) :on-click #(rf/dispatch [::ui/cut])}
|
||||||
[btn :redo (if (seq undone) (str "redo " (first undone) " (⇧⌘Z)") "nothing to redo")
|
{:label "paste" :sub "Paste at playhead into the active row · ⌘/Ctrl V"
|
||||||
{:disabled (empty? undone) :on-click #(rf/dispatch [::history/redo])}]]
|
:disabled? (nil? clipboard) :on-click #(rf/dispatch [::ui/paste])}
|
||||||
[:span.sep]
|
{:label "duplicate" :sub "Duplicate beside selection; lanes repeat forward · ⌘/Ctrl D"
|
||||||
[:div.icons
|
:disabled? (not selected?) :on-click #(rf/dispatch [::ui/duplicate])}
|
||||||
[btn :cut "cut selection (⌘X)" {:disabled (not selected?) :on-click #(rf/dispatch [::ui/cut])}]
|
{:label "duplicate unique"
|
||||||
[btn :copy "copy selection (⌘C)" {:disabled (not selected?) :on-click #(rf/dispatch [::ui/copy])}]
|
:sub "Duplicate with a private nested symbol graph · ⇧⌘/Ctrl D"
|
||||||
[btn :paste "paste at the playhead into the active row (⌘V)"
|
:disabled? (not selected?)
|
||||||
{:disabled (nil? clipboard) :on-click #(rf/dispatch [::ui/paste])}]
|
:on-click #(rf/dispatch [::ui/duplicate-unique])}]}]
|
||||||
[btn :duplicate "duplicate beside the selection; lanes repeat forward (⌘D)"
|
[snapshots/view]
|
||||||
{:disabled (not selected?) :on-click #(rf/dispatch [::ui/duplicate])}]
|
|
||||||
[btn :unique "duplicate unique — with a private copy of its nested symbols (⇧⌘D)"
|
|
||||||
{:disabled (not selected?) :on-click #(rf/dispatch [::ui/duplicate-unique])}]]
|
|
||||||
[:span.sep]
|
|
||||||
[dropper panel :snapshots :snapshots "snapshots — name this version, or go back to one"
|
|
||||||
#(rf/dispatch [::collab/snapshots]) snapshots/panel]
|
|
||||||
[:div.doc
|
|
||||||
(if @renaming?
|
(if @renaming?
|
||||||
[:input.project-name {:auto-focus true :value @draft
|
[:input.project-name {:auto-focus true :value @draft
|
||||||
:on-change #(reset! draft (.. % -target -value))
|
:on-change #(reset! draft (.. % -target -value))
|
||||||
|
|
@ -144,9 +99,7 @@
|
||||||
[:button.project-title {:disabled busy? :title "click to rename project"
|
[:button.project-title {:disabled busy? :title "click to rename project"
|
||||||
:on-click (fn [] (reset! draft title)
|
:on-click (fn [] (reset! draft title)
|
||||||
(reset! renaming? true))}
|
(reset! renaming? true))}
|
||||||
title (when project-seq [:span.dim (str " r" project-seq)])])
|
title (when project-seq (str " r" project-seq))])
|
||||||
[:span.status (or export-status status footage-status)]]
|
[:span.status (or export-status status footage-status)]
|
||||||
[btn :export "export a PNG sequence and audio"
|
|
||||||
{:disabled export-busy? :on-click #(reset! export-open? true)}]
|
|
||||||
[exporter export-open?]
|
[exporter export-open?]
|
||||||
[share/view]])))
|
[share/view]])))
|
||||||
|
|
|
||||||
|
|
@ -1,22 +1,32 @@
|
||||||
(ns arthur.ui.undo
|
(ns arthur.ui.undo
|
||||||
"The list of what undo would take off — newest first, so choosing the third
|
"Undo, redo, and the list of what undo would take off — newest first, so
|
||||||
row undoes three steps. Undo and redo themselves are the top bar's."
|
choosing the third row undoes three steps."
|
||||||
(:require [arthur.events.history :as history]
|
(:require [arthur.events.history :as history]
|
||||||
[re-frame.core :as rf]))
|
[re-frame.core :as rf]
|
||||||
|
[reagent.core :as r]))
|
||||||
|
|
||||||
(defn panel
|
(defn view []
|
||||||
"What undo would take off, newest first, under the edit menu. `close!` shuts it."
|
(r/with-let [open? (r/atom false)]
|
||||||
[close!]
|
(let [{:keys [done undone]} @(rf/subscribe [::history/steps])]
|
||||||
(let [{:keys [done]} @(rf/subscribe [::history/steps])]
|
[:div.menu-wrap.undo
|
||||||
|
[:button {:disabled (empty? done) :title (if (seq done) (str "undo " (first done) " (⌘Z)") "nothing to undo")
|
||||||
|
:on-click #(rf/dispatch [::history/undo])}
|
||||||
|
"undo"]
|
||||||
|
[:button.undo-list {:disabled (empty? done) :class (when @open? "on")
|
||||||
|
:title "undo history" :on-click #(swap! open? not)}
|
||||||
|
"▾"]
|
||||||
|
[:button {:disabled (empty? undone) :title (if (seq undone) (str "redo " (first undone) " (⇧⌘Z)") "nothing to redo")
|
||||||
|
:on-click #(rf/dispatch [::history/redo])}
|
||||||
|
"redo"]
|
||||||
|
(when (and @open? (seq done))
|
||||||
|
[:<> [:div.menu-scrim {:on-click #(reset! open? false)}]
|
||||||
[:div.menu.menu-left
|
[:div.menu.menu-left
|
||||||
[:h2 "undo history"]
|
[:h2 "undo"]
|
||||||
(if (empty? done)
|
|
||||||
[:div.dim "nothing to undo"]
|
|
||||||
(doall
|
(doall
|
||||||
(map-indexed
|
(map-indexed
|
||||||
(fn [i label]
|
(fn [i label]
|
||||||
^{:key i}
|
^{:key i}
|
||||||
[:button.menu-item {:on-click (fn [] (close!)
|
[:button.menu-item {:on-click (fn [] (reset! open? false)
|
||||||
(rf/dispatch [::history/undo (inc i)]))}
|
(rf/dispatch [::history/undo (inc i)]))}
|
||||||
label (when (pos? i) [:span.sub (str (inc i) " steps")])])
|
label (when (pos? i) [:span.sub (str (inc i) " steps")])])
|
||||||
(take 30 done))))]))
|
(take 30 done)))]])])))
|
||||||
|
|
|
||||||
|
|
@ -251,7 +251,8 @@ const CLICK = (label) => `(() => {
|
||||||
// turn of the event loop between them, as it is for anybody using the app.
|
// turn of the event loop between them, as it is for anybody using the app.
|
||||||
const MENU_OPEN = `(() => {
|
const MENU_OPEN = `(() => {
|
||||||
if (document.querySelector('.menu')) return true;
|
if (document.querySelector('.menu')) return true;
|
||||||
const b = document.querySelector('.top button[aria-label="open a project"]');
|
const b = [...document.querySelectorAll('button')]
|
||||||
|
.find((b) => b.textContent.trim() === 'open \u25be');
|
||||||
if (!b || b.disabled) return false;
|
if (!b || b.disabled) return false;
|
||||||
b.click();
|
b.click();
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -155,6 +155,8 @@ audio { display: none; }
|
||||||
/* Which panes are open, in the top bar. Lower-case words rather than icons: the
|
/* Which panes are open, in the top bar. Lower-case words rather than icons: the
|
||||||
three panes have names and the names are what the rest of the chrome calls
|
three panes have names and the names are what the rest of the chrome calls
|
||||||
them. */
|
them. */
|
||||||
|
.panes > button { color: var(--dim); }
|
||||||
|
.panes > button.on { color: var(--fg); }
|
||||||
|
|
||||||
/* A zoom readout that is also the way back to 1:1, so it is a button that looks
|
/* A zoom readout that is also the way back to 1:1, so it is a button that looks
|
||||||
like the number it shows. Tabular figures, because the + beside it must not
|
like the number it shows. Tabular figures, because the + beside it must not
|
||||||
|
|
@ -311,29 +313,8 @@ button.retry { border-color: var(--sel); color: var(--sel); }
|
||||||
}
|
}
|
||||||
|
|
||||||
.top .brand { color: var(--dim); letter-spacing: .14em; text-transform: uppercase; }
|
.top .brand { color: var(--dim); letter-spacing: .14em; text-transform: uppercase; }
|
||||||
/* The top bar's icon runs: plain glyphs until pointed at, accented when on.
|
|
||||||
A run is one group; `.sep` divides one run from the next. */
|
|
||||||
.icons { display: flex; align-items: center; gap: 1px; }
|
|
||||||
.top button.ico { border-color: transparent; background: none; padding: 3px 5px; }
|
|
||||||
.top button.ico:hover:not(:disabled) { background: var(--sunk); border-color: var(--hair); }
|
|
||||||
.top button.ico.on { background: var(--sel-bg); border-color: var(--sel); color: var(--sel); }
|
|
||||||
.top button.ico > svg {
|
|
||||||
width: 16px; height: 16px;
|
|
||||||
fill: none; stroke: currentColor; stroke-width: 1.3; stroke-linecap: round; stroke-linejoin: round;
|
|
||||||
}
|
|
||||||
.top button.ico svg .fill, .panes svg rect:not(.frame) { fill: currentColor; stroke: none; }
|
|
||||||
.top .sep { height: 16px; }
|
|
||||||
|
|
||||||
/* What this is and what it is doing: the middle of the bar, and the room in it. */
|
|
||||||
.top .doc {
|
|
||||||
flex: 1;
|
|
||||||
min-width: 0;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
gap: 9px;
|
|
||||||
}
|
|
||||||
.top .status {
|
.top .status {
|
||||||
|
flex: 1;
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
|
@ -341,13 +322,7 @@ button.retry { border-color: var(--sel); color: var(--sel); }
|
||||||
color: var(--dim);
|
color: var(--dim);
|
||||||
}
|
}
|
||||||
|
|
||||||
.project-title {
|
.project-title { max-width: 22vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap; }
|
||||||
max-width: 28vw; overflow: hidden; text-overflow: ellipsis; white-space: nowrap;
|
|
||||||
border-color: transparent; background: none; font-weight: 600;
|
|
||||||
}
|
|
||||||
.project-title:hover:not(:disabled) { border-color: var(--line); }
|
|
||||||
|
|
||||||
.panes button.ico:not(.on) { color: var(--dim); }
|
|
||||||
.project-name { width: 180px; }
|
.project-name { width: 180px; }
|
||||||
.export-scrim { position: fixed; inset: 0; z-index: 50; background: rgba(0, 0, 0, .45); }
|
.export-scrim { position: fixed; inset: 0; z-index: 50; background: rgba(0, 0, 0, .45); }
|
||||||
.export-dialog {
|
.export-dialog {
|
||||||
|
|
@ -442,6 +417,11 @@ button.link { border: 0; background: none; padding: 0; color: var(--sel); cursor
|
||||||
.index-list a:hover { color: var(--sel); }
|
.index-list a:hover { color: var(--sel); }
|
||||||
a.brand { text-decoration: none; }
|
a.brand { text-decoration: none; }
|
||||||
|
|
||||||
|
/* Undo, its list, redo: one group. */
|
||||||
|
.undo { display: flex; gap: 0; }
|
||||||
|
.undo > button { border-radius: 0; }
|
||||||
|
.undo > button:first-child { border-radius: 2px 0 0 2px; }
|
||||||
|
.undo > .undo-list { padding: 0 4px; margin-right: 4px; border-left: 0; border-radius: 0 2px 2px 0; }
|
||||||
.menu.menu-left { left: 0; right: auto; }
|
.menu.menu-left { left: 0; right: auto; }
|
||||||
|
|
||||||
/* A menu dropping out of a PANE HEAD. Fixed and placed by `ui/menu` against the
|
/* A menu dropping out of a PANE HEAD. Fixed and placed by `ui/menu` against the
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue