Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: IrisGridTheme iconSize #2123

Merged
merged 10 commits into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 12 additions & 10 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,11 +1099,12 @@ 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));
// extra moveTo prevents halfpixel in corner
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 {
mattrunyon marked this conversation as resolved.
Show resolved Hide resolved
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],
mofojed marked this conversation as resolved.
Show resolved Hide resolved
['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
mattrunyon marked this conversation as resolved.
Show resolved Hide resolved
Loading