Skip to content

Commit

Permalink
feat: improved appearance of matrix insertion menu
Browse files Browse the repository at this point in the history
  • Loading branch information
arnog committed Dec 3, 2023
1 parent eefe878 commit f1963af
Show file tree
Hide file tree
Showing 6 changed files with 54 additions and 15 deletions.
8 changes: 4 additions & 4 deletions css/mathfield.less
Original file line number Diff line number Diff line change
Expand Up @@ -430,12 +430,12 @@ menu .ML__base {
font-size: 21px;
// color: transparent;
border: none;
border-radius: 2px;
line-height: 1;
border-radius: 0;
line-height: 21px;
text-align: center;
padding: 4px;
padding: 0;
margin: 0;
}
}

.menu-container-border [part=menu-item] {
font-size: 2rem;
Expand Down
40 changes: 35 additions & 5 deletions src/editor/default-menu.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import { Atom } from 'core/atom-class';
import { VARIANT_REPERTOIRE } from 'core/modes-math';
import { contrast } from 'ui/colors/utils';
import { _Mathfield } from 'editor-mathfield/mathfield-private';
import { _MenuItemState } from 'ui/menu/menu-item';

// Return a string from the selection, if all the atoms are character boxes
// (i.e. not fractions, square roots, etc...)
Expand Down Expand Up @@ -242,24 +243,53 @@ function getColorSubmenu(mf: _Mathfield): MenuItem[] {
return result;
}

class InsertMatrixMenuItem extends _MenuItemState<{
row: number;
col: number;
}> {
row: number;
col: number;
constructor(decl, parent, row, col) {
super(decl, parent);
this.row = row;
this.col = col;
}

set active(value: boolean) {
const cells = this.parentMenu.children as InsertMatrixMenuItem[];
if (value) {
// Make all the items with a smaller column or row active as well
for (const cell of cells) {
cell.element.classList.toggle(
'active',
cell.row <= this.row && cell.col <= this.col
);
}
} else for (const cell of cells) cell.element.classList.remove('active');
}
}

function getInsertMatrixSubmenu(mf: _Mathfield): MenuItem[] {
const result: MenuItem[] = [];

for (let rows = 1; rows <= 5; rows++) {
for (let cols = 1; cols <= 5; cols++) {
for (let row = 1; row <= 5; row++) {
for (let col = 1; col <= 5; col++) {
result.push({
createMenuItem: (decl, parent) =>
new InsertMatrixMenuItem(decl, parent, row, col),
label: `☐`,
data: { row, col },
onMenuSelect: () => {
mf.insert(
`\\begin{pmatrix}${Array(cols)
.fill(Array(rows).fill('#?').join(' & '))
`\\begin{pmatrix}${Array(col)
.fill(Array(row).fill('#?').join(' & '))
.join('\\\\')}\\end{pmatrix}`,
{
selectionMode: 'item',
}
);
},
});
} as MenuItem);
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/public/ui-menu-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ export function isSubmenu(item: MenuItem): item is MenuItemSubmenu {
export function isCommand<T>(item: MenuItem<T>): item is MenuItemCommand<T> {
return (
('type' in item && item.type === 'command') ||
'onSelect' in item ||
'onMenuSelect' in item ||
'id' in item
);
}
Expand Down
3 changes: 1 addition & 2 deletions src/ui/menu/menu-item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -157,8 +157,7 @@ export class _MenuItemState<T> implements MenuItemState<T> {
set active(value: boolean) {
if (!this.element) return;
// The active state is immediate, no need to dirty it
if (value) this.element.classList.add('active');
else this.element.classList.remove('active');
this.element.classList.toggle('active', value);
}

get items(): MenuItemState[] | undefined {
Expand Down
12 changes: 10 additions & 2 deletions src/ui/menu/menu-list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,10 @@ export class _MenuListState implements MenuListState {
this.menuItems = items;
}

get children(): MenuItemState[] {
return this._menuItems;
}

/** Setting the menu items will reset this item and
* redefine a set of _MenuItem objects
*/
Expand All @@ -54,8 +58,12 @@ export class _MenuListState implements MenuListState {
this.parentMenu = parent;
items = [...items];

// Create the _MenuItem objects
this._menuItems = items.map((x) => new _MenuItemState(x, this));
// Create the _MenuItemState objects
this._menuItems = items.map((x) =>
x['createMenuItem']
? x['createMenuItem'](x, this)
: new _MenuItemState(x, this)
);

this.hasCheck = undefined;
}
Expand Down
4 changes: 3 additions & 1 deletion src/ui/menu/private-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,11 @@ export interface MenuItemState<T = unknown> {

/** @internal */
export interface MenuListState {
readonly parentMenu: MenuListState | null;
readonly rootMenu: RootMenuState;

readonly parentMenu: MenuListState | null;
readonly children: MenuItemState[];

readonly element: HTMLElement | null;
isSubmenuOpen: boolean;

Expand Down

0 comments on commit f1963af

Please sign in to comment.