Skip to content

Commit

Permalink
feat(examples): add imgui-basics example
Browse files Browse the repository at this point in the history
  • Loading branch information
postspectacular committed Aug 15, 2020
1 parent 8a7420e commit b2f87de
Show file tree
Hide file tree
Showing 8 changed files with 266 additions and 0 deletions.
8 changes: 8 additions & 0 deletions examples/imgui-basics/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
.cache
out
node_modules
yarn.lock
*.js
*.map
!src/*.d.ts
!*.config.js
13 changes: 13 additions & 0 deletions examples/imgui-basics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# imgui-basics

[Live demo](http://demo.thi.ng/umbrella/imgui-basics/)

Please refer to the [example build instructions](https://github.com/thi-ng/umbrella/wiki/Example-build-instructions) on the wiki.

## Authors

- Karsten Schmidt

## License

© 2020 Karsten Schmidt // Apache Software License 2.0
29 changes: 29 additions & 0 deletions examples/imgui-basics/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html;charset=UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>imgui-basics</title>
<link
href="https://unpkg.com/tachyons@4/css/tachyons.min.css"
rel="stylesheet"
/>
<link
href="https://fonts.googleapis.com/css?family=IBM+Plex+Mono&display=swap"
rel="stylesheet"
/>
<style></style>
</head>
<body class="sans-serif">
<div id="app"></div>
<div class="fixed bottom-0 left-0 z1 pa3">
<a
class="link"
href="https://github.com/thi-ng/umbrella/tree/develop/examples/imgui-basics"
>Source code</a
>
</div>
<script type="text/javascript" src="./src/index.ts"></script>
</body>
</html>
41 changes: 41 additions & 0 deletions examples/imgui-basics/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
{
"name": "imgui-basics",
"version": "0.0.1",
"description": "Minimal IMGUI usage example",
"repository": "https://github.com/thi-ng/umbrella",
"author": "Karsten Schmidt <[email protected]>",
"license": "Apache-2.0",
"scripts": {
"clean": "rm -rf .cache build out",
"build": "yarn clean && parcel build index.html -d out --public-url ./ --no-source-maps --no-cache --detailed-report --experimental-scope-hoisting",
"build:webpack": "../../node_modules/.bin/webpack --mode production",
"start": "parcel index.html -p 8080 --open --no-cache"
},
"devDependencies": {
"parcel-bundler": "^1.12.4",
"terser": "^4.8.0",
"typescript": "^3.9.5"
},
"dependencies": {
"@thi.ng/hdom": "latest",
"@thi.ng/hdom-canvas": "latest",
"@thi.ng/imgui": "latest",
"@thi.ng/layout": "latest",
"@thi.ng/rstream": "latest",
"@thi.ng/rstream-gestures": "latest"
},
"browserslist": [
"last 3 Chrome versions"
],
"browser": {
"process": false
},
"thi.ng": {
"readme": [
"imgui",
"layout",
"rstream-gestures"
],
"screenshot": "examples/imgui-basics.png"
}
}
137 changes: 137 additions & 0 deletions examples/imgui-basics/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
import { start } from "@thi.ng/hdom";
import { canvas } from "@thi.ng/hdom-canvas";
import { buttonH, DEFAULT_THEME, IMGUI, Key, sliderH } from "@thi.ng/imgui";
import { gridLayout } from "@thi.ng/layout";
import { fromDOMEvent, reactive, tweenNumber } from "@thi.ng/rstream";
import { gestureStream } from "@thi.ng/rstream-gestures";

// GUI initialization
const gui = new IMGUI({
theme: {
...DEFAULT_THEME,
font: "16px 'IBM Plex Mono', monospace",
baseLine: 6,
focus: "#000",
},
});

// hdom-canvas component specialization
// use init lifecycle method to create/attach event listeners
// and feed relevant details to IMGUI
const _canvas = {
...canvas,
init: (el: HTMLCanvasElement) => {
// unified mouse & touch event handling
gestureStream(el, {}).subscribe({
next: (e) => gui.setMouse(e.pos, e.buttons),
});
// key events are only required to make IMGUI components more accessible
// and keyboard controllable.
// Important: key events CANNOT ever be attached to a canvas itself...
fromDOMEvent(window, "keydown").subscribe({
next(e) {
if (e.target !== document.body) return;
if (
e.key === Key.TAB ||
e.key === Key.SPACE ||
e.key === Key.UP ||
e.key === Key.DOWN
) {
e.preventDefault();
}
gui.setKey(e);
},
});
fromDOMEvent(window, "keyup").subscribe({
next(e) {
gui.setKey(e);
},
});
},
};

// dummy app state details (using https://thi.ng/rstream)

const PRESETS = <const>[
["Mute", 0, 0],
["Quiet", 1, 25],
["Medium", 33, 50],
["Party", 66, 75],
];

// initial volume state
const volume = reactive(55);

// interpolated version of volume
const smoothedVolume = tweenNumber(volume, 0, 0.2);

// derived view for slider label
const volumeLabel = smoothedVolume.map((x) => {
for (let i = PRESETS.length; --i >= 0; ) {
if (x >= PRESETS[i][1]) return `${Math.round(x)} (${PRESETS[i][0]})`;
}
return "";
});

// hdom update loop
start(() => {
let res: any;
// create grid layout using https://thi.ng/layout
// position grid centered in window
const grid = gridLayout(
16,
(window.innerHeight - 68) / 2,
window.innerWidth - 32,
1,
32,
4
);

// prep GUI for next frame
gui.begin();

// volume slider component
// returns a number (new value) if user interacted w/ slider
res = sliderH(
gui,
grid,
"vol",
0,
100,
1,
smoothedVolume.deref()!,
`Volume: ${volumeLabel.deref()!}`,
() => ""
);
// update state if needed
res !== undefined && volume.next(res);

// create nested inner grid layout
let inner = grid.nest(PRESETS.length);
// create button for each volume preset
// and update state if a button was pressed
for (let preset of PRESETS) {
res = buttonH(gui, inner, `bt${preset[0]}`, preset[0]);
res && volume.next(preset[2]);
}

// end frame
gui.end();

// return main/only component (see definition further above)
// the `gui` itself implements the `IToHiccup` interface and therefore
// can just be provided as canvas body
// (you can also provide other hiccup-canvas shapes/content here)
return [
_canvas,
{
// disable hdom diffing for canvas children
__diff: false,
width: window.innerWidth,
height: window.innerHeight,
style: { background: gui.theme.globalBg, cursor: gui.cursor },
...gui.attribs,
},
gui,
];
});
4 changes: 4 additions & 0 deletions examples/imgui-basics/src/webpack.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module "*.jpg";
declare module "*.png";
declare module "*.svg";
declare module "*.json";
11 changes: 11 additions & 0 deletions examples/imgui-basics/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
{
"extends": "../../tsconfig.json",
"compilerOptions": {
"outDir": ".",
"target": "es6",
"sourceMap": true
},
"include": [
"./src/**/*.ts"
]
}
23 changes: 23 additions & 0 deletions examples/imgui-basics/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
module.exports = {
entry: "./src/index.ts",
output: {
filename: "bundle.[hash].js",
path: __dirname + "/out"
},
resolve: {
extensions: [".ts", ".js"]
},
module: {
rules: [
{
test: /\.(png|jpg|gif)$/,
loader: "file-loader",
options: { name: "[path][hash].[ext]" }
},
{ test: /\.ts$/, use: "ts-loader" }
]
},
node: {
process: false
}
};

0 comments on commit b2f87de

Please sign in to comment.