Skip to content

Commit

Permalink
✨ feat: add WorkingPlane
Browse files Browse the repository at this point in the history
  • Loading branch information
xiangechen committed Oct 25, 2023
1 parent 6d9f99b commit 168a63d
Show file tree
Hide file tree
Showing 17 changed files with 257 additions and 67 deletions.
35 changes: 35 additions & 0 deletions packages/chili-core/src/base/collection.ts
Original file line number Diff line number Diff line change
Expand Up @@ -135,3 +135,38 @@ export class ObservableCollection<T> implements ICollectionChanged, IDisposable
this.#items.length = 0;
}
}

export enum SelectMode {
check,
radio,
combo,
}

export class SelectableItems<T> {
readonly items: ReadonlyArray<T>;
selectedItems: Set<T>;

get selectedIndexes(): number[] {
let indexes: number[] = [];
this.selectedItems.forEach((x) => {
let index = this.items.indexOf(x);
if (index > -1) {
indexes.push(index);
}
});
return indexes;
}

firstSelectedItem() {
return this.selectedItems.values().next().value;
}

constructor(
items: T[],
readonly mode: SelectMode = SelectMode.radio,
selectedItems?: T[],
) {
this.items = items;
this.selectedItems = new Set(selectedItems ?? []);
}
}
2 changes: 2 additions & 0 deletions packages/chili-core/src/base/pubsub.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { AsyncController } from "./asyncController";
import { IDisposable } from "./disposable";
import { NodeRecord } from "./history";
import { MessageType } from "./messageType";
import { IPropertyChanged } from "./observer";
import { Result } from "./result";

export interface PubSubEventMap {
Expand All @@ -33,6 +34,7 @@ export interface PubSubEventMap {
closeCommandContext: () => void;
showHome: () => void;
showToast: (message: I18nKeys, ...args: any[]) => void;
showDialog: (title: I18nKeys, context: IPropertyChanged, callback: () => void) => void;
}

export class PubSub implements IDisposable {
Expand Down
4 changes: 3 additions & 1 deletion packages/chili-core/src/command/commandKeys.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,6 @@ export type CommandKeys =
| "modify.move"
| "modify.rotate"
| "modify.mirror"
| "modify.delete";
| "modify.delete"
| "workingPlane.alignToPlane"
| "workingPlane.set";
3 changes: 3 additions & 0 deletions packages/chili-core/src/i18n/en.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default {
"ribbon.group.modify": "Modify",
"ribbon.group.converter": "Converter",
"ribbon.group.boolean": "Boolean",
"ribbon.group.workingPlane": "Working Plane",
"ribbon.group.importExport": "Import/Export",
"items.header": "Items",
"items.tool.newFolder": "New Folder",
Expand Down Expand Up @@ -131,5 +132,7 @@ export default {
"operate.pickNextPoint": "pick next point, ESC key to cancel",
"operate.pickCircleCenter": "pick center, ESC key to cancel",
"operate.pickRadius": "input radius, ESC key to cancel",
"workingPlane.alignToPlane": "Align to plane",
"workingPlane.set": "Set workplane",
},
} satisfies Locale;
5 changes: 4 additions & 1 deletion packages/chili-core/src/i18n/local.ts
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ export type I18nKeys =
| "ribbon.group.converter"
| "ribbon.group.selection"
| "ribbon.group.boolean"
| "ribbon.group.workingPlane"
| "ribbon.group.importExport"
| "items.header"
| "items.tool.newFolder"
Expand Down Expand Up @@ -132,4 +133,6 @@ export type I18nKeys =
| "error.input.unsupportedInputs"
| "error.input.invalidNumber"
| "error.input.threeNumberCanBeInput"
| "error.input.cannotInputANumber";
| "error.input.cannotInputANumber"
| "workingPlane.alignToPlane"
| "workingPlane.set";
3 changes: 3 additions & 0 deletions packages/chili-core/src/i18n/zh-cn.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ export default {
"ribbon.group.converter": "转换",
"ribbon.group.selection": "选择",
"ribbon.group.boolean": "布尔运算",
"ribbon.group.workingPlane": "工作平面",
"ribbon.group.importExport": "导入/导出",
"items.header": "项目",
"items.tool.newFolder": "文件夹",
Expand Down Expand Up @@ -130,5 +131,7 @@ export default {
"operate.pickNextPoint": "请选择下一个点, 按 ESC 键取消",
"operate.pickCircleCenter": "请选择圆心 按 ESC 键取消",
"operate.pickRadius": "请选择半径, 按 ESC 键取消",
"workingPlane.alignToPlane": "对齐到平面",
"workingPlane.set": "设置工作平面",
},
} satisfies Locale;
9 changes: 8 additions & 1 deletion packages/chili-ui/src/controls/controls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,12 @@ export interface CheckboxProps extends Props {
checked: boolean | Binding;
}

export interface RadioProps extends Props {
type: "radio";
value: string | Binding;
checked: boolean | Binding;
}

export interface ColorProps extends Props {
type: "color";
value?: string | Binding;
Expand All @@ -62,6 +68,7 @@ function createFunction<K extends Tags, O extends Props = Props>(tag: K) {
}
}
dom.append(...children);

return dom;
};
}
Expand Down Expand Up @@ -97,7 +104,7 @@ function setStyle(dom: HTMLElement | SVGElement, style: StyleProps) {
export const div = createFunction("div");
export const span = createFunction("span");
export const button = createFunction("button");
export const input = createFunction<"input", CheckboxProps | ColorProps>("input");
export const input = createFunction<"input", CheckboxProps | ColorProps | RadioProps>("input");
export const textarea = createFunction("textarea");
export const select = createFunction<"select", SelectProps>("select");
export const option = createFunction<"option", OptionProps>("option");
Expand Down
1 change: 0 additions & 1 deletion packages/chili-ui/src/controls/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,3 @@
export * from "./binding";
export * from "./controls";
export * from "./localize";
export * from "./state";
23 changes: 23 additions & 0 deletions packages/chili-ui/src/controls/itemsControl.module.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
.radioGroup {
padding: 8px;

& span {
margin-left: 4px;
}

& ul {
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 0;
}

& li {
margin: 4px;
list-style-type: none;
}

& input {
margin-right: 4px;
}
}
51 changes: 51 additions & 0 deletions packages/chili-ui/src/controls/itemsControl.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { SelectableItems } from "chili-core";
import { div, h2, input, li, span, ul } from "./controls";
import style from "./itemsControl.module.css";

export class RadioGroup extends HTMLElement {
constructor(
readonly header: string,
readonly context: SelectableItems<any>,
) {
super();
this.appendChild(this.render());
}

render() {
return div(
{ className: style.radioGroup },
span(this.header + ": "),
ul(
...this.context.items.map((x) => {
return li(
input({ type: "radio", value: x, checked: this.context.selectedItems.has(x) }),
x,
);
}),
),
);
}

connectedCallback() {
this.addEventListener("click", this.#onClick);
}

disconnectedCallback() {
this.removeEventListener("click", this.#onClick);
}

#onClick = (e: MouseEvent) => {
const target = e.target as HTMLInputElement;
if (target?.type === "radio") {
this.querySelectorAll("input").forEach((x) => {
if (x !== target) x.checked = false;
});
target.checked = true;
this.context.selectedItems = new Set([target.value]);
}
};
}

customElements.define("chili-radios", RadioGroup);
38 changes: 0 additions & 38 deletions packages/chili-ui/src/controls/state.ts

This file was deleted.

27 changes: 21 additions & 6 deletions packages/chili-ui/src/dialog.module.css
Original file line number Diff line number Diff line change
@@ -1,4 +1,15 @@
.dialog {
dialog {
border: none;
box-shadow: 0px 1px 2px #999;
border-radius: 8px;
padding: 0px;
}

dialog::backdrop {
background-color: rgba(0, 0, 0, 0.5);
}

.root {
display: flex;
flex-direction: column;
width: 240px;
Expand All @@ -9,6 +20,7 @@
.title {
padding: 16px;
font-size: medium;
margin: 0px auto;
}

.content {
Expand All @@ -17,10 +29,13 @@
}

.buttons {
margin-top: 16px;
padding: 16px;
}
display: flex;
flex-direction: row;
justify-content: flex-end;
padding: 8px 4px;

.button {
width: 64px;
& button {
width: 64px;
margin: 4px;
}
}
50 changes: 32 additions & 18 deletions packages/chili-ui/src/dialog.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,44 @@
// Copyright 2022-2023 the Chili authors. All rights reserved. AGPL-3.0 license.

import { I18n, I18nKeys, IPropertyChanged, Property, SelectableItems } from "chili-core";
import style from "./dialog.module.css";
import { button, div } from "./controls";
import { RadioGroup } from "./controls/itemsControl";

export class Dialog {
private constructor() {}

static show(msg: string, title?: string) {
static show(title: I18nKeys, context: IPropertyChanged, callback: () => void) {
let properties = Property.getProperties(context);
let dialog = document.createElement("dialog");
dialog.style.padding = "0";
dialog.innerHTML = `
<div class="${style.dialog}">
<div class="${style.title}">${title ?? "chili3d"}</div>
<div class="${style.content}">${msg}</div>
<div class="${style.buttons}">
<button class="${style.button}">OK</button>
</div>
</div>
`;
dialog.appendChild(
div(
{ className: style.root },
div({ className: style.title }, I18n.translate(title) ?? "chili3d"),
...properties.map((x) => {
let value = (context as any)[x.name];
if (value instanceof SelectableItems) {
return new RadioGroup(I18n.translate(x.display), value);
}
return "";
}),
div(
{ className: style.buttons },
button({
textContent: I18n.translate("common.confirm"),
onclick: () => {
dialog.close();
callback();
},
}),
button({
textContent: I18n.translate("common.cancel"),
onclick: () => dialog.close(),
}),
),
),
);
document.body.appendChild(dialog);
let button = dialog.querySelector(`.${style.button}`)!;
let handler = () => {
dialog.close();
document.body.removeChild(dialog);
button.removeEventListener("click", handler);
};
button.addEventListener("click", handler);
dialog.showModal();
}
}
2 changes: 2 additions & 0 deletions packages/chili-ui/src/mainWindow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import {
import { Editor } from "./editor";
import { Home } from "./home";
import { Toast } from "./toast";
import { Dialog } from "./dialog";

document.oncontextmenu = (e) => e.preventDefault();

Expand Down Expand Up @@ -58,6 +59,7 @@ export class MainWindow {
this.#vm.onPropertyChanged(this.onPropertyChanged);
this.setHomeDisplay();
PubSub.default.sub("showToast", this.#toast.show);
PubSub.default.sub("showDialog", Dialog.show);
}

private onDocumentClick = (document: RecentDocumentDTO) => {
Expand Down
4 changes: 4 additions & 0 deletions packages/chili-ui/src/profile/ribbon.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,10 @@ export const DefaultRibbon: RibbonData = [
groupName: "ribbon.group.boolean",
items: ["boolean.common", "boolean.cut", "boolean.fuse"],
},
{
groupName: "ribbon.group.workingPlane",
items: ["workingPlane.set", "workingPlane.alignToPlane"],
},
{
groupName: "ribbon.group.importExport",
items: ["file.import", "file.export.iges", "file.export.stp"],
Expand Down
Loading

0 comments on commit 168a63d

Please sign in to comment.