Skip to content

Commit 73f5043

Browse files
committed
Add text alignment to context menus
Signed-off-by: gjmooney <[email protected]>
1 parent ac4c74d commit 73f5043

File tree

3 files changed

+131
-6
lines changed

3 files changed

+131
-6
lines changed

js/core/gridContextMenu.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,21 @@ export class FeatherGridContextMenu extends GridContextMenu {
112112
this._menu.addItem({
113113
type: 'separator',
114114
});
115+
this._menu.addItem({
116+
command: FeatherGridContextMenu.CommandID.AlignLeft,
117+
args: args,
118+
});
119+
this._menu.addItem({
120+
command: FeatherGridContextMenu.CommandID.AlignCenter,
121+
args: args,
122+
});
123+
this._menu.addItem({
124+
command: FeatherGridContextMenu.CommandID.AlignRight,
125+
args: args,
126+
});
127+
this._menu.addItem({
128+
type: 'separator',
129+
});
115130
this._menu.addItem({
116131
command: FeatherGridContextMenu.CommandID.OpenFilterByConditionDialog,
117132
args: args,
@@ -255,6 +270,9 @@ export namespace FeatherGridContextMenu {
255270
SaveSelectionAsCsv = 'saveSelectionAsCsv',
256271
SaveAllAsCsv = 'saveAllAsCsv',
257272
ClearSelection = 'clearSelection',
273+
AlignLeft = 'align:Left',
274+
AlignCenter = 'align:Center',
275+
AlignRight = 'align:Right',
258276
}
259277

260278
/**

js/datagrid.ts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import {
2323
JupyterLuminoPanelWidget,
2424
// @ts-ignore needed for ipywidgetx 7.x compatibility
2525
JupyterPhosphorPanelWidget,
26+
pack_models,
2627
resolvePromisesDict,
2728
unpack_models,
2829
WidgetModel,
@@ -35,9 +36,9 @@ import { ViewBasedJSONModel } from './core/viewbasedjsonmodel';
3536
import { MODULE_NAME, MODULE_VERSION } from './version';
3637

3738
import { CellRendererModel, CellRendererView } from './cellrenderer';
39+
import { DataSource } from './datasource';
3840
import { FeatherGrid } from './feathergrid';
3941
import { Theme } from './utils';
40-
import { DataSource } from './datasource';
4142

4243
// Import CSS
4344
import '../style/jupyter-widget.css';
@@ -371,7 +372,10 @@ export class DataGridModel extends DOMWidgetModel {
371372
static serializers: ISerializers = {
372373
...DOMWidgetModel.serializers,
373374
transforms: { deserialize: unpack_models as any },
374-
renderers: { deserialize: unpack_models as any },
375+
renderers: {
376+
deserialize: unpack_models as any,
377+
serialize: pack_models as any,
378+
},
375379
corner_renderer: { deserialize: unpack_models as any },
376380
default_renderer: { deserialize: unpack_models as any },
377381
header_renderer: { deserialize: unpack_models as any },
@@ -853,14 +857,14 @@ export class DataGridView extends DOMWidgetView {
853857
export {
854858
BarRendererModel,
855859
BarRendererView,
856-
ImageRendererModel,
857-
ImageRendererView,
860+
HtmlRendererModel,
861+
HtmlRendererView,
858862
HyperlinkRendererModel,
859863
HyperlinkRendererView,
864+
ImageRendererModel,
865+
ImageRendererView,
860866
TextRendererModel,
861867
TextRendererView,
862-
HtmlRendererModel,
863-
HtmlRendererView,
864868
} from './cellrenderer';
865869
export { VegaExprModel, VegaExprView } from './vegaexpr';
866870

js/feathergrid.ts

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,16 @@ import { ViewBasedJSONModel } from './core/viewbasedjsonmodel';
1818
import { KeyHandler } from './keyhandler';
1919
import { MouseHandler as FeatherGridMouseHandler } from './mousehandler';
2020
import { Theme } from './utils';
21+
import { MODULE_NAME, MODULE_VERSION } from './version';
2122

2223
import { DataGridModel as BackBoneModel } from './datagrid';
2324

25+
import {
26+
DOMWidgetModel,
27+
ISerializers,
28+
unpack_models,
29+
} from '@jupyter-widgets/base';
30+
2431
import '@lumino/default-theme/style/datagrid.css';
2532
import '../style/feathergrid.css';
2633

@@ -107,6 +114,11 @@ const themeVariables: Map<string, string[]> = new Map([
107114
]);
108115

109116
export class FeatherGrid extends Widget {
117+
static serializers: ISerializers = {
118+
...DOMWidgetModel.serializers,
119+
renderers: { deserialize: unpack_models as any },
120+
};
121+
110122
constructor(options: DataGrid.IOptions = {}) {
111123
super();
112124
this.addClass('ipydatagrid-widget');
@@ -871,6 +883,55 @@ export class FeatherGrid extends Widget {
871883
});
872884
}
873885

886+
private async _createTextRendererWidget() {
887+
const model = await this.backboneModel.widget_manager.new_widget({
888+
model_name: 'TextRendererModel',
889+
model_module: MODULE_NAME,
890+
model_module_version: MODULE_VERSION,
891+
view_name: 'TextRendererView',
892+
view_module: MODULE_NAME,
893+
view_module_version: MODULE_VERSION,
894+
});
895+
return model;
896+
}
897+
898+
private async _updateTextAlignment(
899+
columnName: string,
900+
alignment: 'left' | 'center' | 'right',
901+
) {
902+
const currentRenderers = this.backboneModel.get('renderers');
903+
const defaultRenderer = this.backboneModel.get('default_renderer');
904+
const currentRendererForColumn = currentRenderers[columnName];
905+
906+
// If there is a renderer for which we can set the alignment, set it
907+
if (
908+
currentRendererForColumn !== undefined &&
909+
'horizontal_alignment' in currentRendererForColumn.attributes
910+
) {
911+
currentRendererForColumn.set('horizontal_alignment', alignment);
912+
currentRendererForColumn.save_changes();
913+
return;
914+
}
915+
916+
// Assuming it's using the default renderer, we create a new renderer and copy its attributes
917+
// TODO create a renderer of the same type as the default renderer
918+
const model = await this._createTextRendererWidget();
919+
for (const attr in model.attributes) {
920+
if (attr in defaultRenderer.attributes) {
921+
model.set(attr, defaultRenderer.get(attr));
922+
}
923+
}
924+
model.set('horizontal_alignment', alignment);
925+
model.save_changes();
926+
927+
const updatedRenderers = { ...currentRenderers };
928+
updatedRenderers[columnName] = model;
929+
930+
// TODO Find why this is not propagated to Python correctly
931+
this.backboneModel.set('renderers', updatedRenderers);
932+
this.backboneModel.save_changes();
933+
}
934+
874935
private _createCommandRegistry(): CommandRegistry {
875936
const commands = new CommandRegistry();
876937
commands.addCommand(FeatherGridContextMenu.CommandID.SortAscending, {
@@ -1034,6 +1095,48 @@ export class FeatherGrid extends Widget {
10341095
this.grid.selectionModel?.clear();
10351096
},
10361097
});
1098+
commands.addCommand(FeatherGridContextMenu.CommandID.AlignLeft, {
1099+
label: 'Align Left',
1100+
mnemonic: -1,
1101+
execute: async (args) => {
1102+
const commandArgs = <FeatherGridContextMenu.CommandArgs>args;
1103+
const columnName: string = this.dataModel.metadata(
1104+
commandArgs.region,
1105+
commandArgs.rowIndex,
1106+
commandArgs.columnIndex,
1107+
)['name'];
1108+
1109+
await this._updateTextAlignment(columnName, 'left');
1110+
},
1111+
});
1112+
commands.addCommand(FeatherGridContextMenu.CommandID.AlignCenter, {
1113+
label: 'Align Center',
1114+
mnemonic: -1,
1115+
execute: async (args) => {
1116+
const commandArgs = <FeatherGridContextMenu.CommandArgs>args;
1117+
const columnName: string = this.dataModel.metadata(
1118+
commandArgs.region,
1119+
commandArgs.rowIndex,
1120+
commandArgs.columnIndex,
1121+
)['name'];
1122+
1123+
await this._updateTextAlignment(columnName, 'center');
1124+
},
1125+
});
1126+
commands.addCommand(FeatherGridContextMenu.CommandID.AlignRight, {
1127+
label: 'Align Right',
1128+
mnemonic: -1,
1129+
execute: async (args) => {
1130+
const commandArgs = <FeatherGridContextMenu.CommandArgs>args;
1131+
const columnName: string = this.dataModel.metadata(
1132+
commandArgs.region,
1133+
commandArgs.rowIndex,
1134+
commandArgs.columnIndex,
1135+
)['name'];
1136+
1137+
await this._updateTextAlignment(columnName, 'right');
1138+
},
1139+
});
10371140

10381141
return commands;
10391142
}

0 commit comments

Comments
 (0)