Skip to content

Commit

Permalink
feat(imgui): add theme stack, extract default event handlers
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Aug 15, 2019
1 parent b8d0892 commit b4aee22
Show file tree
Hide file tree
Showing 3 changed files with 80 additions and 52 deletions.
51 changes: 51 additions & 0 deletions packages/imgui/src/events.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { MouseButton } from "./api";
import { IMGUI } from "./gui";

/**
* Injects default mouse & touch event handlers into `gui.attribs` and
* attaches keydown/up listeners to `window`.
*
* This method should only be used if the IMGUI is to be updated via a
* RAF loop or other non-reactive situation. For on-demand updates /
* rendering event handling and IMGUI mouse/key state preparation is
* left to the user.
*
* @see IMGUI.setMouse()
* @see IMGUI.setKey()
*/
export const useDefaultEventHandlers = (gui: IMGUI) => {
const pos = (e: MouseEvent | TouchEvent) => {
const b = (<HTMLCanvasElement>e.target).getBoundingClientRect();
const t = (<TouchEvent>e).changedTouches
? (<TouchEvent>e).changedTouches[0]
: <MouseEvent>e;
return [t.clientX - b.left, t.clientY - b.top];
};
const touchActive = (e: TouchEvent) => {
gui.setMouse(pos(e), MouseButton.LEFT);
};
const touchEnd = (e: TouchEvent) => {
gui.setMouse(pos(e), 0);
};
const mouseActive = (e: MouseEvent) => {
gui.setMouse(pos(e), e.buttons);
};
Object.assign(gui.attribs, {
onmousemove: mouseActive,
onmousedown: mouseActive,
onmouseup: mouseActive,
ontouchstart: touchActive,
ontouchmove: touchActive,
ontouchend: touchEnd,
ontouchcancel: touchEnd
});
window.addEventListener("keydown", (e) => {
gui.setKey(e);
if (e.key === "Tab") {
e.preventDefault();
}
});
window.addEventListener("keyup", (e) => {
gui.setKey(e);
});
};
80 changes: 28 additions & 52 deletions packages/imgui/src/gui.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ import {
} from "./api";

export class IMGUI implements IToHiccup {
theme!: GUITheme;
attribs!: any;
layers: any[];

Expand All @@ -33,6 +32,7 @@ export class IMGUI implements IToHiccup {
protected currIDs: Set<string>;
protected prevIDs: Set<string>;

protected themes!: GUITheme[];
protected resources: Map<string, Map<Hash, any>>;
protected states: Map<string, any>;
protected sizes: Map<string, any>;
Expand All @@ -54,6 +54,11 @@ export class IMGUI implements IToHiccup {
this.t0 = Date.now();
}

get theme() {
const themes = this.themes;
return themes[themes.length - 1];
}

/**
* Sets mouse position and current mouse button flags (i.e.
* `MouseEvent.buttons`).
Expand Down Expand Up @@ -83,12 +88,32 @@ export class IMGUI implements IToHiccup {
}

/**
* Merges given theme settings with existing theme.
* Merges given theme settings with DEFAULT_THEME and resets theme
* stack.
*
* @param theme
*/
setTheme(theme: Partial<GUITheme>) {
this.theme = { ...DEFAULT_THEME, ...theme };
this.themes = [{ ...DEFAULT_THEME, ...theme }];
}

/**
* Merges given theme settings with current theme and pushes it on
* theme stack.
*
* @param theme
*/
pushTheme(theme: Partial<GUITheme>) {
const themes = this.themes;
themes.push({ ...themes[themes.length - 1], ...theme });
}

/**
* Removes current theme from stack (unless only one theme left).
*/
popTheme() {
const themes = this.themes;
themes.length > 1 && themes.pop();
}

/**
Expand Down Expand Up @@ -299,53 +324,4 @@ export class IMGUI implements IToHiccup {
...this.layers[1]
];
}

/**
* Injects default mouse & touch event handlers into `attribs`
* property and attaches keydown/up listeners to `window`.
*
* This method should only be used if the IMGUI is to be updated via
* a RAF loop or other non-reactive situation. For on-demand
* updates/rendering event handling and IMGUI preparation is left to
* the user.
*
* @see IMGUI.setMouse()
* @see IMGUI.setKey()
*/
useDefaultEventHandlers() {
const pos = (e: MouseEvent | TouchEvent) => {
const b = (<HTMLCanvasElement>e.target).getBoundingClientRect();
const t = (<TouchEvent>e).changedTouches
? (<TouchEvent>e).changedTouches[0]
: <MouseEvent>e;
return [t.clientX - b.left, t.clientY - b.top];
};
const touchActive = (e: TouchEvent) => {
this.setMouse(pos(e), MouseButton.LEFT);
};
const touchEnd = (e: TouchEvent) => {
this.setMouse(pos(e), 0);
};
const mouseActive = (e: MouseEvent) => {
this.setMouse(pos(e), e.buttons);
};
Object.assign(this.attribs, {
onmousemove: mouseActive,
onmousedown: mouseActive,
onmouseup: mouseActive,
ontouchstart: touchActive,
ontouchmove: touchActive,
ontouchend: touchEnd,
ontouchcancel: touchEnd
});
window.addEventListener("keydown", (e) => {
this.setKey(e);
if (e.key === "Tab") {
e.preventDefault();
}
});
window.addEventListener("keyup", (e) => {
this.setKey(e);
});
}
}
1 change: 1 addition & 0 deletions packages/imgui/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
export * from "./api";
export * from "./events";
export * from "./gui";
export * from "./layout";

Expand Down

0 comments on commit b4aee22

Please sign in to comment.