add implementations of floating windows
This commit is contained in:
		| @@ -2,49 +2,42 @@ const std    = @import("std"); | ||||
| const dvui   = @import("dvui"); | ||||
| const hncore = @import("hncore"); | ||||
|  | ||||
| const win = @import("./win/root.zig"); | ||||
| const compo = @import("./compo/root.zig"); | ||||
|  | ||||
| const Self = @This(); | ||||
|  | ||||
| alloc: std.mem.Allocator, | ||||
| today: win.today.Mock, | ||||
| stage: compo.stage.Mock, | ||||
| search: compo.search.Mock, | ||||
| taskedit: compo.taskedit.Mock, | ||||
|  | ||||
| pub fn init(alloc: std.mem.Allocator) !Self { | ||||
|     return Self { | ||||
|         .alloc = alloc, | ||||
|         .today = try win.today.Mock.init(alloc), | ||||
|         .search   = try compo.search.Mock.init(alloc), | ||||
|         .stage    = try compo.stage.Mock.init(alloc), | ||||
|         .taskedit = try compo.taskedit.Mock.init(alloc), | ||||
|     }; | ||||
| } | ||||
| pub fn deinit(self: *Self) void { | ||||
|     self.today.deinit(); | ||||
|     self.taskedit.deinit(); | ||||
|     self.stage.deinit(); | ||||
|     self.search.deinit(); | ||||
| } | ||||
|  | ||||
| pub fn gui(self: *Self) !void { | ||||
|     // ---- menu | ||||
|     try compo.menu.gui(.{}); | ||||
|  | ||||
|     // background | ||||
|     { | ||||
|         var root = try dvui.menu(@src(), .horizontal, .{ .background = true, .expand = .horizontal }); | ||||
|         defer root.deinit(); | ||||
|  | ||||
|         if (try dvui.menuItemLabel(@src(), "File", .{ .submenu = true }, .{})) |r| { | ||||
|             var float = try dvui.floatingMenu( | ||||
|                 @src(), .{.from = dvui.Rect.fromPoint(dvui.Point{ .x = r.x, .y = r.y + r.h })}, .{}); | ||||
|             defer float.deinit(); | ||||
|  | ||||
|             if (try dvui.menuItemLabel(@src(), "Open", .{}, .{})) |_| { | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // ---- project tabs | ||||
|     { | ||||
|         var tbox = try dvui.box(@src(), .vertical, .{ | ||||
|         var box = try dvui.box(@src(), .vertical, .{ | ||||
|             .expand = .both, | ||||
|             .background = true, | ||||
|             .color_fill = .{ .name = .fill_window }, | ||||
|             .color_fill = .{ .color = dvui.Color.white, }, | ||||
|         }); | ||||
|         defer tbox.deinit(); | ||||
|         defer box.deinit(); | ||||
|     } | ||||
|  | ||||
|     // ---- windows | ||||
|     try win.today.gui(&self.today); | ||||
|     try compo.search.gui(&self.search); | ||||
|     try compo.stage.gui(&self.stage); | ||||
|     try compo.taskedit.gui(&self.taskedit); | ||||
| } | ||||
|   | ||||
							
								
								
									
										36
									
								
								src/heavens-net/compo/menu.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								src/heavens-net/compo/menu.zig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,36 @@ | ||||
| const std  = @import("std"); | ||||
| const dvui = @import("dvui"); | ||||
|  | ||||
| pub fn gui(ctx: anytype) !void { | ||||
|     _ = ctx; | ||||
|  | ||||
|     var root = try dvui.menu(@src(), .horizontal, .{ .background = true, .expand = .horizontal }); | ||||
|     defer root.deinit(); | ||||
|  | ||||
|     if (try dvui.menuItemLabel(@src(), "Workspace", .{ .submenu = true }, .{})) |r| { | ||||
|         var float = try dvui.floatingMenu( | ||||
|             @src(), .{.from = dvui.Rect.fromPoint(dvui.Point{ .x = r.x, .y = r.y + r.h })}, .{}); | ||||
|         defer float.deinit(); | ||||
|  | ||||
|         if (try dvui.menuItemLabel(@src(), "New", .{}, .{})) |_| { | ||||
|         } | ||||
|         if (try dvui.menuItemLabel(@src(), "Open", .{}, .{})) |_| { | ||||
|         } | ||||
|  | ||||
|         try dvui.separator(@src(), .{}); | ||||
|  | ||||
|         if (try dvui.menuItemLabel(@src(), "Save", .{}, .{})) |_| { | ||||
|         } | ||||
|         if (try dvui.menuItemLabel(@src(), "Save as", .{}, .{})) |_| { | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     if (try dvui.menuItemLabel(@src(), "Task", .{ .submenu = true }, .{})) |r| { | ||||
|         var float = try dvui.floatingMenu( | ||||
|             @src(), .{.from = dvui.Rect.fromPoint(dvui.Point{ .x = r.x, .y = r.y + r.h })}, .{}); | ||||
|         defer float.deinit(); | ||||
|  | ||||
|         if (try dvui.menuItemLabel(@src(), "New", .{}, .{})) |_| { | ||||
|         } | ||||
|     } | ||||
| } | ||||
							
								
								
									
										4
									
								
								src/heavens-net/compo/root.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										4
									
								
								src/heavens-net/compo/root.zig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,4 @@ | ||||
| pub const menu     = @import("./menu.zig"); | ||||
| pub const search   = @import("./search.zig"); | ||||
| pub const stage    = @import("./stage.zig"); | ||||
| pub const taskedit = @import("./taskedit.zig"); | ||||
							
								
								
									
										102
									
								
								src/heavens-net/compo/search.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										102
									
								
								src/heavens-net/compo/search.zig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,102 @@ | ||||
| const std  = @import("std"); | ||||
| const dvui = @import("dvui"); | ||||
|  | ||||
| const ui = @import("../ui/root.zig"); | ||||
|  | ||||
| pub const Task = struct { | ||||
|     id: usize, | ||||
|     name: [:0]const u8, | ||||
| }; | ||||
|  | ||||
| pub fn gui(ctx: anytype) !void { | ||||
|     var win = try dvui.floatingWindow(@src(), .{}, .{}); | ||||
|     defer win.deinit(); | ||||
|  | ||||
|     const cw = dvui.currentWindow(); | ||||
|  | ||||
|     try dvui.windowHeader("Search", "", null); | ||||
|  | ||||
|     // task adder | ||||
|     { | ||||
|         var adder = try dvui.textEntry(@src(), .{}, .{ | ||||
|             .expand = .horizontal, | ||||
|         }); | ||||
|         defer adder.deinit(); | ||||
|  | ||||
|         if (dvui.focusedWidgetId() == adder.data().id) { | ||||
|             if (ui.event.keyPress("activate")) { | ||||
|                 std.debug.print("hello\n", .{}); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     // task list | ||||
|     { | ||||
|         var scrollArea = try dvui.scrollArea(@src(), .{}, .{ | ||||
|             .expand = .both, | ||||
|         }); | ||||
|         defer scrollArea.deinit(); | ||||
|  | ||||
|         var list = try dvui.box(@src(), .vertical, .{ | ||||
|             .expand  = .both, | ||||
|             .padding = dvui.Rect.all(4), | ||||
|         }); | ||||
|         defer list.deinit(); | ||||
|  | ||||
|         for (0.., ctx.tasks()) |idx, task| { | ||||
|             if (idx > 0) { | ||||
|                 _ = try dvui.spacer(@src(), .{ .w = 0, .h = 1}, .{ | ||||
|                     .id_extra = idx, | ||||
|                     .expand   = .horizontal, | ||||
|                 }); | ||||
|             } | ||||
|             var hbox = try dvui.box(@src(), .horizontal, .{ | ||||
|                 .id_extra   = idx, | ||||
|                 .expand     = .horizontal, | ||||
|                 .background = true, | ||||
|                 .border     = dvui.Rect.all(1), | ||||
|             }); | ||||
|             defer hbox.deinit(); | ||||
|  | ||||
|             try dvui.label(@src(), "#{d} {s}", .{ task.id, task.name, }, .{}); | ||||
|  | ||||
|             if (hbox.data().borderRect().contains(cw.mouse_pt)) { | ||||
|                 var icons = try dvui.box(@src(), .horizontal, .{ | ||||
|                     .expand    = .vertical, | ||||
|                     .gravity_x = 1, | ||||
|                 }); | ||||
|                 defer icons.deinit(); | ||||
|  | ||||
|                 dvui. | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         try dvui.labelNoFmt(@src(), "no tasks anymore :)", .{ .gravity_x = 0.5 }); | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub const Mock = struct { | ||||
|     const Self     = @This(); | ||||
|     const TaskList = std.ArrayList(Task); | ||||
|  | ||||
|     _tasks: TaskList, | ||||
|  | ||||
|     pub fn init(alloc: std.mem.Allocator) !Self { | ||||
|         var ts = TaskList.init(alloc); | ||||
|         errdefer ts.deinit(); | ||||
|  | ||||
|         try ts.append(Task { .id = 0, .name = "helloworld", }); | ||||
|         try ts.append(Task { .id = 1, .name = "goodbye", }); | ||||
|  | ||||
|         return Mock { | ||||
|             ._tasks = ts, | ||||
|         }; | ||||
|     } | ||||
|     pub fn deinit(self: *Self) void { | ||||
|         self._tasks.deinit(); | ||||
|     } | ||||
|  | ||||
|     fn tasks(self: *const Self) []const Task { | ||||
|         return self._tasks.items; | ||||
|     } | ||||
| }; | ||||
| @@ -2,6 +2,7 @@ const std  = @import("std"); | ||||
| const dvui = @import("dvui"); | ||||
| 
 | ||||
| pub const Task = struct { | ||||
|     id: usize, | ||||
|     name: [:0]const u8, | ||||
|     mark: bool, | ||||
| }; | ||||
| @@ -10,7 +11,7 @@ pub fn gui(ctx: anytype) !void { | ||||
|     var win = try dvui.floatingWindow(@src(), .{}, .{}); | ||||
|     defer win.deinit(); | ||||
| 
 | ||||
|     try dvui.windowHeader("Today", "", null); | ||||
|     try dvui.windowHeader("Stage", "", null); | ||||
| 
 | ||||
|     var scrollArea = try dvui.scrollArea(@src(), .{}, .{ | ||||
|         .expand = .both, | ||||
| @@ -46,7 +47,7 @@ pub fn gui(ctx: anytype) !void { | ||||
|             ctx.mark(idx, mark); | ||||
|         } | ||||
| 
 | ||||
|         try dvui.label(@src(), "{s}", .{ task.name, }, .{}); | ||||
|         try dvui.label(@src(), "#{d} {s}", .{ task.id, task.name, }, .{}); | ||||
| 
 | ||||
|         _ = try dvui.ReorderWidget.draggable(@src(), .{ .reorderable = reorderable, }, .{ | ||||
|             .expand      = .vertical, | ||||
| @@ -68,8 +69,8 @@ pub const Mock = struct { | ||||
|         var tasks = TaskList.init(alloc); | ||||
|         errdefer tasks.deinit(); | ||||
| 
 | ||||
|         try tasks.append(Task { .name = "helloworld", .mark = true, }); | ||||
|         try tasks.append(Task { .name = "goodbye", .mark = false, }); | ||||
|         try tasks.append(Task { .id = 0, .name = "helloworld", .mark = true, }); | ||||
|         try tasks.append(Task { .id = 1, .name = "goodbye", .mark = false, }); | ||||
| 
 | ||||
|         return Mock { | ||||
|             .tasks = tasks, | ||||
| @@ -79,10 +80,10 @@ pub const Mock = struct { | ||||
|         self.tasks.deinit(); | ||||
|     } | ||||
| 
 | ||||
|     fn mark(self: *Self, idx: usize, check: bool) void { | ||||
|     pub fn mark(self: *Self, idx: usize, check: bool) void { | ||||
|         self.tasks.items[idx].mark = check; | ||||
|     } | ||||
|     fn get_tasks(self: *const Self) []const Task { | ||||
|     pub fn get_tasks(self: *const Self) []const Task { | ||||
|         return self.tasks.items; | ||||
|     } | ||||
| }; | ||||
							
								
								
									
										158
									
								
								src/heavens-net/compo/taskedit.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										158
									
								
								src/heavens-net/compo/taskedit.zig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,158 @@ | ||||
| const std  = @import("std"); | ||||
| const dvui = @import("dvui"); | ||||
|  | ||||
| const ui = @import("../ui/root.zig"); | ||||
|  | ||||
| pub const Tab = enum { | ||||
|     info, | ||||
|     detail, | ||||
|     network, | ||||
|     gantt, | ||||
| }; | ||||
|  | ||||
| pub fn gui(ctx: anytype) !void { | ||||
|     var win = try dvui.floatingWindow(@src(), .{}, .{}); | ||||
|     defer win.deinit(); | ||||
|  | ||||
|     // window header | ||||
|     { | ||||
|         var buf: [128]u8 = undefined; | ||||
|         const subtitle = std.fmt.bufPrint(&buf, "#{d}", .{ctx.taskId()}) catch unreachable; | ||||
|         try dvui.windowHeader("Task", subtitle, null); | ||||
|     } | ||||
|  | ||||
|     // task summary | ||||
|     { | ||||
|         var hbox = try dvui.box(@src(), .horizontal, .{ .expand = .horizontal, }); | ||||
|         defer hbox.deinit(); | ||||
|  | ||||
|         var mark: bool = false; | ||||
|         if (try dvui.checkbox(@src(), &mark, null, .{ .gravity_y = 0.5, })) { | ||||
|         } | ||||
|  | ||||
|         var summary = try dvui.textEntry(@src(), .{}, .{ | ||||
|             .expand = .horizontal, | ||||
|         }); | ||||
|         defer summary.deinit(); | ||||
|     } | ||||
|  | ||||
|     // tabs | ||||
|     { | ||||
|         const shown = ctx.shownTab(); | ||||
|  | ||||
|         var tbox = try dvui.box(@src(), .vertical, .{ .expand = .both, }); | ||||
|         defer tbox.deinit(); | ||||
|  | ||||
|         { | ||||
|             var tabs = dvui.TabsWidget.init(@src(), .{ .dir = .horizontal }, .{ | ||||
|                 .expand = .horizontal, | ||||
|             }); | ||||
|             try tabs.install(); | ||||
|             defer tabs.deinit(); | ||||
|  | ||||
|             inline for (std.meta.fields(Tab)) |tabMeta| { | ||||
|                 const tab = @field(Tab, tabMeta.name); | ||||
|                 if (try tabs.addTabLabel(shown == tab, tabMeta.name)) { | ||||
|                     ctx.switchTab(tab); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|  | ||||
|         var vbox = try dvui.box(@src(), .vertical, .{ .expand = .both, }); | ||||
|         defer vbox.deinit(); | ||||
|  | ||||
|         switch (shown) { | ||||
|             .info   => try tabInfo(ctx), | ||||
|             .detail => try tabDetail(ctx), | ||||
|             else    => try dvui.labelNoFmt(@src(), "NOT IMPLEMENTED YET :(", .{ | ||||
|                 .gravity_x = 0.5, | ||||
|                 .gravity_y = 0.5, | ||||
|             }), | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn tabInfo(ctx: anytype) !void { | ||||
|     _ = ctx; | ||||
|  | ||||
|     var vbox = try dvui.box(@src(), .vertical, .{ .expand = .both, }); | ||||
|     defer vbox.deinit(); | ||||
|  | ||||
|     const fields = [_][:0]const u8 {"foo", "baz", "bar"}; | ||||
|     for (0.., fields) |idx, name| { | ||||
|         var hbox = try dvui.box(@src(), .horizontal, .{ | ||||
|             .id_extra = idx, | ||||
|             .expand   = .horizontal, | ||||
|         }); | ||||
|         defer hbox.deinit(); | ||||
|  | ||||
|         { | ||||
|             var box = try dvui.box(@src(), .horizontal, .{ | ||||
|                 .min_size_content = .{ .w = 64, .h = 0, }, | ||||
|             }); | ||||
|             defer box.deinit(); | ||||
|             try dvui.label(@src(), "{s}", .{name}, .{ | ||||
|                 .gravity_x = 1, | ||||
|             }); | ||||
|         } | ||||
|         { | ||||
|             var box = try dvui.box(@src(), .horizontal, .{ | ||||
|                 .expand = .horizontal, | ||||
|             }); | ||||
|             defer box.deinit(); | ||||
|             try dvui.labelNoFmt(@src(), "this is a field value", .{}); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  | ||||
| fn tabDetail(ctx: anytype) !void { | ||||
|     _ = ctx; | ||||
|     // const task = ctx.task(); | ||||
|  | ||||
|     var vbox = try dvui.box(@src(), .vertical, .{ .expand = .both, }); | ||||
|     defer vbox.deinit(); | ||||
|  | ||||
|     // detail | ||||
|     { | ||||
|         var detail = try dvui.textEntry(@src(), .{ | ||||
|             .break_lines       = true, | ||||
|             .scroll_vertical   = true, | ||||
|             .scroll_horizontal = true, | ||||
|             .multiline         = true, | ||||
|         }, .{ | ||||
|             .expand = .both, | ||||
|         }); | ||||
|         defer detail.deinit(); | ||||
|     } | ||||
| } | ||||
|  | ||||
| pub const Mock = struct { | ||||
|     const Self = @This(); | ||||
|  | ||||
|     _taskId: usize, | ||||
|     _summary: []const u8, | ||||
|  | ||||
|     _shownTab: Tab, | ||||
|  | ||||
|     pub fn init(alloc: std.mem.Allocator) !Self { | ||||
|         _ = alloc; | ||||
|         return Mock { | ||||
|             ._taskId = 0, | ||||
|             ._summary = "hello", | ||||
|             ._shownTab = .info, | ||||
|         }; | ||||
|     } | ||||
|     pub fn deinit(self: *Self) void { | ||||
|         _ = self; | ||||
|     } | ||||
|  | ||||
|     fn switchTab(self: *Self, tab: Tab) void { | ||||
|         self._shownTab = tab; | ||||
|     } | ||||
|  | ||||
|     fn taskId(self: *const Self) usize { return self._taskId; } | ||||
|     fn summary(self: *const Self) []const u8 { return self._summary; } | ||||
|  | ||||
|     fn shownTab(self: *const Self) Tab { return self._shownTab; } | ||||
| }; | ||||
|  | ||||
							
								
								
									
										21
									
								
								src/heavens-net/ui/event.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								src/heavens-net/ui/event.zig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| const dvui = @import("dvui"); | ||||
|  | ||||
| pub fn key(bind: []const u8) ?*const dvui.Event.Key { | ||||
|     for (dvui.events()) |e| { | ||||
|         if (e.evt == .key) { | ||||
|             if (e.evt.key.matchBind(bind)) { | ||||
|                 return &e.evt.key; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|     return null; | ||||
| } | ||||
| pub fn keyDown(bind: []const u8) bool { | ||||
|     return if (key(bind)) |k| k.action == .down else false; | ||||
| } | ||||
| pub fn keyPress(bind: []const u8) bool { | ||||
|     return if (key(bind)) |k| (k.action == .down or k.action == .repeat) else false; | ||||
| } | ||||
| pub fn keyUp(bind: []const u8) bool { | ||||
|     return if (key(bind)) |k| k.action == .up else false; | ||||
| } | ||||
							
								
								
									
										1
									
								
								src/heavens-net/ui/root.zig
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/heavens-net/ui/root.zig
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| pub const event = @import("./event.zig"); | ||||
| @@ -1 +0,0 @@ | ||||
| pub const today = @import("./today.zig"); | ||||
		Reference in New Issue
	
	Block a user