feat: make text follow touch/pointer
parent
c3d240358a
commit
1ba884d7b8
10
src/core.zig
10
src/core.zig
|
@ -309,6 +309,16 @@ pub const Surface = struct {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn frame(surface: Surface, callback: u32) !void {
|
||||||
|
try surface.conn.send(
|
||||||
|
Request,
|
||||||
|
surface.id,
|
||||||
|
.{ .frame = .{
|
||||||
|
.callback = callback,
|
||||||
|
} },
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
pub fn commit(surface: Surface) !void {
|
pub fn commit(surface: Surface) !void {
|
||||||
try surface.conn.send(
|
try surface.conn.send(
|
||||||
Request,
|
Request,
|
||||||
|
|
99
src/main.zig
99
src/main.zig
|
@ -114,6 +114,7 @@ pub fn main() !void {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
{
|
||||||
std.debug.assert(app.state == .run);
|
std.debug.assert(app.state == .run);
|
||||||
const pool = &app.state.run.pool;
|
const pool = &app.state.run.pool;
|
||||||
const width = app.state.run.width;
|
const width = app.state.run.width;
|
||||||
|
@ -124,6 +125,8 @@ pub fn main() !void {
|
||||||
canvas.renderGradient();
|
canvas.renderGradient();
|
||||||
try canvas.attach(surface);
|
try canvas.attach(surface);
|
||||||
try app.callbacks.put(canvas.buffer.id, bufferHandler);
|
try app.callbacks.put(canvas.buffer.id, bufferHandler);
|
||||||
|
}
|
||||||
|
try app.queue_redraw();
|
||||||
|
|
||||||
while (app.state != .close) {
|
while (app.state != .close) {
|
||||||
const header, const body = try conn.recv();
|
const header, const body = try conn.recv();
|
||||||
|
@ -152,6 +155,7 @@ const App = struct {
|
||||||
callbacks: std.AutoHashMap(u32, Callback),
|
callbacks: std.AutoHashMap(u32, Callback),
|
||||||
freetype_lib: freetype.Library,
|
freetype_lib: freetype.Library,
|
||||||
font_face: freetype.Face,
|
font_face: freetype.Face,
|
||||||
|
rerender: ?u32 = null,
|
||||||
|
|
||||||
display: wayland.core.Display,
|
display: wayland.core.Display,
|
||||||
shm: wayland.core.Shm,
|
shm: wayland.core.Shm,
|
||||||
|
@ -180,6 +184,14 @@ const App = struct {
|
||||||
x: f32,
|
x: f32,
|
||||||
y: f32,
|
y: f32,
|
||||||
},
|
},
|
||||||
|
point: ?struct {
|
||||||
|
x: f32 = 0,
|
||||||
|
y: f32 = 0,
|
||||||
|
} = null,
|
||||||
|
page_offset: struct {
|
||||||
|
x: f32,
|
||||||
|
y: f32,
|
||||||
|
},
|
||||||
},
|
},
|
||||||
close,
|
close,
|
||||||
},
|
},
|
||||||
|
@ -195,6 +207,15 @@ const App = struct {
|
||||||
app.callbacks.deinit();
|
app.callbacks.deinit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn queue_redraw(app: *App) !void {
|
||||||
|
if (app.rerender) |_| return;
|
||||||
|
const id = app.conn.id_pool.create();
|
||||||
|
app.rerender = id;
|
||||||
|
try app.surface.frame(id);
|
||||||
|
try app.callbacks.put(id, onFrame);
|
||||||
|
try app.surface.commit();
|
||||||
|
}
|
||||||
|
|
||||||
fn close(app: *App) void {
|
fn close(app: *App) void {
|
||||||
std.debug.assert(app.state == .run);
|
std.debug.assert(app.state == .run);
|
||||||
app.state.run.pool.deinit();
|
app.state.run.pool.deinit();
|
||||||
|
@ -216,6 +237,7 @@ const App = struct {
|
||||||
.pool = try Pool.init(app.ally, app.shm),
|
.pool = try Pool.init(app.ally, app.shm),
|
||||||
.keyboard = init.keyboard.?,
|
.keyboard = init.keyboard.?,
|
||||||
.mouse = .{ .x = 0, .y = 0 },
|
.mouse = .{ .x = 0, .y = 0 },
|
||||||
|
.page_offset = .{ .x = 0, .y = 0 },
|
||||||
} };
|
} };
|
||||||
|
|
||||||
try app.callbacks.put(app.state.run.keyboard.id, keyboardHandler);
|
try app.callbacks.put(app.state.run.keyboard.id, keyboardHandler);
|
||||||
|
@ -499,8 +521,7 @@ const Canvas = struct {
|
||||||
var x: i32 = @intCast(pos[0]);
|
var x: i32 = @intCast(pos[0]);
|
||||||
var y: i32 = @intCast(pos[1]);
|
var y: i32 = @intCast(pos[1]);
|
||||||
while (unicode_iter.nextCodepoint()) |codepoint| {
|
while (unicode_iter.nextCodepoint()) |codepoint| {
|
||||||
const glyph_index = face.getCharIndex(codepoint) orelse continue;
|
try face.loadChar(codepoint, .{ .render = true });
|
||||||
try face.loadGlyph(glyph_index, .{ .render = true });
|
|
||||||
const glyph = face.glyph();
|
const glyph = face.glyph();
|
||||||
const bitmap = glyph.bitmap();
|
const bitmap = glyph.bitmap();
|
||||||
canvas.blitFreetypeBitmap(bitmap, .{ @intCast(x + glyph.bitmapLeft()), @intCast(y - glyph.bitmapTop()) }, color);
|
canvas.blitFreetypeBitmap(bitmap, .{ @intCast(x + glyph.bitmapLeft()), @intCast(y - glyph.bitmapTop()) }, color);
|
||||||
|
@ -547,26 +568,32 @@ fn surfaceDesktopHandler(app: *App, header: wayland.Header, body: []const u32) !
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.configure => |conf| {
|
.configure => |conf| {
|
||||||
try app.xdg_surface.ack_configure(conf.serial);
|
try app.xdg_surface.ack_configure(conf.serial);
|
||||||
|
|
||||||
std.debug.assert(app.state == .run);
|
|
||||||
const pool = &app.state.run.pool;
|
|
||||||
const width = app.state.run.width;
|
|
||||||
const height = app.state.run.height;
|
|
||||||
|
|
||||||
// render
|
|
||||||
const canvas = try pool.getFramebuffer(.{ width, height });
|
|
||||||
canvas.renderGradient();
|
|
||||||
try canvas.print(app.font_face, "Hello, World!", .{ 10, 60 }, Color.White);
|
|
||||||
try canvas.attach(app.surface);
|
|
||||||
try app.callbacks.put(canvas.buffer.id, bufferHandler);
|
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn touchHandler(app: *App, header: wayland.Header, body: []const u32) !void {
|
fn touchHandler(app: *App, header: wayland.Header, body: []const u32) !void {
|
||||||
const event = try wayland.deserialize(wayland.core.Touch.Event, header, body);
|
const event = try wayland.deserialize(wayland.core.Touch.Event, header, body);
|
||||||
_ = app;
|
|
||||||
switch (event) {
|
switch (event) {
|
||||||
|
.frame => {},
|
||||||
|
.down => |touch| {
|
||||||
|
if (touch.id == 0) {
|
||||||
|
app.state.run.page_offset.x = @floatFromInt(touch.x >> 8);
|
||||||
|
app.state.run.page_offset.y = @floatFromInt(touch.y >> 8);
|
||||||
|
} else {
|
||||||
|
std.log.info("Non-zero touch id: {}", .{touch});
|
||||||
|
}
|
||||||
|
try app.queue_redraw();
|
||||||
|
},
|
||||||
|
.motion => |touch| {
|
||||||
|
if (touch.id == 0) {
|
||||||
|
app.state.run.page_offset.x = @floatFromInt(touch.x >> 8);
|
||||||
|
app.state.run.page_offset.y = @floatFromInt(touch.y >> 8);
|
||||||
|
} else {
|
||||||
|
std.log.info("Non-zero touch id: {}", .{touch});
|
||||||
|
}
|
||||||
|
try app.queue_redraw();
|
||||||
|
},
|
||||||
else => {
|
else => {
|
||||||
std.log.info("touch event: {}", .{event});
|
std.log.info("touch event: {}", .{event});
|
||||||
},
|
},
|
||||||
|
@ -577,13 +604,15 @@ fn pointerHandler(app: *App, header: wayland.Header, body: []const u32) !void {
|
||||||
const event = try wayland.deserialize(wayland.core.Pointer.Event, header, body);
|
const event = try wayland.deserialize(wayland.core.Pointer.Event, header, body);
|
||||||
switch (event) {
|
switch (event) {
|
||||||
.enter => |enter| {
|
.enter => |enter| {
|
||||||
app.state.run.mouse.x = @floatFromInt(enter.surface_x);
|
app.state.run.page_offset.x = @floatFromInt(enter.surface_x >> 8);
|
||||||
app.state.run.mouse.y = @floatFromInt(enter.surface_y);
|
app.state.run.page_offset.y = @floatFromInt(enter.surface_y >> 8);
|
||||||
|
try app.queue_redraw();
|
||||||
},
|
},
|
||||||
.leave => |_| {},
|
.leave => |_| {},
|
||||||
.motion => |motion| {
|
.motion => |motion| {
|
||||||
app.state.run.mouse.x = @floatFromInt(motion.surface_x);
|
app.state.run.page_offset.x = @floatFromInt(motion.surface_x >> 8);
|
||||||
app.state.run.mouse.y = @floatFromInt(motion.surface_y);
|
app.state.run.page_offset.y = @floatFromInt(motion.surface_y >> 8);
|
||||||
|
try app.queue_redraw();
|
||||||
},
|
},
|
||||||
else => {
|
else => {
|
||||||
std.log.info("pointer event: {}", .{event});
|
std.log.info("pointer event: {}", .{event});
|
||||||
|
@ -623,3 +652,35 @@ fn bufferHandler(app: *App, header: wayland.Header, body: []const u32) !void {
|
||||||
const pool = &app.state.run.pool;
|
const pool = &app.state.run.pool;
|
||||||
try pool.freeFramebuffer(header.object_id);
|
try pool.freeFramebuffer(header.object_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn onFrame(app: *App, header: wayland.Header, body: []const u32) !void {
|
||||||
|
_, _ = .{ header, body };
|
||||||
|
app.rerender = null;
|
||||||
|
|
||||||
|
std.debug.assert(app.state == .run);
|
||||||
|
const pool = &app.state.run.pool;
|
||||||
|
const width = app.state.run.width;
|
||||||
|
const height = app.state.run.height;
|
||||||
|
|
||||||
|
// render
|
||||||
|
const canvas = try pool.getFramebuffer(.{ width, height });
|
||||||
|
canvas.renderGradient();
|
||||||
|
var offsetx: u32 = if (app.state.run.page_offset.x >= 0) @intFromFloat(app.state.run.page_offset.x) else 0;
|
||||||
|
var offsety: u32 = if (app.state.run.page_offset.y >= 0) @intFromFloat(app.state.run.page_offset.y) else 0;
|
||||||
|
if (app.state.run.point) |point| {
|
||||||
|
offsetx -|= @intFromFloat(point.x);
|
||||||
|
offsety -|= @intFromFloat(point.y);
|
||||||
|
}
|
||||||
|
std.log.info("Calculated page offset: {}, {}", .{ offsetx, offsety });
|
||||||
|
try canvas.print(
|
||||||
|
app.font_face,
|
||||||
|
"Hello, World!",
|
||||||
|
.{
|
||||||
|
offsetx + 10,
|
||||||
|
offsety + 60,
|
||||||
|
},
|
||||||
|
Color.White,
|
||||||
|
);
|
||||||
|
try canvas.attach(app.surface);
|
||||||
|
try app.callbacks.put(canvas.buffer.id, bufferHandler);
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue