Skip to content

Commit

Permalink
yolo
Browse files Browse the repository at this point in the history
  • Loading branch information
hokolomopo committed Dec 17, 2024
1 parent 8caa8ef commit ef48607
Show file tree
Hide file tree
Showing 4 changed files with 111 additions and 79 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ export class GridCellIconStore extends SpreadsheetStore {
this.iconProviders = this.iconProviders.filter((provider) => provider !== iconProvider);
}

private getIcon(position: CellPosition): GridCellIconParams | undefined {
const iconMatchers = [...this.iconProviders, ...gridCellIconRegistry.getAll()];
getIcon(position: CellPosition): GridCellIconParams | undefined {
const iconProviders = [...this.iconProviders, ...gridCellIconRegistry.getAll()];

for (const iconMatcher of iconMatchers) {
for (const iconMatcher of iconProviders) {
if (iconMatcher.hasIcon(this.getters, position)) {
return {
position,
Expand Down
105 changes: 105 additions & 0 deletions src/components/headers_overlay/autoresize_store.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
import { CellPosition, Command, HeaderIndex, UID } from "../..";
import { GRID_ICON_MARGIN, ICON_EDGE_LENGTH, PADDING_AUTORESIZE_HORIZONTAL } from "../../constants";
import {
computeIconWidth,
computeTextWidth,
largeMax,
positions,
splitTextToWidth,
} from "../../helpers";
import { SpreadsheetStore } from "../../stores";
import { GridCellIconStore } from "../grid_cell_icon_overlay/grid_cell_icon_overlay_store";

export class AutoresizeStore extends SpreadsheetStore {
private ctx = document.createElement("canvas").getContext("2d")!;

protected gridCellIconStore = this.get(GridCellIconStore);

handle(cmd: Command) {
switch (cmd.type) {
case "AUTORESIZE_COLUMNS":
for (let col of cmd.cols) {
const size = this.getColMaxWidth(cmd.sheetId, col);
if (size !== 0) {
this.model.dispatch("RESIZE_COLUMNS_ROWS", {
elements: [col],
dimension: "COL",
size,
sheetId: cmd.sheetId,
});
}
}
break;
case "AUTORESIZE_ROWS":
for (let row of cmd.rows) {
this.model.dispatch("RESIZE_COLUMNS_ROWS", {
elements: [row],
dimension: "ROW",
size: null,
sheetId: cmd.sheetId,
});
}
break;
}
}

getCellWidth(position: CellPosition): number {
const style = this.getters.getCellComputedStyle(position);

let contentWidth = 0;

const content = this.getters.getEvaluatedCell(position).formattedValue;
if (content) {
const multiLineText = splitTextToWidth(this.ctx, content, style, undefined);
contentWidth += Math.max(
...multiLineText.map((line) => computeTextWidth(this.ctx, line, style))
);
}

const icon = this.getters.getCellIconSrc(position);
if (icon) {
contentWidth += computeIconWidth(style);
}

/** ADRM TODO: DISCUSS. This ts-ignore sucks. We don't wan't getIcon to be a mutator (we don't want a render).
* Could call this.gridCellIconStore.icons, but this would compute the icons of all the visible cells, which is very
* wasteful. Possible solutions:
* 1) add a getter mechanism to stores which does not trigger a render
* 2) cache the computed icons. The icons change based on a bunch of commands and based on the side panel opened, so
* invalidating it is a problem. Something that clears the cache at each render ?
* 3) don't use stores for this PR and use good ol' plugins instead. Would need a command ADD_ICON_PROVIDER, but if
* we cannot use store for all UI related features, what's the point of having them ?
* 4) make getIcon a mutator and trust owl and the dev. Here if owl works correctly it should be fine (command AUTORESIZE
* already triggers a render, and I hope that multiple render(true) called in the same frame do'nt trigger multiple
* renders). TBH I think it's a bad idea.
* 5) make the gridCellIconStore expose the iconProviders and use non-store helpers to compute the icons.
* 6) have autoresize ignore the pivot sort icons. Functionally why not, but we'd have 2 source of truth for the icons:
* the gridCellIconStore and the getGridCellIcon getter. Not great.
*
* IMO 1) > 5) > 3)
*/
// @ts-ignore
const cellIcon = this.gridCellIconStore.getIcon(position);
if (cellIcon) {
contentWidth += ICON_EDGE_LENGTH + GRID_ICON_MARGIN;
}

if (contentWidth === 0) {
return 0;
}

contentWidth += 2 * PADDING_AUTORESIZE_HORIZONTAL;
if (style.wrapping === "wrap") {
const colWidth = this.getters.getColSize(this.getters.getActiveSheetId(), position.col);
return Math.min(colWidth, contentWidth);
}

return contentWidth;
}

private getColMaxWidth(sheetId: UID, index: HeaderIndex): number {
const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
return Math.max(0, largeMax(sizes));
}
}
2 changes: 2 additions & 0 deletions src/components/headers_overlay/headers_overlay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import { isCtrlKey } from "../helpers/dom_helpers";
import { dragAndDropBeyondTheViewport, startDnd } from "../helpers/drag_and_drop";
import { MergeErrorMessage } from "../translations_terms";
import { ComposerFocusStore } from "./../composer/composer_focus_store";
import { AutoresizeStore } from "./autoresize_store";

// -----------------------------------------------------------------------------
// Resizer component
Expand Down Expand Up @@ -112,6 +113,7 @@ abstract class AbstractResizer extends Component<ResizerProps, SpreadsheetChildE

setup(): void {
this.composerFocusStore = useStore(ComposerFocusStore);
useStore(AutoresizeStore);
}

_computeHandleDisplay(ev: MouseEvent) {
Expand Down
77 changes: 1 addition & 76 deletions src/plugins/ui_feature/ui_sheet.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,7 @@
import { GRID_ICON_MARGIN, ICON_EDGE_LENGTH, PADDING_AUTORESIZE_HORIZONTAL } from "../../constants";
import {
computeIconWidth,
computeTextWidth,
formatValue,
isEqual,
largeMax,
positions,
range,
splitTextToWidth,
} from "../../helpers/index";
Expand All @@ -17,13 +13,11 @@ import {
import { iconsOnCellRegistry } from "../../registries/icons_on_cell_registry";
import { CellValueType, Command, CommandResult, LocalCommand, UID } from "../../types";
import { ImageSrc } from "../../types/image";
import { CellPosition, HeaderIndex, Pixel, Style, Zone } from "../../types/misc";
import { CellPosition, Pixel, Style, Zone } from "../../types/misc";
import { UIPlugin } from "../ui_plugin";

export class SheetUIPlugin extends UIPlugin {
static getters = [
"getGridCellIcon",
"getCellWidth",
"getCellIconSrc",
"getTextWidth",
"getCellText",
Expand All @@ -41,73 +35,10 @@ export class SheetUIPlugin extends UIPlugin {
return this.chainValidations(this.checkSheetExists, this.checkZonesAreInSheet)(cmd);
}

handle(cmd: Command) {
switch (cmd.type) {
case "AUTORESIZE_COLUMNS":
for (let col of cmd.cols) {
const size = this.getColMaxWidth(cmd.sheetId, col);
if (size !== 0) {
this.dispatch("RESIZE_COLUMNS_ROWS", {
elements: [col],
dimension: "COL",
size,
sheetId: cmd.sheetId,
});
}
}
break;
case "AUTORESIZE_ROWS":
for (let row of cmd.rows) {
this.dispatch("RESIZE_COLUMNS_ROWS", {
elements: [row],
dimension: "ROW",
size: null,
sheetId: cmd.sheetId,
});
}
break;
}
}

// ---------------------------------------------------------------------------
// Getters
// ---------------------------------------------------------------------------

getCellWidth(position: CellPosition): number {
const style = this.getters.getCellComputedStyle(position);

let contentWidth = 0;

const content = this.getters.getEvaluatedCell(position).formattedValue;
if (content) {
const multiLineText = splitTextToWidth(this.ctx, content, style, undefined);
contentWidth += Math.max(
...multiLineText.map((line) => computeTextWidth(this.ctx, line, style))
);
}

const icon = this.getters.getCellIconSrc(position);
if (icon) {
contentWidth += computeIconWidth(style);
}

if (this.getters.getGridCellIcon(position)) {
contentWidth += ICON_EDGE_LENGTH + GRID_ICON_MARGIN;
}

if (contentWidth === 0) {
return 0;
}

contentWidth += 2 * PADDING_AUTORESIZE_HORIZONTAL;
if (style.wrapping === "wrap") {
const colWidth = this.getters.getColSize(this.getters.getActiveSheetId(), position.col);
return Math.min(colWidth, contentWidth);
}

return contentWidth;
}

getCellIconSrc(position: CellPosition): ImageSrc | undefined {
const callbacks = iconsOnCellRegistry.getAll();
for (const callback of callbacks) {
Expand Down Expand Up @@ -224,12 +155,6 @@ export class SheetUIPlugin extends UIPlugin {
return this.getters.getEvaluatedCell(mainPosition).type === CellValueType.empty;
}

private getColMaxWidth(sheetId: UID, index: HeaderIndex): number {
const cellsPositions = positions(this.getters.getColsZone(sheetId, index, index));
const sizes = cellsPositions.map((position) => this.getCellWidth({ sheetId, ...position }));
return Math.max(0, largeMax(sizes));
}

/**
* Check that any "sheetId" in the command matches an existing
* sheet.
Expand Down

0 comments on commit ef48607

Please sign in to comment.