Skip to content

Commit

Permalink
feat: IrisGridTheme iconSize (#2123)
Browse files Browse the repository at this point in the history
This is part of the work needed for #885 that I felt would be better as
a separate PR.

Snapshot changes are going to be slightly shifted sort icon and vertical
center + slight left shift on tree table arrows.
  • Loading branch information
mattrunyon authored Jul 16, 2024
1 parent 50f2a6d commit 58ee88d
Show file tree
Hide file tree
Showing 57 changed files with 61 additions and 54 deletions.
28 changes: 15 additions & 13 deletions packages/grid/src/GridRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1082,11 +1082,12 @@ export class GridRenderer {
context.beginPath();
for (let i = 0; i < depth - depthDiff; i += 1) {
const lineX =
columnX +
i * treeDepthIndent +
treeDepthIndent * 0.5 +
treeHorizontalPadding +
0.5;
Math.floor(
columnX +
i * treeDepthIndent +
treeDepthIndent * 0.5 +
treeHorizontalPadding
) + 0.5; // The 0.5 makes the line crisp https://stackoverflow.com/questions/9311428/draw-single-pixel-line-in-html5-canvas
context.moveTo(lineX, rowY);
context.lineTo(lineX, rowY + rowHeight);
}
Expand All @@ -1098,18 +1099,19 @@ export class GridRenderer {
context.beginPath();
for (let i = depth - depthDiff; i < depth; i += 1) {
const lineX =
columnX +
i * treeDepthIndent +
treeDepthIndent * 0.5 +
treeHorizontalPadding +
0.5;
Math.floor(
columnX +
i * treeDepthIndent +
treeDepthIndent * 0.5 +
treeHorizontalPadding
) + 0.5;
context.moveTo(lineX, rowY);
context.lineTo(lineX, rowY + Math.ceil(rowHeight / 2));
context.lineTo(lineX, rowY + Math.floor(rowHeight / 2));
// extra moveTo prevents halfpixel in corner
context.moveTo(lineX - 0.5, rowY + Math.ceil(rowHeight / 2) + 0.5);
context.moveTo(lineX - 0.5, rowY + Math.floor(rowHeight / 2) + 0.5);
context.lineTo(
lineX + treeDepthIndent - 0.5,
rowY + Math.ceil(rowHeight / 2) + 0.5
rowY + Math.floor(rowHeight / 2) + 0.5
);
}
context.stroke();
Expand Down
2 changes: 1 addition & 1 deletion packages/iris-grid/src/IrisGrid.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1498,7 +1498,7 @@ class IrisGrid extends Component<IrisGridProps, IrisGridState> {
return rowIndex != null ? modelRows.get(rowIndex) : null;
}

getTheme(): Partial<IrisGridThemeType> {
getTheme(): IrisGridThemeType {
const { model, theme } = this.props;

return this.getCachedTheme(
Expand Down
13 changes: 8 additions & 5 deletions packages/iris-grid/src/IrisGridCellRendererUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,15 @@ class IrisGridCellRendererUtils {
isExpanded: boolean
): void {
context.save();
const { x1, y1 } = treeBox;
const { theme } = state;
const { iconSize } = theme;
const { x1, x2, y1, y2 } = treeBox;
const markerIcon = isExpanded
? getIcon('caretDown')
: getIcon('caretRight');
const iconX = columnX + x1 - 2;
const iconY = rowY + y1 + 2.5;
? getIcon('caretDown', iconSize)
: getIcon('caretRight', iconSize);

const iconX = columnX + (x1 + x2) / 2 - iconSize / 2; // Midpoint of the tree box minus half the icon width
const iconY = rowY + (y2 - y1 - iconSize) / 2; // y2 - y1 is effectively rowHeight

context.fillStyle = color;
context.textAlign = 'center';
Expand Down
19 changes: 8 additions & 11 deletions packages/iris-grid/src/IrisGridIcons.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,12 @@
import { memoizeClear } from '@deephaven/grid';
import {
dhSortDown,
dhSortUp,
vsTriangleDown,
vsTriangleRight,
vsTriangleUp,
vsLinkExternal,
IconDefinition,
} from '@deephaven/icons';

export const ICON_SIZE = 16;

export type IconName =
| 'sortUp'
| 'sortDown'
Expand All @@ -18,15 +15,15 @@ export type IconName =
| 'cellOverflow';

const iconMap = new Map<IconName, IconDefinition>([
['sortUp', dhSortUp],
['sortDown', dhSortDown],
['sortUp', vsTriangleUp],
['sortDown', vsTriangleDown],
['caretDown', vsTriangleDown],
['caretRight', vsTriangleRight],
['cellOverflow', vsLinkExternal],
]);

const makeIcon = memoizeClear(
(name: IconName) => {
(name: IconName, size: number) => {
const faIcon = iconMap.get(name);
if (faIcon === undefined) {
throw new Error('Icon is undefined');
Expand All @@ -38,15 +35,15 @@ const makeIcon = memoizeClear(
const icon = new Path2D(path);
const scaledIcon = new Path2D();
const scaleMatrix = {
a: ICON_SIZE / faIcon.icon[0],
d: ICON_SIZE / faIcon.icon[1],
a: size / faIcon.icon[0],
d: size / faIcon.icon[1],
};
scaledIcon.addPath(icon, scaleMatrix);
return scaledIcon;
},
{ max: 1000 }
);

export function getIcon(name: IconName): Path2D {
return makeIcon(name);
export function getIcon(name: IconName, size: number): Path2D {
return makeIcon(name, size);
}
37 changes: 20 additions & 17 deletions packages/iris-grid/src/IrisGridRenderer.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
/* eslint react/destructuring-assignment: "off" */
/* eslint class-methods-use-this: "off" */
/* eslint no-param-reassign: "off" */
import {
BoundedAxisRange,
Coordinate,
Expand Down Expand Up @@ -69,15 +67,15 @@ export class IrisGridRenderer extends GridRenderer {

protected dataBarCellRenderer = new IrisGridDataBarCellRenderer();

getSortIcon(sort: dh.Sort | null): Path2D | null {
getSortIcon(sort: dh.Sort | null, size: number): Path2D | null {
if (!sort) {
return null;
}
if (sort.direction === TableUtils.sortDirection.ascending) {
return getIcon(ICON_NAMES.SORT_UP);
return getIcon(ICON_NAMES.SORT_UP, size);
}
if (sort.direction === TableUtils.sortDirection.descending) {
return getIcon(ICON_NAMES.SORT_DOWN);
return getIcon(ICON_NAMES.SORT_DOWN, size);
}
return null;
}
Expand Down Expand Up @@ -135,7 +133,7 @@ export class IrisGridRenderer extends GridRenderer {
mouseX: Coordinate | null;
mouseY: Coordinate | null;
metrics: GridMetrics | undefined;
theme: GridThemeType;
theme: IrisGridThemeType;
}): {
left: Coordinate | null;
top: Coordinate | null;
Expand Down Expand Up @@ -173,6 +171,7 @@ export class IrisGridRenderer extends GridRenderer {
cellHorizontalPadding,
overflowButtonColor,
overflowButtonHoverColor,
iconSize,
} = theme;

context.save();
Expand All @@ -191,9 +190,12 @@ export class IrisGridRenderer extends GridRenderer {
} else if (overflowButtonColor != null) {
context.fillStyle = overflowButtonColor;
}
const icon = getIcon(ICON_NAMES.CELL_OVERFLOW);
if (buttonLeft != null && buttonTop != null) {
context.translate(buttonLeft + cellHorizontalPadding, buttonTop + 2);
const icon = getIcon(ICON_NAMES.CELL_OVERFLOW, iconSize);
if (buttonLeft != null && buttonTop != null && buttonHeight != null) {
context.translate(
buttonLeft + cellHorizontalPadding,
buttonTop + (buttonHeight - iconSize) / 2
);
}
context.fill(icon);

Expand Down Expand Up @@ -470,7 +472,8 @@ export class IrisGridRenderer extends GridRenderer {
fontWidths,
} = metrics;

const { headerHorizontalPadding } = theme;
const { headerHorizontalPadding, iconSize: themeIconSize } = theme;
const iconSize = Math.round(themeIconSize * 0.75); // The vsTriangle icons are a bit bigger than we want
const columnWidth = getOrThrow(allColumnWidths, index, 0);
const columnX = getOrThrow(allColumnXs, index) + gridX;
const modelColumn = modelColumns.get(index);
Expand All @@ -491,7 +494,7 @@ export class IrisGridRenderer extends GridRenderer {
return;
}

const icon = this.getSortIcon(sort);
const icon = this.getSortIcon(sort, iconSize);
if (!icon) {
return;
}
Expand All @@ -506,14 +509,14 @@ export class IrisGridRenderer extends GridRenderer {
const textWidth = text.length * fontWidth;
const textRight = gridX + columnX + textWidth + headerHorizontalPadding;
let { maxX } = bounds;
maxX -= headerHorizontalPadding;
const defaultX =
gridX + columnX + columnWidth - headerHorizontalPadding - 1;
maxX -= headerHorizontalPadding; // Right visible edge of the headers
// Right edge of the column. The icon has its own horizontal padding
const defaultX = gridX + columnX + columnWidth - iconSize;

// If the text is partially off the screen, put the icon to the right of the text
// else put it at the right edge of the column/grid (whichever is smaller)
const x = textRight > maxX ? textRight + 1 : Math.min(maxX, defaultX);
const yOffset =
sort.direction === TableUtils.sortDirection.ascending ? -6 : -12;
const y = columnHeaderHeight * 0.5 + yOffset;
const y = (columnHeaderHeight - iconSize) * 0.5;

context.save();

Expand Down
9 changes: 4 additions & 5 deletions packages/iris-grid/src/IrisGridTextCellRenderer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ import {
DEFAULT_FONT_WIDTH,
getOrThrow,
GridMetrics,
GridThemeType,
GridUtils,
TextCellRenderer,
VisibleIndex,
} from '@deephaven/grid';
import { TableUtils } from '@deephaven/jsapi-utils';
import { IrisGridRenderState } from './IrisGridRenderer';
import { ICON_SIZE } from './IrisGridIcons';
import IrisGridCellRendererUtils from './IrisGridCellRendererUtils';
import type { IrisGridThemeType } from './IrisGridTheme';

class IrisGridTextCellRenderer extends TextCellRenderer {
drawCellContent(
Expand Down Expand Up @@ -85,7 +84,7 @@ class IrisGridTextCellRenderer extends TextCellRenderer {
mouseX: Coordinate | null,
mouseY: Coordinate | null,
metrics: GridMetrics | undefined,
theme: GridThemeType
theme: IrisGridThemeType
): {
left: Coordinate | null;
top: Coordinate | null;
Expand All @@ -107,9 +106,9 @@ class IrisGridTextCellRenderer extends TextCellRenderer {
}

const { width: gridWidth, verticalBarWidth } = metrics;
const { cellHorizontalPadding } = theme;
const { cellHorizontalPadding, iconSize } = theme;

const width = ICON_SIZE + 2 * cellHorizontalPadding;
const width = iconSize + 2 * cellHorizontalPadding;
const height = rowHeight;
// Right edge of column or of visible grid, whichever is smaller
const right = Math.min(
Expand Down
4 changes: 3 additions & 1 deletion packages/iris-grid/src/IrisGridTheme.ts
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ export type IrisGridThemeType = GridThemeType & {
overflowButtonColor: GridColor;
overflowButtonHoverColor: GridColor;
floatingGridRowColor: NullableGridColor;
iconSize: number;
};

/**
Expand Down Expand Up @@ -149,6 +150,7 @@ export function createDefaultIrisGridTheme(): IrisGridThemeType {
sortHeaderBarHeight: 2,
reverseHeaderBarHeight: 4,
filterBarHorizontalPadding: 4,
iconSize: 16,

activeCellSelectionBorderWidth:
parseInt(IrisGridTheme['active-cell-selection-border-width'], 10) || 2,
Expand Down Expand Up @@ -182,5 +184,5 @@ export function createDefaultIrisGridTheme(): IrisGridThemeType {
positiveBarColor: IrisGridTheme['positive-bar-color'],
negativeBarColor: IrisGridTheme['negative-bar-color'],
markerBarColor: IrisGridTheme['marker-bar-color'],
});
} satisfies IrisGridThemeType);
}
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ exports[`createDefaultIrisGridTheme should derive the default Iris grid theme 1`
"headerSeparatorHoverColor": "IrisGridTheme['header-separator-hover-color']",
"headerSortBarColor": "IrisGridTheme['header-sort-bar-color']",
"hyperlinkColor": "IrisGridTheme['hyperlink-color']",
"iconSize": 16,
"linkerColumnHoverBackgroundColor": "IrisGridTheme['linker-column-hover-bg']",
"markerBarColor": "IrisGridTheme['marker-bar-color']",
"maxColumnWidth": 600,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ class IrisGridCellOverflowMouseHandler extends GridMouseHandler {
const { model } = props;

const { canvasContext: context } = grid;
const theme = grid.getTheme();
const theme = this.irisGrid.getTheme();
const rendererState = {
context,
mouseX: x,
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/context-menu.spec.ts-snapshots/sort-by-1-chromium-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/context-menu.spec.ts-snapshots/sort-by-1-firefox-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/context-menu.spec.ts-snapshots/sort-by-1-webkit-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/context-menu.spec.ts-snapshots/sort-by-2-chromium-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/context-menu.spec.ts-snapshots/sort-by-2-webkit-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/styleguide.spec.ts-snapshots/grids-iris-chromium-linux.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified tests/styleguide.spec.ts-snapshots/grids-iris-firefox-linux.png
Binary file modified tests/styleguide.spec.ts-snapshots/grids-iris-webkit-linux.png

0 comments on commit 58ee88d

Please sign in to comment.