diff --git a/README.md b/README.md index ead5f17..bc78039 100644 --- a/README.md +++ b/README.md @@ -58,7 +58,13 @@ scroll- und zoombare Fläche, die **Objekte** trägt: Canvas-Objekt, unabhängig vom DOM. Nur Zeilen, nicht Spalten (in der Praxis wird eher die Zeilenzahl groß). Spaltenbreite per Drag am Spaltenkopf (ab **24 px**), **Zeilenhöhe** per Drag - an der Unterkante des Zeilenkopfs (Standard + je Zeile). + an der Unterkante des Zeilenkopfs (Standard + je Zeile). **„Ohne Rahmen/ + Kopfzeilen, wenn nicht ausgewählt"** (Einstellungen → Objekt, je Tabelle): + solange die Tabelle nicht das ausgewählte Canvas-Objekt ist, verschwinden + Titelleiste, Spaltenbuchstaben und Zeilennummern komplett — nicht nur + optisch, ihr reservierter Platz fällt mit weg, die Tabelle schrumpft auf + reines Zellraster. Ein Klick hinein (z. B. auf eine Zelle) wählt sie + wieder aus und blendet alles zurück ein. - **Diagramm-Objekt** — Chart.js (Balken/Linie), frei positionier- **und** skalierbar. Datenquelle = ein Tabellen-Objekt; jede Zelländerung aktualisiert es sofort. @@ -646,7 +652,8 @@ wichtigen Punkte: - **Objekt** (das gewählte): - Tabelle → Name, Zeilen/Spalten (exakt), Darstellung, Viewport-Größe, fixierte Kopfzeilen/Spalten, Position, Zahlenformat-Locale, **Standard- - Zeilenhöhe**, **Tabellen-Hintergrund/-Textfarbe**, und – bei aktiver + Zeilenhöhe**, **Tabellen-Hintergrund/-Textfarbe**, **„Ohne Rahmen/ + Kopfzeilen, wenn nicht ausgewählt"** (s. u.), und – bei aktiver Zellauswahl – die **Auswahl**-Formatierung (s. o.). - Diagramm → Name, Ansicht, Quelltabelle, Größe, Position, Zahlenformat-Locale, **Hintergrund**, **Text-/Achsenfarbe**. diff --git a/src/components/CanvasObject.vue b/src/components/CanvasObject.vue index 7bb53c4..977bc7f 100644 --- a/src/components/CanvasObject.vue +++ b/src/components/CanvasObject.vue @@ -221,6 +221,16 @@ function onResizeUp() { window.removeEventListener('mouseup', onResizeUp); } +/** A table with `hideChromeUnfocused` set shows its title bar (and, via the + * `selected` prop passed to TableGrid below, its row/column headers) only + * while it's the selected object -- a "clean look" presentation option + * ("Ohne Rahmen/Kopfzeilen, wenn nicht ausgewählt" in Settings). Every + * other object kind is unaffected -- always shown, today's behaviour. */ +const showChrome = computed(() => { + const o = props.object; + return props.selected || !(o.kind === 'table' && o.hideChromeUnfocused); +}); + const icon = computed(() => { switch (props.object.kind) { case 'table': @@ -253,7 +263,7 @@ const style = computed(() => { :style="style" @mousedown="emit('select')" > -
+
{
-
- +
+ @@ -357,6 +367,11 @@ const style = computed(() => { overflow: hidden; border-radius: 0 0 10px 10px; } +/* the chrome bar is what normally rounds the top corners -- without it + (hideChromeUnfocused, currently unfocused), .content fills the whole box */ +.content.full-radius { + border-radius: 10px; +} .canvas-object.flex .content { flex: 1; min-height: 0; diff --git a/src/components/SettingsPanel.vue b/src/components/SettingsPanel.vue index 9b7b30d..80b9292 100644 --- a/src/components/SettingsPanel.vue +++ b/src/components/SettingsPanel.vue @@ -161,6 +161,14 @@ function resetDoc() { Design +
diff --git a/src/components/TableGrid.vue b/src/components/TableGrid.vue index d233824..2d4ba94 100644 --- a/src/components/TableGrid.vue +++ b/src/components/TableGrid.vue @@ -19,12 +19,11 @@ import { useKeyboardPointMode } from '../composables/useKeyboardPointMode'; import ContextMenu from './ContextMenu.vue'; import FormulaSuggest from './FormulaSuggest.vue'; -const props = defineProps<{ tableId: string }>(); +const props = defineProps<{ tableId: string; selected: boolean }>(); const store = useDocument(); const table = computed(() => store.tableById(props.tableId)); -const HEAD_W = 44; const DEFAULT_W = 104; /** How far the in-cell editor may grow beyond the cell before it wraps/scrolls * -- an approximation of "the visible display width/height" rather than @@ -33,7 +32,18 @@ const EDIT_MAX_W = 560; const EDIT_MAX_H = 320; const colWidth = (c: number) => table.value?.colWidths[c] ?? DEFAULT_W; const rowH = (r: number) => store.rowHeightOf(props.tableId, r); -const headerH = computed(() => table.value?.rowHeight ?? DEFAULT_ROW_H); +/** `hideChromeUnfocused` (Settings panel "Ohne Rahmen/Kopfzeilen, wenn nicht + * ausgewählt") hides the row/column headers -- not just visually, their + * reserved space collapses to 0 too -- whenever this table isn't the + * selected canvas object (CanvasObject.vue hides its title bar the same + * way, via its own `showChrome`). `headW`/`headerH` below are what + * actually implement the collapse: every position calculation in this file + * already goes through them (or through `rowTop`/`colLeft`, which do), so + * making them 0 when hidden is the entire fix -- cells simply start at + * (0,0) instead of past a header that isn't there. */ +const showHeaders = computed(() => props.selected || table.value?.hideChromeUnfocused !== true); +const headW = computed(() => (showHeaders.value ? 44 : 0)); +const headerH = computed(() => (showHeaders.value ? (table.value?.rowHeight ?? DEFAULT_ROW_H) : 0)); /** Prefix sums of row heights (`rowCumHeights[i]` = total height of rows * `0..i-1`, excluding the header) -- lets `rowTop()` and the row @@ -127,7 +137,7 @@ const scrollStyle = computed(() => /** px from the table's left edge to the start of column `c` (incl. row header). */ function colLeft(c: number): number { - return HEAD_W + (colCumWidths.value[c] ?? 0); + return headW.value + (colCumWidths.value[c] ?? 0); } /** The internal scroll element of a fixed table (null for auto-size tables). */ @@ -1284,8 +1294,8 @@ function onRowResizeUp() { const totalWidth = computed(() => { const t = table.value; - if (!t) return HEAD_W; - let w = HEAD_W; + if (!t) return headW.value; + let w = headW.value; for (let c = 0; c < t.cols; c++) w += colWidth(c); return w; }); @@ -1320,10 +1330,10 @@ defineExpose({
- + - +