+++ /dev/null
-package ui
-
-use package core
-
-#private_file
-SA_State :: struct {
- transform: gfx.Transform = .{
- translation = .{ 0, 0 },
- scale = .{ 1, 1 },
- };
-
- dragging := false;
-}
-
-#private
-scrollable_area_states : map.Map(UI_Id, SA_State);
-
-scrollable_area_start :: (use r: Rectangle, site := #callsite) {
- hash := get_site_hash(site, 0);
- x, y := Rectangle.top_left(r);
- width, height := Rectangle.dimensions(r);
-
- state := map.get(^scrollable_area_states, hash);
-
- mx, my := get_mouse_position();
- if Rectangle.contains(r, mx, my) {
- if hot_item == 0 do set_hot_item(hash);
- }
-
- if is_hot_item(hash) {
- speed :: 30.0f; @ThemeConfiguration
- scale_speed :: 0.02f; @ThemeConfiguration
-
- if is_key_down(38) do state.transform.translation.y += speed;
- if is_key_down(40) do state.transform.translation.y -= speed;
- if is_key_down(39) do state.transform.translation.x -= speed;
- if is_key_down(37) do state.transform.translation.x += speed;
-
- if is_key_down(187) do zoom(^state, r, 1.02);
- if is_key_down(189) do zoom(^state, r, 0.98);
-
- if mouse_state.left_button_just_down && !state.dragging {
- state.dragging = true;
- }
-
- if state.dragging {
- if !mouse_state.left_button_down {
- state.dragging = false;
-
- } else {
- dx, dy := get_mouse_delta();
- state.transform.translation.x -= dx;
- state.transform.translation.y -= dy;
- }
- }
-
- if mouse_state.dwheel > 0 do zoom(^state, r, 1.04);
- if mouse_state.dwheel < 0 do zoom(^state, r, 0.96);
-
- } else {
- state.dragging = false;
- }
-
- map.put(^scrollable_area_states, hash, state);
-
- gfx.push_scissor(x, y, width, height);
- gfx.push_matrix();
- gfx.apply_transform(state.transform);
-
- zoom :: (state: ^SA_State, r: Rectangle, scale := 1.0f) {
- x, y := Rectangle.top_left(r);
- width, height := Rectangle.dimensions(r);
-
- bx: f32 = (state.transform.translation.x - (width / 2) - x) / state.transform.scale.x;
- by: f32 = (state.transform.translation.y - (height / 2) - y) / state.transform.scale.y;
-
- state.transform.scale.x *= scale;
- state.transform.scale.y *= scale;
-
- state.transform.translation.x = bx * state.transform.scale.x + (width / 2) + x;
- state.transform.translation.y = by * state.transform.scale.y + (height / 2) + y;
- }
-}
-
-scrollable_area_end :: () {
- gfx.pop_scissor();
- gfx.pop_matrix();
-}
\ No newline at end of file
cursor_color := gfx.Color4.{ 0.5, 0.5, 0.5 };
cursor_width := 4.0f; @InPixels
cursor_blink_speed := 0.04f; // Bigger is faster
+
+ placeholder_text_color := gfx.Color4.{ 0.5, 0.5, 0.5 };
}
default_textbox_theme := Textbox_Theme.{};
// There is only one 'Textbox_Editing_State', not a map of them because there can only be one textbox being edited at once.
textbox_editing_state := Textbox_Editing_State.{};
-textbox :: (use r: Rectangle, text_buffer: ^string.String_Buffer, theme := ^default_textbox_theme, site := #callsite, increment := 0) -> bool {
+textbox :: (use r: Rectangle, text_buffer: ^string.String_Buffer, placeholder := null_str, theme := ^default_textbox_theme, site := #callsite, increment := 0) -> bool {
result := false;
hash := get_site_hash(site, increment);
border_width := theme.border_width;
width, height := Rectangle.dimensions(r);
+ text_color := theme.text_color;
text := string.buffer_to_str(text_buffer);
+ if text.count == 0 && placeholder.count > 0 {
+ text = placeholder;
+ text_color = theme.placeholder_text_color;
+ }
text_width := bmfont.get_width(^font, text, theme.font_size);
text_height := bmfont.get_height(^font, text, theme.font_size);
surface_color = color_lerp(animation_state.click_time, surface_color, theme.click_color);
gfx.rect(.{ x0 + border_width, y0 + border_width }, .{ width - border_width * 2, height - border_width * 2 }, surface_color);
- draw_text_raw(text, text_x, text_y, theme.font_size, theme.text_color);
+ draw_text_raw(text, text_x, text_y, theme.font_size, text_color);
if textbox_editing_state.hash == hash {
cursor_x := get_cursor_location(text_buffer, text_x, text_y, theme.font_size, textbox_editing_state.cursor_position);
--- /dev/null
+package ui
+
+use package core
+
+#private_file
+Workspace_State :: struct {
+ transform: gfx.Transform = .{
+ translation = .{ 0, 0 },
+ scale = .{ 1, 1 },
+ };
+
+ dragging := false;
+}
+
+#private
+workspace_states : map.Map(UI_Id, Workspace_State);
+
+workspace_start :: (use r: Rectangle, site := #callsite) {
+ hash := get_site_hash(site, 0);
+ x, y := Rectangle.top_left(r);
+ width, height := Rectangle.dimensions(r);
+
+ state := map.get(^workspace_states, hash);
+
+ mx, my := get_mouse_position();
+ if Rectangle.contains(r, mx, my) {
+ if hot_item == 0 do set_hot_item(hash);
+ }
+
+ if is_hot_item(hash) {
+ speed :: 30.0f; @ThemeConfiguration
+ scale_speed :: 0.02f; @ThemeConfiguration
+
+ if is_key_down(38) do state.transform.translation.y += speed;
+ if is_key_down(40) do state.transform.translation.y -= speed;
+ if is_key_down(39) do state.transform.translation.x -= speed;
+ if is_key_down(37) do state.transform.translation.x += speed;
+
+ if is_key_down(187) do zoom(^state, r, 1.02);
+ if is_key_down(189) do zoom(^state, r, 0.98);
+
+ if mouse_state.left_button_just_down && !state.dragging {
+ state.dragging = true;
+ }
+
+ if state.dragging {
+ if !mouse_state.left_button_down {
+ state.dragging = false;
+
+ } else {
+ dx, dy := get_mouse_delta();
+ state.transform.translation.x -= dx;
+ state.transform.translation.y -= dy;
+ }
+ }
+
+ if mouse_state.dwheel > 0 do zoom(^state, r, 1.04);
+ if mouse_state.dwheel < 0 do zoom(^state, r, 0.96);
+
+ } else {
+ state.dragging = false;
+ }
+
+ map.put(^workspace_states, hash, state);
+
+ gfx.push_scissor(x, y, width, height);
+ gfx.push_matrix();
+ gfx.apply_transform(state.transform);
+
+ zoom :: (state: ^Workspace_State, r: Rectangle, scale := 1.0f) {
+ x, y := Rectangle.top_left(r);
+ width, height := Rectangle.dimensions(r);
+
+ bx: f32 = (state.transform.translation.x - (width / 2) - x) / state.transform.scale.x;
+ by: f32 = (state.transform.translation.y - (height / 2) - y) / state.transform.scale.y;
+
+ state.transform.scale.x *= scale;
+ state.transform.scale.y *= scale;
+
+ state.transform.translation.x = bx * state.transform.scale.x + (width / 2) + x;
+ state.transform.translation.y = by * state.transform.scale.y + (height / 2) + y;
+ }
+}
+
+workspace_end :: () {
+ gfx.pop_scissor();
+ gfx.pop_matrix();
+}
\ No newline at end of file
#load "./components/slider"
#load "./components/radio"
#load "./components/textbox"
-#load "./components/scrollable_area"
+#load "./components/workspace"
// Package inclusions that are part of all files in the "ui" package.
#private gfx :: package immediate_mode // The immediate_mode module needs to be accessible
init_font();
map.init(^animation_states, default=.{}, hash_count=4);
- map.init(^scrollable_area_states, default=.{}, hash_count=4);
+ map.init(^workspace_states, default=.{}, hash_count=4);
}
// This function should be called at the end of drawing a frame, after all of the UI elements