Skip to content

Commit 010bbdc

Browse files
committed
Add support for corner header renderer
Signed-off-by: Itay Dafna <[email protected]>
1 parent 85db7ec commit 010bbdc

File tree

3 files changed

+100
-3
lines changed

3 files changed

+100
-3
lines changed

ipydatagrid/datagrid.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,8 @@ class DataGrid(DOMWidget):
216216
Default renderer to use for cell rendering
217217
header_renderer : CellRenderer (default: TextRenderer)
218218
Renderer to use for header cell rendering
219+
corner_renderer : CellRenderer (default: TextRenderer)
220+
Renderer to use for corner header cell rendering
219221
selection_mode : {'row', 'column', 'cell', 'none'} (default: 'none')
220222
Selection mode used when user clicks on grid or makes selections
221223
programmatically.
@@ -314,6 +316,9 @@ class DataGrid(DOMWidget):
314316
header_renderer = Instance(CellRenderer, allow_none=True).tag(
315317
sync=True, **widget_serialization
316318
)
319+
corner_renderer = Instance(CellRenderer, allow_none=True).tag(
320+
sync=True, **widget_serialization
321+
)
317322
selection_mode = Enum(
318323
default_value="none", values=["row", "column", "cell", "none"]
319324
).tag(sync=True)

js/datagrid.ts

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export class DataGridModel extends DOMWidgetModel {
5656
headerVisibility: 'all',
5757
_data: {},
5858
renderers: {},
59+
corner_renderer: null,
5960
default_renderer: null,
6061
header_renderer: null,
6162
selection_mode: 'none',
@@ -238,6 +239,7 @@ export class DataGridModel extends DOMWidgetModel {
238239
...DOMWidgetModel.serializers,
239240
transforms: { deserialize: unpack_models as any },
240241
renderers: { deserialize: unpack_models as any },
242+
corner_renderer: { deserialize: unpack_models as any },
241243
default_renderer: { deserialize: unpack_models as any },
242244
header_renderer: { deserialize: unpack_models as any },
243245
_data: { deserialize: unpack_data as any },
@@ -444,7 +446,13 @@ export class DataGridView extends DOMWidgetView {
444446
});
445447

446448
this.model.on_some_change(
447-
['header_renderer', 'default_renderer', 'renderers', 'grid_style'],
449+
[
450+
'corner_renderer',
451+
'header_renderer',
452+
'default_renderer',
453+
'renderers',
454+
'grid_style',
455+
],
448456
() => {
449457
this.updateRenderers()
450458
.then(this.updateGridStyle.bind(this))
@@ -476,6 +484,9 @@ export class DataGridView extends DOMWidgetView {
476484
if (this.header_renderer) {
477485
this.stopListening(this.header_renderer, 'renderer-changed');
478486
}
487+
if (this.corner_renderer) {
488+
this.stopListening(this.corner_renderer, 'renderer-changed');
489+
}
479490
for (const key in this.renderers) {
480491
this.stopListening(this.renderers[key], 'renderer-changed');
481492
}
@@ -498,6 +509,23 @@ export class DataGridView extends DOMWidgetView {
498509
),
499510
);
500511

512+
const corner_renderer = this.model.get('corner_renderer');
513+
if (corner_renderer) {
514+
promises.push(
515+
this.create_child_view(corner_renderer).then(
516+
(cornerRendererView: any) => {
517+
this.corner_renderer = cornerRendererView;
518+
519+
this.listenTo(
520+
this.corner_renderer,
521+
'renderer-changed',
522+
this.updateGridRenderers.bind(this),
523+
);
524+
},
525+
),
526+
);
527+
}
528+
501529
const header_renderer = this.model.get('header_renderer');
502530
if (header_renderer) {
503531
promises.push(
@@ -577,6 +605,11 @@ export class DataGridView extends DOMWidgetView {
577605
columnHeaderRenderer = this.header_renderer.renderer;
578606
}
579607

608+
let cornerHeaderRenderer = null;
609+
if (this.corner_renderer) {
610+
cornerHeaderRenderer = this.corner_renderer.renderer;
611+
}
612+
580613
const renderers: Dict<CellRenderer> = {};
581614
Object.entries(this.renderers).forEach(([name, rendererView]) => {
582615
renderers[name] = rendererView.renderer;
@@ -587,6 +620,10 @@ export class DataGridView extends DOMWidgetView {
587620
if (columnHeaderRenderer) {
588621
this.grid.columnHeaderRenderer = columnHeaderRenderer;
589622
}
623+
624+
if (cornerHeaderRenderer) {
625+
this.grid.cornerHeaderRenderer = cornerHeaderRenderer;
626+
}
590627
this.grid.renderers = renderers;
591628
}
592629

@@ -608,6 +645,7 @@ export class DataGridView extends DOMWidgetView {
608645
}
609646

610647
renderers: Dict<CellRendererView>;
648+
corner_renderer: CellRendererView;
611649
default_renderer: CellRendererView;
612650
header_renderer: CellRendererView;
613651
grid: FeatherGrid;

js/feathergrid.ts

Lines changed: 56 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -424,6 +424,39 @@ export class FeatherGrid extends Widget {
424424
return this._columnHeaderRenderer;
425425
}
426426

427+
set cornerHeaderRenderer(renderer: CellRenderer) {
428+
const textRenderer = renderer as TextRenderer;
429+
430+
// HeaderRenderer adds the filter dialogue box overlay
431+
this._cornerHeaderRenderer = new HeaderRenderer({
432+
textOptions: {
433+
font: textRenderer.font,
434+
wrapText: textRenderer.wrapText,
435+
elideDirection: textRenderer.elideDirection,
436+
textColor: textRenderer.textColor,
437+
backgroundColor:
438+
this.grid.style.headerBackgroundColor ||
439+
textRenderer.backgroundColor ||
440+
Theme.getBackgroundColor(),
441+
verticalAlignment: textRenderer.verticalAlignment,
442+
horizontalAlignment: textRenderer.horizontalAlignment,
443+
format: textRenderer.format,
444+
},
445+
isLightTheme: this._isLightTheme,
446+
grid: this.grid,
447+
});
448+
449+
if (!this.grid) {
450+
return;
451+
}
452+
453+
this._updateHeaderRenderer();
454+
}
455+
456+
get cornerHeaderRenderer(): CellRenderer {
457+
return this._cornerHeaderRenderer;
458+
}
459+
427460
set renderers(renderers: Dict<CellRenderer>) {
428461
this._renderers = renderers;
429462

@@ -607,6 +640,18 @@ export class FeatherGrid extends Widget {
607640
isLightTheme: this._isLightTheme,
608641
grid: this.grid,
609642
});
643+
644+
this._cornerHeaderRenderer = new HeaderRenderer({
645+
textOptions: {
646+
textColor: Theme.getFontColor(1),
647+
backgroundColor:
648+
this.grid.style.headerBackgroundColor || Theme.getBackgroundColor(2),
649+
horizontalAlignment: 'left',
650+
verticalAlignment: 'center',
651+
},
652+
isLightTheme: this._isLightTheme,
653+
grid: this.grid,
654+
});
610655
}
611656

612657
copyToClipboard(): void {
@@ -893,9 +938,17 @@ export class FeatherGrid extends Widget {
893938
this.grid.cellRenderers.update({
894939
'column-header': this._columnHeaderRenderer,
895940
});
896-
// Treating corner header as column header for rendering purposes
941+
// Treating corner-header as column-header if a value has not
942+
// been passed for the former.
943+
let hasCornerRenderer = false;
944+
if (this.backboneModel) {
945+
hasCornerRenderer = this.backboneModel.get('corner_renderer') !== null;
946+
}
947+
897948
this.grid.cellRenderers.update({
898-
'corner-header': this._columnHeaderRenderer,
949+
'corner-header': hasCornerRenderer
950+
? this._cornerHeaderRenderer
951+
: this._columnHeaderRenderer,
899952
});
900953
}
901954

@@ -1027,6 +1080,7 @@ export class FeatherGrid extends Widget {
10271080
private _renderers: Dict<CellRenderer> = {};
10281081
private _defaultRenderer: CellRenderer;
10291082
private _columnHeaderRenderer: CellRenderer;
1083+
private _cornerHeaderRenderer: CellRenderer;
10301084
private _rowHeaderRenderer: CellRenderer;
10311085
private _defaultRendererSet = false;
10321086
private _cellClicked = new Signal<this, FeatherGrid.ICellClickedEvent>(this);

0 commit comments

Comments
 (0)