add addition of channels from device screen
This commit is contained in:
parent
25377c8b4f
commit
8ba3d0c914
46
src/app.zig
46
src/app.zig
@ -12,6 +12,7 @@ const RangeF64 = @import("./range.zig").RangeF64;
|
|||||||
const P = @import("profiler");
|
const P = @import("profiler");
|
||||||
|
|
||||||
const MainScreen = @import("./screens/main_screen.zig");
|
const MainScreen = @import("./screens/main_screen.zig");
|
||||||
|
const ChannelFromDeviceScreen = @import("./screens/channel_from_device.zig");
|
||||||
|
|
||||||
const log = std.log.scoped(.app);
|
const log = std.log.scoped(.app);
|
||||||
const clamp = std.math.clamp;
|
const clamp = std.math.clamp;
|
||||||
@ -107,28 +108,28 @@ channel_mutex: std.Thread.Mutex = .{},
|
|||||||
|
|
||||||
// UI Fields
|
// UI Fields
|
||||||
ui: UI,
|
ui: UI,
|
||||||
screen: MainScreen,
|
current_screen: enum {
|
||||||
graph_controls: struct {
|
main_menu,
|
||||||
drag_start: ?struct {
|
channel_from_device
|
||||||
index: f64,
|
} = .main_menu,
|
||||||
value: f64
|
main_screen: MainScreen,
|
||||||
} = null,
|
channel_from_device: ChannelFromDeviceScreen,
|
||||||
} = .{},
|
|
||||||
fullscreen_channel: ?*ChannelView = null,
|
|
||||||
|
|
||||||
pub fn init(self: *App, allocator: std.mem.Allocator) !void {
|
pub fn init(self: *App, allocator: std.mem.Allocator) !void {
|
||||||
self.* = App{
|
self.* = App{
|
||||||
.allocator = allocator,
|
.allocator = allocator,
|
||||||
.ui = UI.init(allocator),
|
.ui = UI.init(allocator),
|
||||||
|
.main_screen = MainScreen{
|
||||||
|
.app = self
|
||||||
|
},
|
||||||
|
.channel_from_device = ChannelFromDeviceScreen{
|
||||||
|
.app = self,
|
||||||
|
.channel_names = std.heap.ArenaAllocator.init(allocator)
|
||||||
|
},
|
||||||
.task_pool = undefined,
|
.task_pool = undefined,
|
||||||
.screen = undefined
|
|
||||||
};
|
};
|
||||||
errdefer self.deinit();
|
errdefer self.deinit();
|
||||||
|
|
||||||
self.screen = MainScreen{
|
|
||||||
.app = self
|
|
||||||
};
|
|
||||||
|
|
||||||
if (NIDaq.Api.init()) |ni_daq_api| {
|
if (NIDaq.Api.init()) |ni_daq_api| {
|
||||||
self.ni_daq_api = ni_daq_api;
|
self.ni_daq_api = ni_daq_api;
|
||||||
|
|
||||||
@ -173,6 +174,8 @@ pub fn init(self: *App, allocator: std.mem.Allocator) !void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn deinit(self: *App) void {
|
pub fn deinit(self: *App) void {
|
||||||
|
self.task_pool.deinit();
|
||||||
|
|
||||||
for (self.channel_views.slice()) |*channel| {
|
for (self.channel_views.slice()) |*channel| {
|
||||||
channel.view_cache.deinit();
|
channel.view_cache.deinit();
|
||||||
}
|
}
|
||||||
@ -192,8 +195,8 @@ pub fn deinit(self: *App) void {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.ui.deinit();
|
self.ui.deinit();
|
||||||
|
self.channel_from_device.deinit();
|
||||||
|
|
||||||
self.task_pool.deinit();
|
|
||||||
if (self.ni_daq_api) |*ni_daq_api| ni_daq_api.deinit();
|
if (self.ni_daq_api) |*ni_daq_api| ni_daq_api.deinit();
|
||||||
if (self.ni_daq) |*ni_daq| ni_daq.deinit(self.allocator);
|
if (self.ni_daq) |*ni_daq| ni_daq.deinit(self.allocator);
|
||||||
}
|
}
|
||||||
@ -254,7 +257,10 @@ pub fn tick(self: *App) !void {
|
|||||||
ui.begin();
|
ui.begin();
|
||||||
defer ui.end();
|
defer ui.end();
|
||||||
|
|
||||||
try self.screen.tick();
|
switch (self.current_screen) {
|
||||||
|
.main_menu => try self.main_screen.tick(),
|
||||||
|
.channel_from_device => try self.channel_from_device.tick()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -263,6 +269,16 @@ pub fn tick(self: *App) !void {
|
|||||||
|
|
||||||
// ------------------------ Channel management -------------------------------- //
|
// ------------------------ Channel management -------------------------------- //
|
||||||
|
|
||||||
|
pub fn getChannelDeviceByName(self: *App, name: []const u8) ?*DeviceChannel {
|
||||||
|
for (&self.device_channels) |*maybe_channel| {
|
||||||
|
var channel: *DeviceChannel = &(maybe_channel.* orelse continue);
|
||||||
|
if (std.mem.eql(u8, channel.name.slice(), name)) {
|
||||||
|
return channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn getChannelSamples(self: *App, channel_view: *ChannelView) []const f64 {
|
pub fn getChannelSamples(self: *App, channel_view: *ChannelView) []const f64 {
|
||||||
return switch (channel_view.source) {
|
return switch (channel_view.source) {
|
||||||
.file => |index| {
|
.file => |index| {
|
||||||
|
58
src/main.zig
58
src/main.zig
@ -82,67 +82,11 @@ pub fn main() !void {
|
|||||||
const allocator = gpa.allocator();
|
const allocator = gpa.allocator();
|
||||||
defer _ = gpa.deinit();
|
defer _ = gpa.deinit();
|
||||||
|
|
||||||
// const devices = try ni_daq.listDeviceNames();
|
|
||||||
|
|
||||||
// for (devices) |device| {
|
|
||||||
// if (try ni_daq.checkDeviceAIMeasurementType(device, .Voltage)) {
|
|
||||||
// const voltage_ranges = try ni_daq.listDeviceAIVoltageRanges(device);
|
|
||||||
// assert(voltage_ranges.len > 0);
|
|
||||||
|
|
||||||
// const min_sample = voltage_ranges[0].low;
|
|
||||||
// const max_sample = voltage_ranges[0].high;
|
|
||||||
|
|
||||||
// for (try ni_daq.listDeviceAIPhysicalChannels(device)) |channel_name| {
|
|
||||||
// var channel = try app.appendChannel();
|
|
||||||
// channel.min_sample = min_sample;
|
|
||||||
// channel.max_sample = max_sample;
|
|
||||||
// try app.task_pool.createAIVoltageChannel(ni_daq, .{
|
|
||||||
// .channel = channel_name,
|
|
||||||
// .min_value = min_sample,
|
|
||||||
// .max_value = max_sample,
|
|
||||||
// });
|
|
||||||
// break;
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// if (try ni_daq.checkDeviceAOOutputType(device, .Voltage)) {
|
|
||||||
// const voltage_ranges = try ni_daq.listDeviceAOVoltageRanges(device);
|
|
||||||
// assert(voltage_ranges.len > 0);
|
|
||||||
|
|
||||||
// const min_sample = voltage_ranges[0].low;
|
|
||||||
// const max_sample = voltage_ranges[0].high;
|
|
||||||
|
|
||||||
// for (try ni_daq.listDeviceAOPhysicalChannels(device)) |channel_name| {
|
|
||||||
// var channel = try app.appendChannel();
|
|
||||||
// channel.min_sample = min_sample;
|
|
||||||
// channel.max_sample = max_sample;
|
|
||||||
// try app.task_pool.createAOVoltageChannel(ni_daq, .{
|
|
||||||
// .channel = channel_name,
|
|
||||||
// .min_value = min_sample,
|
|
||||||
// .max_value = max_sample,
|
|
||||||
// });
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
|
|
||||||
// for (0.., app.channels.items) |i, *channel| {
|
|
||||||
// channel.color = rl.Color.fromHSV(@as(f32, @floatFromInt(i)) / @as(f32, @floatFromInt(app.channels.items.len)) * 360, 0.75, 0.8);
|
|
||||||
// }
|
|
||||||
|
|
||||||
// const sample_rate: f64 = 5000;
|
|
||||||
// try app.task_pool.setContinousSampleRate(sample_rate);
|
|
||||||
|
|
||||||
// var channel_samples = try app.task_pool.start(0.01, allocator);
|
|
||||||
// defer channel_samples.deinit();
|
|
||||||
// defer app.task_pool.stop() catch @panic("stop task failed");
|
|
||||||
|
|
||||||
// app.channel_samples = channel_samples;
|
|
||||||
|
|
||||||
const icon_png = @embedFile("./assets/icon.png");
|
const icon_png = @embedFile("./assets/icon.png");
|
||||||
var icon_image = rl.loadImageFromMemory(".png", icon_png);
|
var icon_image = rl.loadImageFromMemory(".png", icon_png);
|
||||||
defer icon_image.unload();
|
defer icon_image.unload();
|
||||||
|
|
||||||
rl.initWindow(800, 450, "DAQ view");
|
rl.initWindow(800, 600, "DAQ view");
|
||||||
defer rl.closeWindow();
|
defer rl.closeWindow();
|
||||||
rl.setWindowState(.{ .window_resizable = true, .vsync_hint = true });
|
rl.setWindowState(.{ .window_resizable = true, .vsync_hint = true });
|
||||||
rl.setWindowMinSize(256, 256);
|
rl.setWindowMinSize(256, 256);
|
||||||
|
225
src/screens/channel_from_device.zig
Normal file
225
src/screens/channel_from_device.zig
Normal file
@ -0,0 +1,225 @@
|
|||||||
|
const std = @import("std");
|
||||||
|
const App = @import("../app.zig");
|
||||||
|
const UI = @import("../ui.zig");
|
||||||
|
const srcery = @import("../srcery.zig");
|
||||||
|
const NIDaq = @import("../ni-daq/root.zig");
|
||||||
|
|
||||||
|
const assert = std.debug.assert;
|
||||||
|
const log = std.log.scoped(.channel_from_device_screen);
|
||||||
|
|
||||||
|
const Screen = @This();
|
||||||
|
|
||||||
|
app: *App,
|
||||||
|
|
||||||
|
hot_channel: ?[:0]const u8 = null,
|
||||||
|
|
||||||
|
// TODO: 32 limit
|
||||||
|
selected_channels: std.BoundedArray([:0]u8, 32) = .{},
|
||||||
|
// TODO: Don't use arena
|
||||||
|
channel_names: std.heap.ArenaAllocator,
|
||||||
|
|
||||||
|
pub fn deinit(self: *Screen) void {
|
||||||
|
_ = self.channel_names.reset(.free_all);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn isChannelSelected(self: *Screen, channel: []const u8) bool {
|
||||||
|
for (self.selected_channels.slice()) |selected_channel| {
|
||||||
|
if (std.mem.eql(u8, selected_channel, channel)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
fn selectChannel(self: *Screen, channel: []const u8) void {
|
||||||
|
if (self.selected_channels.unusedCapacitySlice().len == 0) {
|
||||||
|
log.warn("Maximum number of selected channels reached", .{});
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.isChannelSelected(channel)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const allocator = self.channel_names.allocator();
|
||||||
|
const channel_dupe = allocator.dupeZ(u8, channel) catch |e| {
|
||||||
|
log.err("Failed to duplicate channel name: {}", .{e});
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.selected_channels.appendAssumeCapacity(channel_dupe);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn deselectChannel(self: *Screen, channel: []const u8) void {
|
||||||
|
for (0.., self.selected_channels.slice()) |i, selected_channel| {
|
||||||
|
if (std.mem.eql(u8, selected_channel, channel)) {
|
||||||
|
_ = self.selected_channels.swapRemove(i);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn toggleChannel(self: *Screen, channel: []const u8) void {
|
||||||
|
if (self.isChannelSelected(channel)) {
|
||||||
|
self.deselectChannel(channel);
|
||||||
|
} else {
|
||||||
|
self.selectChannel(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn tick(self: *Screen) !void {
|
||||||
|
var ni_daq = self.app.ni_daq orelse return;
|
||||||
|
var ui = &self.app.ui;
|
||||||
|
|
||||||
|
if (ui.isKeyboardPressed(.key_escape)) {
|
||||||
|
self.app.current_screen = .main_menu;
|
||||||
|
}
|
||||||
|
|
||||||
|
const root = ui.parentBox().?;
|
||||||
|
root.layout_direction = .left_to_right;
|
||||||
|
|
||||||
|
{
|
||||||
|
const panel = ui.beginScrollbar(ui.keyFromString("Channels"));
|
||||||
|
defer ui.endScrollbar();
|
||||||
|
panel.layout_direction = .top_to_bottom;
|
||||||
|
|
||||||
|
const devices = try ni_daq.listDeviceNames();
|
||||||
|
for (devices) |device| {
|
||||||
|
var ai_voltage_physical_channels: []const [:0]const u8 = &.{};
|
||||||
|
if (try ni_daq.checkDeviceAIMeasurementType(device, .Voltage)) {
|
||||||
|
ai_voltage_physical_channels = try ni_daq.listDeviceAIPhysicalChannels(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
var ao_physical_channels: []const [:0]const u8 = &.{};
|
||||||
|
if (try ni_daq.checkDeviceAOOutputType(device, .Voltage)) {
|
||||||
|
ao_physical_channels = try ni_daq.listDeviceAOPhysicalChannels(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline for (.{ ai_voltage_physical_channels, ao_physical_channels }) |channels| {
|
||||||
|
for (channels) |channel| {
|
||||||
|
const channel_button = ui.textButton(channel);
|
||||||
|
channel_button.background = srcery.black;
|
||||||
|
if (self.isChannelSelected(channel)) {
|
||||||
|
channel_button.background = srcery.bright_white;
|
||||||
|
channel_button.text_color = srcery.black;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (self.app.getChannelDeviceByName(channel) != null) {
|
||||||
|
channel_button.text_color = srcery.white;
|
||||||
|
channel_button.background = srcery.hard_black;
|
||||||
|
} else {
|
||||||
|
const signal = ui.signal(channel_button);
|
||||||
|
if (signal.clicked()) {
|
||||||
|
self.toggleChannel(channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (signal.hot) {
|
||||||
|
self.hot_channel = channel;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const panel = ui.createBox(.{
|
||||||
|
.size_x = UI.Sizing.initGrowFull(),
|
||||||
|
.size_y = UI.Sizing.initGrowFull(),
|
||||||
|
.borders = .{
|
||||||
|
.left = .{ .color = srcery.hard_black, .size = 4 }
|
||||||
|
},
|
||||||
|
.layout_direction = .top_to_bottom,
|
||||||
|
.padding = UI.Padding.all(ui.rem(2))
|
||||||
|
});
|
||||||
|
panel.beginChildren();
|
||||||
|
defer panel.endChildren();
|
||||||
|
|
||||||
|
const info_container = ui.createBox(.{
|
||||||
|
.size_x = UI.Sizing.initGrowFull(),
|
||||||
|
.size_y = UI.Sizing.initGrowFull(),
|
||||||
|
.layout_direction = .top_to_bottom,
|
||||||
|
});
|
||||||
|
|
||||||
|
if (self.hot_channel) |hot_channel| {
|
||||||
|
info_container.beginChildren();
|
||||||
|
defer info_container.endChildren();
|
||||||
|
|
||||||
|
var maybe_hot_device: ?[:0]const u8 = null;
|
||||||
|
var device_buff: NIDaq.BoundedDeviceName = .{};
|
||||||
|
if (NIDaq.getDeviceNameFromChannel(hot_channel)) |device| {
|
||||||
|
device_buff.appendSliceAssumeCapacity(device);
|
||||||
|
device_buff.buffer[device_buff.len] = 0;
|
||||||
|
maybe_hot_device = device_buff.buffer[0..device_buff.len :0];
|
||||||
|
}
|
||||||
|
|
||||||
|
var channel_type_name: []const u8 = "unknown";
|
||||||
|
if (NIDaq.getChannelType(hot_channel)) |channel_type| {
|
||||||
|
channel_type_name = channel_type.name();
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
const channel_info = ui.createBox(.{
|
||||||
|
.size_x = UI.Sizing.initGrowFull(),
|
||||||
|
.size_y = UI.Sizing.initFitChildren(),
|
||||||
|
.padding = .{
|
||||||
|
.bottom = ui.rem(2)
|
||||||
|
},
|
||||||
|
.layout_direction = .top_to_bottom
|
||||||
|
});
|
||||||
|
channel_info.beginChildren();
|
||||||
|
defer channel_info.endChildren();
|
||||||
|
|
||||||
|
_ = ui.label("Channel properties", .{});
|
||||||
|
_ = ui.label("Name: {s}", .{hot_channel});
|
||||||
|
_ = ui.label("Type: {s}", .{channel_type_name});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (maybe_hot_device) |hot_device| {
|
||||||
|
_ = ui.label("Device properties", .{});
|
||||||
|
|
||||||
|
if (ni_daq.listDeviceAIMeasurementTypes(hot_device)) |measurement_types| {
|
||||||
|
_ = ui.label("Measurement types: {} types", .{measurement_types.len});
|
||||||
|
} else |e| {
|
||||||
|
log.err("ni_daq.listDeviceAIMeasurementTypes(): {}", .{ e });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
info_container.alignment.x = .center;
|
||||||
|
info_container.alignment.y = .center;
|
||||||
|
info_container.setText("Hover on a channel");
|
||||||
|
info_container.flags.insert(.wrap_text);
|
||||||
|
info_container.text_color = srcery.hard_black;
|
||||||
|
info_container.font = .{
|
||||||
|
.variant = .bold_italic,
|
||||||
|
.size = ui.rem(3)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
const add_button = ui.button(ui.keyFromString("Add channels"));
|
||||||
|
add_button.setFmtText("Add {} selected channels", .{self.selected_channels.len});
|
||||||
|
add_button.size.x = UI.Sizing.initGrowFull();
|
||||||
|
add_button.alignment.x = .center;
|
||||||
|
if (self.selected_channels.len > 0) {
|
||||||
|
add_button.borders = UI.Borders.all(.{
|
||||||
|
.color = srcery.green,
|
||||||
|
.size = 2
|
||||||
|
});
|
||||||
|
|
||||||
|
const signal = ui.signal(add_button);
|
||||||
|
if (signal.clicked()) {
|
||||||
|
self.app.current_screen = .main_menu;
|
||||||
|
for (self.selected_channels.slice()) |channel| {
|
||||||
|
try self.app.appendChannelFromDevice(channel);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
add_button.borders = UI.Borders.all(.{
|
||||||
|
.color = srcery.hard_black,
|
||||||
|
.size = 2
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -550,7 +550,7 @@ fn showChannelView(self: *MainScreen, channel_view: *ChannelView, height: UI.Siz
|
|||||||
if (self.app.getChannelSourceDevice(channel_view)) |device_channel| {
|
if (self.app.getChannelSourceDevice(channel_view)) |device_channel| {
|
||||||
_ = device_channel;
|
_ = device_channel;
|
||||||
|
|
||||||
const follow = ui.button("Follow");
|
const follow = ui.textButton("Follow");
|
||||||
follow.background = srcery.hard_black;
|
follow.background = srcery.hard_black;
|
||||||
if (channel_view.follow) {
|
if (channel_view.follow) {
|
||||||
follow.borders = UI.Borders.bottom(.{
|
follow.borders = UI.Borders.bottom(.{
|
||||||
@ -659,7 +659,7 @@ pub fn tick(self: *MainScreen) !void {
|
|||||||
toolbar.beginChildren();
|
toolbar.beginChildren();
|
||||||
defer toolbar.endChildren();
|
defer toolbar.endChildren();
|
||||||
|
|
||||||
var start_all = ui.button("Start/Stop button");
|
var start_all = ui.textButton("Start/Stop button");
|
||||||
start_all.borders = UI.Borders.all(.{ .size = 4, .color = srcery.red });
|
start_all.borders = UI.Borders.all(.{ .size = 4, .color = srcery.red });
|
||||||
start_all.background = srcery.black;
|
start_all.background = srcery.black;
|
||||||
start_all.size.y = UI.Sizing.initFixed(.{ .parent_percent = 1 });
|
start_all.size.y = UI.Sizing.initFixed(.{ .parent_percent = 1 });
|
||||||
@ -725,9 +725,12 @@ pub fn tick(self: *MainScreen) !void {
|
|||||||
add_channel_view.beginChildren();
|
add_channel_view.beginChildren();
|
||||||
defer add_channel_view.endChildren();
|
defer add_channel_view.endChildren();
|
||||||
|
|
||||||
const add_from_file = ui.button("Add from file");
|
const add_from_file = ui.textButton("Add from file");
|
||||||
add_from_file.borders = UI.Borders.all(.{ .size = 2, .color = srcery.green });
|
add_from_file.borders = UI.Borders.all(.{ .size = 2, .color = srcery.green });
|
||||||
if (ui.signal(add_from_file).clicked()) {
|
if (ui.signal(add_from_file).clicked()) {
|
||||||
|
self.app.channel_mutex.unlock();
|
||||||
|
defer self.app.channel_mutex.lock();
|
||||||
|
|
||||||
if (Platform.openFilePicker(self.app.allocator)) |filename| {
|
if (Platform.openFilePicker(self.app.allocator)) |filename| {
|
||||||
defer self.app.allocator.free(filename);
|
defer self.app.allocator.free(filename);
|
||||||
|
|
||||||
@ -739,10 +742,10 @@ pub fn tick(self: *MainScreen) !void {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const add_from_device = ui.button("Add from device");
|
const add_from_device = ui.textButton("Add from device");
|
||||||
add_from_device.borders = UI.Borders.all(.{ .size = 2, .color = srcery.green });
|
add_from_device.borders = UI.Borders.all(.{ .size = 2, .color = srcery.green });
|
||||||
if (ui.signal(add_from_device).clicked()) {
|
if (ui.signal(add_from_device).clicked()) {
|
||||||
|
self.app.current_screen = .channel_from_device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
13
src/ui.zig
13
src/ui.zig
@ -1881,9 +1881,9 @@ pub fn mouseTooltip(self: *UI) *Box {
|
|||||||
return tooltip;
|
return tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn button(self: *UI, text: []const u8) *Box {
|
pub fn button(self: *UI, key: UI.Key) *Box {
|
||||||
return self.createBox(.{
|
return self.createBox(.{
|
||||||
.key = self.keyFromString(text),
|
.key = key,
|
||||||
.size_x = Sizing.initFixed(.text),
|
.size_x = Sizing.initFixed(.text),
|
||||||
.size_y = Sizing.initFixed(.text),
|
.size_y = Sizing.initFixed(.text),
|
||||||
.flags = &.{ .draw_hot, .draw_active, .clickable },
|
.flags = &.{ .draw_hot, .draw_active, .clickable },
|
||||||
@ -1894,10 +1894,17 @@ pub fn button(self: *UI, text: []const u8) *Box {
|
|||||||
.right = self.rem(1)
|
.right = self.rem(1)
|
||||||
},
|
},
|
||||||
.hot_cursor = .mouse_cursor_pointing_hand,
|
.hot_cursor = .mouse_cursor_pointing_hand,
|
||||||
.text = text
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn textButton(self: *UI, text: []const u8) *Box {
|
||||||
|
var box = self.button(self.keyFromString(text));
|
||||||
|
box.setText(text);
|
||||||
|
box.alignment.x = .center;
|
||||||
|
box.alignment.y = .center;
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
pub fn label(self: *UI, comptime fmt: []const u8, args: anytype) *Box {
|
pub fn label(self: *UI, comptime fmt: []const u8, args: anytype) *Box {
|
||||||
const box = self.createBox(.{
|
const box = self.createBox(.{
|
||||||
.size_x = Sizing.initFixed(.text),
|
.size_x = Sizing.initFixed(.text),
|
||||||
|
Loading…
Reference in New Issue
Block a user