mirror of
https://github.com/raylib-zig/raylib-zig.git
synced 2026-01-20 22:35:26 +00:00
167 lines
7.2 KiB
Zig
167 lines
7.2 KiB
Zig
const std = @import("std");
|
|
const rl = @import("raylib");
|
|
const rg = @import("raygui");
|
|
|
|
const WINDOW_STATUS_BAR_HEIGHT = 24;
|
|
const WINDOW_CLOSE_BUTTON_SIZE = 18;
|
|
const CLOSE_TITLE_SIZE_DELTA_HALF = (WINDOW_STATUS_BAR_HEIGHT - WINDOW_CLOSE_BUTTON_SIZE) / 2;
|
|
|
|
const DrawContentFn = *const fn(rl.Vector2, rl.Vector2) void;
|
|
|
|
fn floatingWindow(
|
|
position: *rl.Vector2,
|
|
size: *rl.Vector2,
|
|
minimized: *bool,
|
|
moving: *bool,
|
|
resizing: *bool,
|
|
draw_content: DrawContentFn,
|
|
content_size: rl.Vector2,
|
|
scroll: *rl.Vector2,
|
|
title: []const u8
|
|
) void {
|
|
var title_buf: [64]u8 = undefined;
|
|
const title_text = std.fmt.bufPrintZ(&title_buf, "{s}", .{ title }) catch "";
|
|
const mouse_position = rl.getMousePosition();
|
|
|
|
const is_left_pressed = rl.isMouseButtonPressed(rl.MouseButton.left);
|
|
if(is_left_pressed and !(moving.*) and !(resizing.*)) {
|
|
|
|
const title_collsion_rect = rl.Rectangle{.x = position.x, .y = position.y, .width = size.x - WINDOW_CLOSE_BUTTON_SIZE - CLOSE_TITLE_SIZE_DELTA_HALF, .height = WINDOW_STATUS_BAR_HEIGHT};
|
|
const resize_collision_rect = rl.Rectangle{.x = position.x + size.x - 20, .y = position.y + size.y - 20, .width = 20, .height = 20};
|
|
|
|
_ = rl.drawRectangleLinesEx(title_collsion_rect, 15, rl.Color.red);
|
|
_ = rl.drawRectangleLinesEx(resize_collision_rect, 15, rl.Color.green);
|
|
if(rl.checkCollisionPointRec(mouse_position, title_collsion_rect)) {
|
|
moving.* = true;
|
|
} else if(!(minimized.*) and rl.checkCollisionPointRec(mouse_position, resize_collision_rect)) {
|
|
resizing.* = true;
|
|
}
|
|
}
|
|
|
|
const screen_width = rl.getScreenWidth();
|
|
const screen_width_f32 = @as(f32, @floatFromInt(screen_width));
|
|
const screen_height = rl.getScreenHeight();
|
|
const screen_height_f32 = @as(f32, @floatFromInt(screen_height));
|
|
// window movement and resize update
|
|
if(moving.*) {
|
|
const mouse_delta = rl.getMouseDelta();
|
|
position.x += mouse_delta.x;
|
|
position.y += mouse_delta.y;
|
|
|
|
if(rl.isMouseButtonReleased(rl.MouseButton.left)) {
|
|
moving.* = false;
|
|
|
|
if(position.x < 0) {
|
|
position.x = 0;
|
|
} else if(position.x > screen_width_f32 - size.x) {
|
|
position.x = screen_width_f32 - size.x;
|
|
}
|
|
if(position.y < 0) {
|
|
position.x = 0;
|
|
} else if(position.y > screen_height_f32) {
|
|
position.y = screen_height_f32 - WINDOW_STATUS_BAR_HEIGHT;
|
|
}
|
|
}
|
|
} else if(resizing.*) {
|
|
if (mouse_position.x > position.x) {
|
|
size.x = mouse_position.x - position.x;
|
|
}
|
|
if (mouse_position.y > position.y) {
|
|
size.y = mouse_position.y - position.y;
|
|
}
|
|
// clamp window size to an arbitrary minimum value and the window size as the maximum
|
|
const min_window_size = 100;
|
|
if(size.x < min_window_size) {
|
|
size.x = min_window_size;
|
|
} else if(size.x > screen_width_f32) {
|
|
size.x = screen_width_f32;
|
|
}
|
|
if(size.y < min_window_size) {
|
|
size.y = min_window_size;
|
|
} else if(size.y > screen_height_f32) {
|
|
size.y = screen_height_f32;
|
|
}
|
|
|
|
if (rl.isMouseButtonReleased(rl.MouseButton.left)) {
|
|
resizing.* = false;
|
|
}
|
|
}
|
|
// window and content drawing with scissor and scroll area
|
|
if(minimized.*) {
|
|
_ = rg.statusBar(rl.Rectangle{ .x = position.x, .y = position.y, .width = size.x, .height = WINDOW_STATUS_BAR_HEIGHT}, title_text);
|
|
|
|
if (rg.button(rl.Rectangle{ .x = position.x + size.x - WINDOW_CLOSE_BUTTON_SIZE - CLOSE_TITLE_SIZE_DELTA_HALF,
|
|
.y = position.y + CLOSE_TITLE_SIZE_DELTA_HALF,
|
|
.width = WINDOW_CLOSE_BUTTON_SIZE,
|
|
.height = WINDOW_CLOSE_BUTTON_SIZE},
|
|
"#120#")) {
|
|
minimized.* = false;
|
|
}
|
|
|
|
} else {
|
|
minimized.* = rg.windowBox(rl.Rectangle{ .x = position.x, .y = position.y, .width = size.x, .height = size.y}, title_text) > 0;
|
|
|
|
// scissor and draw content within a scroll panel
|
|
var scissor: rl.Rectangle = undefined;
|
|
_ = rg.scrollPanel(rl.Rectangle{ .x = position.x, .y = position.y + WINDOW_STATUS_BAR_HEIGHT, .width = size.x, .height = size.y - WINDOW_STATUS_BAR_HEIGHT},
|
|
null,
|
|
rl.Rectangle{ .x = position.x, .y = position.y, .width = content_size.x, .height = content_size.y },
|
|
scroll,
|
|
&scissor);
|
|
|
|
_ = rl.drawRectangleRec(scissor, rl.Color.gold);
|
|
|
|
const require_scissor = size.x < content_size.x or size.y < content_size.y;
|
|
|
|
if(require_scissor) {
|
|
rl.beginScissorMode(@intFromFloat(scissor.x), @intFromFloat(scissor.y), @intFromFloat(scissor.width), @intFromFloat(scissor.height));
|
|
}
|
|
|
|
draw_content(position.*, scroll.*);
|
|
|
|
if(require_scissor) {
|
|
rl.endScissorMode();
|
|
}
|
|
|
|
// draw the resize button/icon
|
|
_ = rg.drawIcon(71, @intFromFloat(position.x + size.x - 20), @intFromFloat(position.y + size.y - 20), 1, rl.Color.gray);
|
|
|
|
}
|
|
}
|
|
|
|
fn drawContent(position: rl.Vector2, window_scroll: rl.Vector2) void {
|
|
_ = rg.button(rl.Rectangle{ .x = position.x + 20 + window_scroll.x, .y = position.y + 50 + window_scroll.y, .width = 100, .height = 25 }, "Button 1");
|
|
_ = rg.button(rl.Rectangle{ .x = position.x + 20 + window_scroll.x, .y = position.y + 100 + window_scroll.y, .width = 100, .height = 25 }, "Button 2");
|
|
_ = rg.button(rl.Rectangle{ .x = position.x + 20 + window_scroll.x, .y = position.y + 150 + window_scroll.y, .width = 100, .height = 25 }, "Button 3");
|
|
_ = rg.label(rl.Rectangle{ .x = position.x + 20 + window_scroll.x, .y = position.y + 200 + window_scroll.y, .width = 250, .height = 25 }, "A Label");
|
|
_ = rg.label(rl.Rectangle{ .x = position.x + 20 + window_scroll.x, .y = position.y + 250 + window_scroll.y, .width = 250, .height = 25 }, "Another Label");
|
|
_ = rg.label(rl.Rectangle{ .x = position.x + 20 + window_scroll.x, .y = position.y + 300 + window_scroll.y, .width = 250, .height = 25 }, "Yet Another Label");
|
|
}
|
|
|
|
pub fn main() !void {
|
|
var window_position = rl.Vector2{ .x = 10, .y = 10};
|
|
var window2_position = rl.Vector2{ .x = 250, .y = 10};
|
|
var window_size = rl.Vector2{ .x = 200, .y = 400};
|
|
var window2_size = rl.Vector2{ .x = 200, .y = 400};
|
|
var minimized = false;
|
|
var minimized2 = false;
|
|
var moving = false;
|
|
var moving2 = false;
|
|
var resizing = false;
|
|
var resizing2 = false;
|
|
var scroll: rl.Vector2 = rl.Vector2{ .x = -1, .y = -1};
|
|
var scroll2: rl.Vector2 = rl.Vector2{ .x = -1, .y = -1};
|
|
|
|
rl.initWindow(960, 560, "raygui - floating window example");
|
|
rl.setTargetFPS(60);
|
|
|
|
while(!rl.windowShouldClose()) {
|
|
rl.beginDrawing();
|
|
defer rl.endDrawing();
|
|
floatingWindow(&window_position, &window_size, &minimized, &moving, &resizing, &drawContent, rl.Vector2{ .x = 140, .y = 320 }, &scroll, "Movable & Scalable Window");
|
|
floatingWindow(&window2_position, &window2_size, &minimized2, &moving2, &resizing2, &drawContent, rl.Vector2{ .x = 140, .y = 320 }, &scroll2, "Another window");
|
|
rl.clearBackground(rl.Color.ray_white);
|
|
}
|
|
|
|
rl.closeWindow();
|
|
} |