Skip to content

Commit

Permalink
Add mobile device 'emulation'
Browse files Browse the repository at this point in the history
By passing the ZGT_MOBILE_EMULATED environment variable, zgt
will force the window size and source DPI to be equal to the
given phone's one. In the future, this will allow testing
responsive design easily and with slow compile times.
In essence, this is similar to Chrome's and Firefox's
mobile emulation mode.
  • Loading branch information
zenith391 committed Jul 17, 2022
1 parent 79c72eb commit 1279128
Show file tree
Hide file tree
Showing 2 changed files with 57 additions and 4 deletions.
14 changes: 13 additions & 1 deletion src/backends/gtk/backend.zig
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ pub const Window = struct {
/// A VBox is required to contain the menu and the window's child (wrapped in wbin)
vbox: *c.GtkWidget,
menuBar: ?*c.GtkWidget = null,
source_dpi: u32 = 96,
scale: f32 = 1.0,

pub usingnamespace Events(Window);

Expand All @@ -79,7 +81,9 @@ pub const Window = struct {
}

pub fn resize(self: *Window, width: c_int, height: c_int) void {
c.gtk_window_resize(@ptrCast(*c.GtkWindow, self.peer), width, height);
c.gtk_window_resize(@ptrCast(*c.GtkWindow, self.peer),
@floatToInt(c_int, @intToFloat(f32, width) * self.scale),
@floatToInt(c_int, @intToFloat(f32, height) * self.scale));
}

pub fn setTitle(self: *Window, title: [*:0]const u8) void {
Expand Down Expand Up @@ -107,6 +111,14 @@ pub const Window = struct {
self.menuBar = menuBar;
}

pub fn setSourceDpi(self: *Window, dpi: u32) void {
self.source_dpi = 96;
// TODO: Handle GtkWindow moving between screens with different DPIs
const resolution = @as(f32, 96.0);
self.scale = resolution / @intToFloat(f32, dpi);
std.log.debug("Scale: {d}", .{ self.scale });
}

fn initMenu(menu: *c.GtkMenuShell, items: []const lib.MenuItem_Impl) void {
for (items) |item| {
const menuItem = c.gtk_menu_item_new_with_label(item.config.label);
Expand Down
47 changes: 44 additions & 3 deletions src/window.zig
Original file line number Diff line number Diff line change
@@ -1,18 +1,33 @@
const std = @import("std");
const backend = @import("backend.zig");
const internal = @import("internal.zig");
const Widget = @import("widget.zig").Widget;
const ImageData = @import("image.zig").ImageData;
const MenuBar_Impl = @import("menu.zig").MenuBar_Impl;
const Size = @import("data.zig").Size;

const Display = struct {
resolution: Size,
dpi: u32
};

const devices = std.ComptimeStringMap(Display, .{
.{ "iphone-13-mini", .{ .resolution = Size.init(1080, 2340), .dpi = 476 }},
.{ "iphone-13", .{ .resolution = Size.init(1170, 2532), .dpi = 460 }},
.{ "pixel-6", .{ .resolution = Size.init(1080, 2400), .dpi = 411 }},
.{ "pixel-6-pro", .{ .resolution = Size.init(1440, 3120), .dpi = 512 }},
});

pub const Window = struct {
/// The DPI the GUI has been developed against
source_dpi: u32 = 96,
peer: backend.Window,
_child: ?Widget = null,

pub fn init() !Window {
const peer = try backend.Window.create();
return Window{ .peer = peer };
var window = Window{ .peer = peer };
window.setSourceDpi(96);
window.resize(640, 480);
return window;
}

pub fn show(self: *Window) void {
Expand Down Expand Up @@ -53,7 +68,28 @@ pub const Window = struct {
return self._child;
}

var did_invalid_warning = false;

pub fn resize(self: *Window, width: u32, height: u32) void {
const EMULATOR_KEY = "ZGT_MOBILE_EMULATION";
if (std.process.hasEnvVarConstant(EMULATOR_KEY)) {
const id = std.process.getEnvVarOwned(
internal.scratch_allocator, EMULATOR_KEY) catch unreachable;
defer internal.scratch_allocator.free(id);
if (devices.get(id)) |device| {
self.peer.resize(@intCast(c_int, device.resolution.width),
@intCast(c_int, device.resolution.height));
self.setSourceDpi(device.dpi);
return;
} else if (!did_invalid_warning) {
std.log.warn("Invalid property \"" ++ EMULATOR_KEY ++ "={s}\"", .{ id });
std.debug.print("Expected one of:\r\n", .{});
for (devices.kvs) |entry| {
std.debug.print(" - {s}\r\n", .{ entry.key });
}
did_invalid_warning = true;
}
}
self.peer.resize(@intCast(c_int, width), @intCast(c_int, height));
}

Expand All @@ -73,6 +109,11 @@ pub const Window = struct {
self.peer.setMenuBar(bar);
}

/// Specify for which DPI the GUI was developed against.
pub fn setSourceDpi(self: *Window, dpi: u32) void {
self.peer.setSourceDpi(dpi);
}

pub fn deinit(self: *Window) void {
if (self._child) |*child| {
child.deinit();
Expand Down

0 comments on commit 1279128

Please sign in to comment.