diff --git a/Cargo.lock b/Cargo.lock
index 92331f52..b6ffa22f 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -95,6 +95,26 @@ dependencies = [
"libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "clipboard"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "clipboard-win 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "x11-clipboard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "clipboard-win"
+version = "2.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "cloudabi"
version = "0.0.3"
@@ -189,6 +209,7 @@ dependencies = [
name = "example_glium"
version = "0.1.0"
dependencies = [
+ "clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"emigui 0.1.0",
"emigui_glium 0.1.0",
"glium 0.24.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -436,6 +457,24 @@ dependencies = [
"malloc_buf 0.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "objc-foundation"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "block 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "objc_id"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "ordered-float"
version = "1.0.2"
@@ -915,6 +954,14 @@ dependencies = [
"x11-dl 2.18.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "x11-clipboard"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "x11-dl"
version = "2.18.5"
@@ -926,6 +973,15 @@ dependencies = [
"pkg-config 0.3.17 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "xcb"
+version = "0.8.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "xdg"
version = "2.2.0"
@@ -951,6 +1007,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum cc 1.0.52 (registry+https://github.com/rust-lang/crates.io-index)" = "c3d87b23d6a92cd03af510a5ade527033f6aa6fa92161e2d5863a907d4c5e31d"
"checksum cfg-if 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822"
"checksum cgl 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "55e7ec0b74fe5897894cbc207092c577e87c52f8a59e8ca8d97ef37551f60a49"
+"checksum clipboard 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "25a904646c0340239dcf7c51677b33928bf24fdf424b79a57909c0109075b2e7"
+"checksum clipboard-win 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e3a093d6fed558e5fe24c3dfc85a68bb68f1c824f440d3ba5aca189e2998786b"
"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
"checksum cocoa 0.18.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1706996401131526e36b3b49f0c4d912639ce110996f3ca144d78946727bce54"
"checksum core-foundation 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "25b9e03f145fd4f2bf705e07b900cd41fc636598fe5dc452fd0db1441c3f496d"
@@ -985,6 +1043,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum nix 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "6c722bee1037d430d0f8e687bbdbf222f27cc6e4e68d5caf630857bb2b6dbdce"
"checksum num-traits 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "c62be47e61d1842b9170f0fdeec8eba98e60e90e5446449a0545e5152acd7096"
"checksum objc 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1"
+"checksum objc-foundation 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1add1b659e36c9607c7aab864a76c7a4c2760cd0cd2e120f3fb8b952c7e22bf9"
+"checksum objc_id 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c92d4ddb4bd7b50d730c215ff871754d0da6b2178849f8a2a2ab69712d0c073b"
"checksum ordered-float 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "18869315e81473c951eb56ad5558bbc56978562d3ecfb87abb7a1e944cea4518"
"checksum osmesa-sys 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88cfece6e95d2e717e0872a7f53a8684712ad13822a7979bc760b9c77ec0013b"
"checksum parking_lot 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a704eb390aafdc107b0e392f56a82b668e3a71366993b5340f5833fd62505e"
@@ -1041,6 +1101,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
"checksum winapi-util 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum winit 0.19.5 (registry+https://github.com/rust-lang/crates.io-index)" = "1e96eb4bb472fa43e718e8fa4aef82f86cd9deac9483a1e1529230babdb394a8"
+"checksum x11-clipboard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "89bd49c06c9eb5d98e6ba6536cf64ac9f7ee3a009b2f53996d405b3944f6bcea"
"checksum x11-dl 2.18.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2bf981e3a5b3301209754218f962052d4d9ee97e478f4d26d4a6eced34c1fef8"
+"checksum xcb 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5e917a3f24142e9ff8be2414e36c649d47d6cc2ba81f16201cdef96e533e02de"
"checksum xdg 2.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d089681aa106a86fade1b0128fb5daf07d5867a509ab036d99988dec80429a57"
"checksum xml-rs 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2bb76e5c421bbbeb8924c60c030331b345555024d56261dae8f3e786ed817c23"
diff --git a/README.md b/README.md
index e2b300ff..23dabb03 100644
--- a/README.md
+++ b/README.md
@@ -4,9 +4,11 @@
An immediate mode GUI library written in Rust. For web apps or native apps.
## Goals:
-* Easy to use
+* Lightweight
+* Short, conveniant syntax
+* Responsive (60 Hz without breaking a sweat)
+* Portable
* Platform independent (the same code works on the web and as a native app)
-* Responsive
## How it works:
Loop:
diff --git a/docs/index.html b/docs/index.html
index 9a4070ad..6ef4633e 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -86,6 +86,7 @@
var g_is_touch = false; // we don't know yet
var g_scroll_delta_x = 0;
var g_scroll_delta_y = 0;
+ var g_events = [];
function pixels_per_point() {
return window.devicePixelRatio || 1.0;
@@ -106,9 +107,11 @@
screen_size: { x: window.innerWidth, y: window.innerHeight },
pixels_per_point: pixels_per_point(),
time: window.performance.now() / 1000.0,
+ events: g_events,
};
g_scroll_delta_x = 0;
g_scroll_delta_y = 0;
+ g_events = [];
return input;
}
@@ -210,6 +213,37 @@
event.preventDefault();
});
+ document.addEventListener("keydown", function (event) {
+ console.log(`keydown: '${event.key}'`);
+ var key = translate_key(event.key);
+ if (key) {
+ g_events.push({ "key": { "key": key, 'pressed': true } });
+ } else {
+ g_events.push({ "text": event.key });
+ }
+ invalidate();
+ event.stopPropagation();
+ event.preventDefault();
+ });
+
+ // document.addEventListener("keypress", function (event) {
+ // console.log(`keypress: ${event.key} ${JSON.stringify(event)}`);
+ // invalidate();
+ // event.stopPropagation();
+ // event.preventDefault();
+ // });
+
+ document.addEventListener("keyup", function (event) {
+ // console.log(`keyup: ${event.key} ${JSON.stringify(event)}`);
+ var key = translate_key(event.key);
+ if (key) {
+ g_events.push({ "key": { "key": key, 'pressed': false } });
+ }
+ invalidate();
+ event.stopPropagation();
+ event.preventDefault();
+ });
+
if (!ANIMATION_FRAME) {
window.addEventListener("load", invalidate);
window.addEventListener("pagehide", invalidate);
@@ -219,6 +253,29 @@
paint_and_schedule();
}
+
+ function translate_key(key) {
+ if (key == "Alt") { return "alt"; }
+ if (key == "Backspace") { return "backspace"; }
+ if (key == "Control") { return "control"; }
+ if (key == "Delete") { return "delete"; }
+ if (key == "ArrowDown") { return "down"; }
+ if (key == "End") { return "end"; }
+ if (key == "Escape") { return "escape"; }
+ if (key == "Home") { return "home"; }
+ if (key == "Help") { return "insert"; }
+ if (key == "ArrowLeft") { return "left"; }
+ if (key == "Meta") { return "logo"; }
+ if (key == "PageDown") { return "page_down"; }
+ if (key == "PageUp") { return "page_up"; }
+ if (key == "Enter") { return "return"; }
+ if (key == "ArrowRight") { return "right"; }
+ if (key == "Shift") { return "shift"; }
+ // if (key == " ") { return "space"; }
+ if (key == "Tab") { return "tab"; }
+ if (key == "ArrowUp") { return "up"; }
+ return null;
+ }
diff --git a/emigui/README.md b/emigui/README.md
index 99a70280..0a9fe6fb 100644
--- a/emigui/README.md
+++ b/emigui/README.md
@@ -22,8 +22,14 @@ This is the core library crate Emigui. It is fully platform independent without
* [ ] Kinetic scrolling
* [x] Add support for clicking links
* [ ] Menu bar (File, Edit, etc)
-* [ ] One-line TextField
+* [ ] Text input
+ * [x] Input events (key presses)
+ * [x] Text focus
+ * [ ] Cursor movement
+ * [ ] Text selection
* [ ] Clipboard copy/paste
+ * [ ] Move focus with tab
+ * [ ] Handle leading/trailing space
* [ ] Color picker
* [ ] Style editor
* [ ] Table with resizable columns
@@ -45,6 +51,7 @@ Add extremely quick animations for some things, maybe 2-3 frames. For instance:
* [x] Use clip rectangles when painting
* [x] Use clip rectangles when interacting
* [x] Adjust clip rects so edges of child widgets aren't clipped
+* [ ] Use HW clip rects
### Modularity
* [x] `trait Widget` (`Label`, `Slider`, `Checkbox`, ...)
diff --git a/emigui/src/emigui.rs b/emigui/src/emigui.rs
index 9bd33ebd..2e4ae935 100644
--- a/emigui/src/emigui.rs
+++ b/emigui/src/emigui.rs
@@ -149,15 +149,16 @@ fn font_definitions_ui(font_definitions: &mut FontDefinitions, region: &mut Regi
impl RawInput {
pub fn ui(&self, region: &mut Region) {
// TODO: simpler way to show values, e.g. `region.value("Mouse Pos:", self.mouse_pos);
+ // TODO: easily change default font!
region.add(label!("mouse_down: {}", self.mouse_down));
region.add(label!("mouse_pos: {:.1?}", self.mouse_pos));
region.add(label!("scroll_delta: {:?}", self.scroll_delta));
region.add(label!("screen_size: {:?}", self.screen_size));
region.add(label!("pixels_per_point: {}", self.pixels_per_point));
region.add(label!("time: {:.3} s", self.time));
- region.add(label!("text: {:?}", self.text));
- // region.add(label!("dropped_files: {}", self.dropped_files));
- // region.add(label!("hovered_files: {}", self.hovered_files));
+ region.add(label!("events: {:?}", self.events));
+ region.add(label!("dropped_files: {:?}", self.dropped_files));
+ region.add(label!("hovered_files: {:?}", self.hovered_files));
}
}
@@ -172,8 +173,8 @@ impl GuiInput {
region.add(label!("screen_size: {:?}", self.screen_size));
region.add(label!("pixels_per_point: {}", self.pixels_per_point));
region.add(label!("time: {}", self.time));
- region.add(label!("text: {:?}", self.text));
- // region.add(label!("dropped_files: {}", self.dropped_files));
- // region.add(label!("hovered_files: {}", self.hovered_files));
+ region.add(label!("events: {:?}", self.events));
+ region.add(label!("dropped_files: {:?}", self.dropped_files));
+ region.add(label!("hovered_files: {:?}", self.hovered_files));
}
}
diff --git a/emigui/src/example_app.rs b/emigui/src/example_app.rs
index d1151ff8..d738af36 100644
--- a/emigui/src/example_app.rs
+++ b/emigui/src/example_app.rs
@@ -5,6 +5,7 @@ pub struct ExampleApp {
checked: bool,
count: usize,
radio: usize,
+ text_inputs: [String; 3],
size: Vec2,
corner_radius: f32,
@@ -24,6 +25,8 @@ impl Default for ExampleApp {
checked: true,
radio: 0,
count: 0,
+ text_inputs: Default::default(),
+
size: vec2(100.0, 50.0),
corner_radius: 5.0,
stroke_width: 2.0,
@@ -52,7 +55,7 @@ impl ExampleApp {
});
CollapsingHeader::new("Widgets")
- // .default_open()
+ .default_open()
.show(region, |region| {
region.horizontal(Align::Min, |region| {
region.add(label!("Text can have").text_color(srgba(110, 255, 110, 255)));
@@ -94,6 +97,13 @@ impl ExampleApp {
if region.add(Button::new("Double it")).clicked {
self.slider_value *= 2;
}
+
+ for (i, text) in self.text_inputs.iter_mut().enumerate() {
+ region.horizontal(Align::Min, |region|{
+ region.add(label!("Text input {}: ", i));
+ region.add(TextEdit::new(text).id(i));
+ }); // TODO: .tooltip_text("Enter text to edit me")
+ }
});
region.collapsing("Layouts", |region| {
@@ -151,7 +161,7 @@ impl ExampleApp {
.show(region, |region| self.painting.ui(region));
CollapsingHeader::new("Resize")
- .default_open()
+ // .default_open()
.show(region, |region| {
Resize::default()
.default_height(200.0)
diff --git a/emigui/src/lib.rs b/emigui/src/lib.rs
index 77d60295..c3738bd9 100644
--- a/emigui/src/lib.rs
+++ b/emigui/src/lib.rs
@@ -40,4 +40,5 @@ pub use {
style::Style,
texture_atlas::Texture,
types::*,
+ widgets::Widget,
};
diff --git a/emigui/src/memory.rs b/emigui/src/memory.rs
index d05211ef..4304302f 100644
--- a/emigui/src/memory.rs
+++ b/emigui/src/memory.rs
@@ -10,6 +10,9 @@ pub struct Memory {
/// The widget being interacted with (e.g. dragged, in case of a slider).
pub(crate) active_id: Option,
+ /// The widget with keyboard focus (i.e. a text input field).
+ pub(crate) kb_focus_id: Option,
+
// states of various types of widgets
pub(crate) collapsing_headers: HashMap,
pub(crate) scroll_areas: HashMap,
diff --git a/emigui/src/region.rs b/emigui/src/region.rs
index fbc6ca85..26b9835e 100644
--- a/emigui/src/region.rs
+++ b/emigui/src/region.rs
@@ -143,6 +143,10 @@ impl Region {
self.ctx.memory.lock()
}
+ pub fn output(&self) -> parking_lot::MutexGuard