Skip to content

Commit 02aa23a

Browse files
gluaxspeeda7ul
andauthored
MenuBar and Menu Componenets (#128)
* MenuBar and Menu components * Tried to add Systray but its a NodeObject * fixes conflicts Co-authored-by: Atul R <atulanand94@gmail.com>
1 parent 8199778 commit 02aa23a

File tree

10 files changed

+1941
-392
lines changed

10 files changed

+1941
-392
lines changed

package-lock.json

Lines changed: 121 additions & 342 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,17 +22,15 @@
2222
"dependencies": {
2323
"@types/react-reconciler": "^0.18.0",
2424
"phin": "^3.4.1",
25+
"@nodegui/nodegui": ">=0.22.0",
2526
"react-deep-force-update": "^2.1.3",
2627
"react-proxy": "^2.0.8",
2728
"react-reconciler": "^0.25.1"
2829
},
2930
"peerDependencies": {
30-
"@nodegui/nodegui": ">=0.17.0",
31-
"@nodegui/qode": "*",
3231
"react": "^16.9.0"
3332
},
3433
"devDependencies": {
35-
"@nodegui/nodegui": "^0.22.0",
3634
"@types/node": "^14.0.12",
3735
"prettier": "^2.0.5",
3836
"react": "^16.13.1",

src/components/Menu/RNMenu.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import { NodeWidget, QAction, QMenu, QMenuSignals } from "@nodegui/nodegui";
2+
import { ViewProps, setViewProps } from "../View/RNView";
3+
import { RNWidget } from "../config";
4+
import { throwUnsupported } from "../../utils/helpers";
5+
6+
export interface MenuProps extends ViewProps<QMenuSignals> {
7+
title?: string;
8+
actions?: QAction[];
9+
}
10+
11+
const setMenuProps = (
12+
widget: RNMenu,
13+
newProps: MenuProps,
14+
oldProps: MenuProps
15+
) => {
16+
const setter: MenuProps = {
17+
set title(title: string) {
18+
widget.setTitle(title);
19+
},
20+
set actions(actions: QAction[]) {
21+
actions.forEach(action => {
22+
widget.addAction(action);
23+
});
24+
}
25+
};
26+
Object.assign(setter, newProps);
27+
setViewProps(widget, newProps, oldProps);
28+
};
29+
30+
export class RNMenu extends QMenu implements RNWidget {
31+
setProps(newProps: MenuProps, oldProps: MenuProps): void {
32+
setMenuProps(this, newProps, oldProps);
33+
}
34+
appendInitialChild(child: NodeWidget<any>): void {
35+
throwUnsupported(this);
36+
}
37+
appendChild(child: NodeWidget<any>): void {
38+
throwUnsupported(this);
39+
}
40+
insertBefore(child: NodeWidget<any>, beforeChild: NodeWidget<any>): void {
41+
throwUnsupported(this);
42+
}
43+
removeChild(child: NodeWidget<any>): void {
44+
throwUnsupported(this);
45+
}
46+
static tagName = "menu";
47+
};

src/components/Menu/index.ts

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import { Fiber } from "react-reconciler";
2+
import { registerComponent, ComponentConfig } from "../config";
3+
import { RNMenu, MenuProps } from "./RNMenu";
4+
import { AppContainer } from "../../reconciler";
5+
class MenuConfig extends ComponentConfig {
6+
7+
tagName = RNMenu.tagName;
8+
shouldSetTextContent(nextProps: MenuProps): boolean {
9+
return false;
10+
}
11+
createInstance(
12+
newProps: MenuProps,
13+
rootInstance: AppContainer,
14+
context: any,
15+
workInProgress: Fiber
16+
): RNMenu {
17+
const widget = new RNMenu();
18+
widget.setProps(newProps, {});
19+
return widget;
20+
}
21+
commitMount(
22+
instance: RNMenu,
23+
newProps: MenuProps,
24+
internalInstanceHandle: any
25+
): void {
26+
if (newProps.visible !== false) {
27+
instance.show();
28+
}
29+
return;
30+
}
31+
commitUpdate(
32+
instance: RNMenu,
33+
updatePayload: any,
34+
oldProps: MenuProps,
35+
newProps: MenuProps,
36+
finishedWork: Fiber
37+
): void {
38+
instance.setProps(newProps, oldProps);
39+
}
40+
}
41+
42+
export const Menu = registerComponent<MenuProps>(
43+
new MenuConfig()
44+
);

src/components/MenuBar/RNMenuBar.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { NodeWidget, QMenu, QMenuBar, QMenuBarSignals } from "@nodegui/nodegui";
2+
import { ViewProps, setViewProps } from "../View/RNView";
3+
import { RNWidget } from "../config";
4+
import { throwUnsupported } from "../../utils/helpers";
5+
6+
export interface MenuBarProps extends ViewProps<QMenuBarSignals> {
7+
nativeMenuBar?: boolean;
8+
}
9+
10+
const setMenuBarProps = (
11+
widget: RNMenuBar,
12+
newProps: MenuBarProps,
13+
oldProps: MenuBarProps
14+
) => {
15+
const setter: MenuBarProps = {
16+
set nativeMenuBar(shouldBeNative: boolean) {
17+
widget.setNativeMenuBar(shouldBeNative);
18+
},
19+
};
20+
Object.assign(setter, newProps);
21+
setViewProps(widget, newProps, oldProps);
22+
};
23+
24+
export class RNMenuBar extends QMenuBar implements RNWidget {
25+
setProps(newProps: MenuBarProps, oldProps: MenuBarProps): void {
26+
setMenuBarProps(this, newProps, oldProps);
27+
}
28+
appendInitialChild(child: QMenu): void {
29+
if (child instanceof QMenu) {
30+
this.addMenu(child);
31+
} else {
32+
console.warn("MenuBar only supports Menu as its children");
33+
}
34+
}
35+
appendChild(child: QMenu): void {
36+
this.appendInitialChild(child);
37+
}
38+
insertBefore(child: NodeWidget<any>, beforeChild: NodeWidget<any>): void {
39+
console.warn(
40+
"Updating menubar is not yet supported. Please help by raising a PR"
41+
);
42+
throwUnsupported(this);
43+
}
44+
removeChild(child: NodeWidget<any>): void {
45+
console.warn(
46+
"Updating menubar is not yet supported. Please help by raising a PR"
47+
);
48+
throwUnsupported(this);
49+
}
50+
static tagName = "menubar";
51+
}

src/components/MenuBar/index.ts

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { Fiber } from "react-reconciler";
2+
import { registerComponent, ComponentConfig } from "../config";
3+
import { RNMenuBar, MenuBarProps } from "./RNMenuBar";
4+
import { AppContainer } from "../../reconciler";
5+
6+
class MenuBarConfig extends ComponentConfig {
7+
tagName = RNMenuBar.tagName;
8+
shouldSetTextContent(nextProps: MenuBarProps): boolean {
9+
return false;
10+
}
11+
createInstance(
12+
newProps: MenuBarProps,
13+
rootInstance: AppContainer,
14+
context: any,
15+
workInProgress: Fiber
16+
): RNMenuBar {
17+
const widget = new RNMenuBar();
18+
widget.setProps(newProps, {});
19+
return widget;
20+
}
21+
commitMount(
22+
instance: RNMenuBar,
23+
newProps: MenuBarProps,
24+
internalInstanceHandle: any
25+
): void {
26+
if (newProps.visible !== false) {
27+
instance.show();
28+
}
29+
return;
30+
}
31+
commitUpdate(
32+
instance: RNMenuBar,
33+
updatePayload: any,
34+
oldProps: MenuBarProps,
35+
newProps: MenuBarProps,
36+
finishedWork: Fiber
37+
): void {
38+
instance.setProps(newProps, oldProps);
39+
}
40+
}
41+
42+
export const MenuBar = registerComponent<MenuBarProps>(new MenuBarConfig());

src/components/Window/RNWindow.ts

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,26 @@
1-
import { QMainWindow, NodeWidget, QMainWindowSignals } from "@nodegui/nodegui";
1+
import {
2+
QMainWindow,
3+
NodeWidget,
4+
QMainWindowSignals,
5+
QMenuBar,
6+
} from "@nodegui/nodegui";
27
import { setViewProps, ViewProps } from "../View/RNView";
38
import { RNWidget } from "../config";
49

5-
export interface WindowProps extends ViewProps<QMainWindowSignals> {}
10+
export interface WindowProps extends ViewProps<QMainWindowSignals> {
11+
menuBar?: QMenuBar;
12+
}
613

714
const setWindowProps = (
815
window: RNWindow,
916
newProps: WindowProps,
1017
oldProps: WindowProps
1118
) => {
1219
const setter: WindowProps = {
13-
// TODO add more props
20+
set menuBar(menubar: QMenuBar) {
21+
window.setMenuBar(menubar);
22+
console.log("menubar was set");
23+
},
1424
};
1525
Object.assign(setter, newProps);
1626
setViewProps(window, newProps, oldProps);
@@ -30,12 +40,21 @@ export class RNWindow extends QMainWindow implements RNWidget {
3040
}
3141
child.close();
3242
}
33-
appendInitialChild(child: NodeWidget<any>): void {
34-
if (this.centralWidget) {
35-
console.warn("MainWindow can't have more than one child node");
43+
appendInitialChild(child: NodeWidget<any> | QMenuBar): void {
44+
if (child instanceof QMenuBar) {
45+
if (!this.menuBar()) {
46+
this.setMenuBar(child);
47+
} else {
48+
console.warn("MainWindow can't have more than one menubar.");
49+
}
3650
return;
3751
}
38-
this.setCentralWidget(child);
52+
53+
if (!this.centralWidget) {
54+
this.setCentralWidget(child);
55+
} else {
56+
console.warn("MainWindow can't have more than one child node");
57+
}
3958
}
4059
appendChild(child: NodeWidget<any>): void {
4160
this.appendInitialChild(child);

src/demo.tsx

Lines changed: 21 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,50 +1,31 @@
1-
import React, { useState } from "react";
2-
import { Renderer, Window, Button } from "./index";
3-
import { BoxView } from "./components/BoxView";
4-
import { useEventHandler } from "./hooks";
5-
import { QPushButtonSignals, Direction } from "@nodegui/nodegui";
1+
import React from "react";
2+
import { Renderer, Window, MenuBar, Menu } from "./index";
3+
import { QAction, QApplication } from "@nodegui/nodegui";
64

7-
const App = () => {
8-
const [additionalButtons, setAdditionalButtons] = useState<string[]>([]);
9-
const [direction, setDirection] = useState<Direction>(Direction.LeftToRight);
5+
const quitAction = new QAction();
6+
quitAction.setText("Quit");
7+
quitAction.addEventListener("triggered", () => {
8+
const app = QApplication.instance();
9+
app.exit(0);
10+
});
1011

11-
const addHandler = useEventHandler<QPushButtonSignals>(
12-
{
13-
clicked: () =>
14-
setAdditionalButtons((buttons) => [
15-
...buttons,
16-
`Button ${buttons.length}`,
17-
]),
18-
},
19-
[]
20-
);
12+
const fileActions: QAction[] = [quitAction];
2113

22-
const removeHandler = useEventHandler<QPushButtonSignals>(
23-
{
24-
clicked: () =>
25-
setAdditionalButtons((buttons) => buttons.slice(0, buttons.length - 1)),
26-
},
27-
[]
28-
);
14+
const sayHi = new QAction();
15+
sayHi.setText("Hello");
16+
sayHi.addEventListener("triggered", () => {
17+
console.log("hello");
18+
});
2919

30-
const toggleDirection = useEventHandler<QPushButtonSignals>(
31-
{
32-
clicked: () =>
33-
setDirection((prevDirection) => ((prevDirection + 1) % 4) as Direction),
34-
},
35-
[]
36-
);
20+
const randActions: QAction[] = [sayHi];
3721

22+
const App = () => {
3823
return (
3924
<Window>
40-
<BoxView direction={direction}>
41-
<Button text="Add" on={addHandler} />
42-
<Button text="Remove" on={removeHandler} />
43-
<Button text="Toggle direction" on={toggleDirection} />
44-
{additionalButtons.map((button) => (
45-
<Button key={button} text={button} />
46-
))}
47-
</BoxView>
25+
<MenuBar>
26+
<Menu title={"File"} actions={fileActions} />
27+
<Menu title={"Random"} actions={randActions} />
28+
</MenuBar>
4829
</Window>
4930
);
5031
};

src/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ export { AnimatedImage } from "./components/AnimatedImage";
88
export { Button } from "./components/Button";
99
export { CheckBox } from "./components/CheckBox";
1010
export { LineEdit } from "./components/LineEdit";
11+
export { Menu } from "./components/Menu";
12+
export { MenuBar } from "./components/MenuBar";
1113
export { PlainTextEdit } from "./components/PlainTextEdit";
1214
export { ProgressBar } from "./components/ProgressBar";
1315
export { RadioButton } from "./components/RadioButton";

0 commit comments

Comments
 (0)