proper output of selected rect
This commit is contained in:
parent
cc205d45df
commit
78955de959
173
main.zig
173
main.zig
|
@ -274,7 +274,6 @@ const Output = struct {
|
|||
self.output.destroy();
|
||||
}
|
||||
|
||||
|
||||
fn setSourceU32(c: *Cairo.cairo_t, color: u32) void {
|
||||
Cairo.cairo_set_source_rgba(
|
||||
c,
|
||||
|
@ -299,7 +298,7 @@ const Output = struct {
|
|||
|
||||
fn drawDimensions(self: *Self, c: *Cairo.cairo_t, color: u32, box: *const Box) void {
|
||||
const opts = self.state.getOptions();
|
||||
const font_family = if (opts.@"font-family") |ff| ff.ptr else null;
|
||||
const font_family = opts.@"font-family".ptr;
|
||||
Cairo.cairo_select_font_face(c,
|
||||
font_family,
|
||||
Cairo.CAIRO_FONT_SLANT_NORMAL,
|
||||
|
@ -528,7 +527,7 @@ const Seat = struct {
|
|||
|
||||
pointer: ?struct {
|
||||
pointer: *wl.Pointer,
|
||||
current_surface_offset: ?Point = null,
|
||||
current_surface_geom: ?Box = null,
|
||||
stage: SelectionStage = .Edit,
|
||||
selection: SelectionState = SelectionState.None(),
|
||||
} = null,
|
||||
|
@ -614,21 +613,21 @@ const Seat = struct {
|
|||
switch (event) {
|
||||
.enter => |enter| {
|
||||
if (self.state.getOutputForSurface(enter.surface.?)) |output| {
|
||||
self.pointer.?.current_surface_offset = output.logical_geometry.position;
|
||||
self.pointer.?.current_surface_geom = output.logical_geometry;
|
||||
}
|
||||
|
||||
std.debug.print("surface offset: {?}\n", .{self.pointer.?.current_surface_offset});
|
||||
std.debug.print("surface geom: {?}\n", .{self.pointer.?.current_surface_geom});
|
||||
},
|
||||
.leave => {
|
||||
self.pointer.?.current_surface_offset = null;
|
||||
self.pointer.?.current_surface_geom = null;
|
||||
},
|
||||
.motion => |motion| {
|
||||
const x = motion.surface_x.toInt();
|
||||
const y = motion.surface_y.toInt();
|
||||
const xy = Point{.x = x, .y = y,};
|
||||
|
||||
if (self.pointer.?.current_surface_offset) |offset| {
|
||||
const point = xy.added(offset);
|
||||
if (self.pointer.?.current_surface_geom) |geom| {
|
||||
const point = xy.added(geom.position);
|
||||
|
||||
switch (self.pointer.?.stage) {
|
||||
.Edit => {
|
||||
|
@ -676,7 +675,7 @@ const Seat = struct {
|
|||
.updating => |selection| {
|
||||
const box = selection.asBox();
|
||||
self.pointer.?.selection = .{.post = box};
|
||||
return self.calculateRedraws();
|
||||
return self.state.finish(box, self.pointer.?.current_surface_geom.?);
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
|
@ -1116,9 +1115,44 @@ const State = struct {
|
|||
}
|
||||
}
|
||||
|
||||
fn finish(self: *Self, box: Box) void {
|
||||
_ = self;
|
||||
_ = box;
|
||||
fn finish(self: *Self, box: Box, surface_geom: Box) void {
|
||||
self.running = false;
|
||||
|
||||
const format = OutputFormat.fromFormatStr(self.ally, self.getOptions().format) catch return;
|
||||
var iter = format.iter();
|
||||
|
||||
const stdout = std.io.getStdOut().writer();
|
||||
while (iter.next()) |entry| {
|
||||
if (entry.piece) |piece| {
|
||||
_ = stdout.write(piece) catch return;
|
||||
}
|
||||
if (entry.arg) |arg| {
|
||||
switch (arg) {
|
||||
.X => {stdout.print("{}", .{box.getX(i32)}) catch return;},
|
||||
.Y => {stdout.print("{}", .{box.getY(i32)}) catch return;},
|
||||
.Width => {stdout.print("{}", .{box.getWidth(u32)}) catch return;},
|
||||
.Height => {stdout.print("{}", .{box.getHeight(u32)}) catch return;},
|
||||
.XRel => {stdout.print("{}", .{box.getX(i32) - surface_geom.getX(i32)}) catch return;},
|
||||
.YRel => {stdout.print("{}", .{box.getY(i32) - surface_geom.getY(i32)}) catch return;},
|
||||
.WidthClamped => {
|
||||
stdout.print(
|
||||
"{}",
|
||||
.{@min(box.getWidth(i32),
|
||||
surface_geom.getRightMost(i32) - box.getX(i32))},
|
||||
) catch return;
|
||||
},
|
||||
.HeightClamped=> {
|
||||
stdout.print(
|
||||
"{}",
|
||||
.{@min(box.getHeight(i32),
|
||||
surface_geom.getBottomMost(i32) - box.getY(i32))},
|
||||
) catch return;
|
||||
},
|
||||
// TODO: implement label and outputname
|
||||
}
|
||||
}
|
||||
}
|
||||
_ = stdout.write("\n") catch null;
|
||||
}
|
||||
|
||||
fn removeOutput(self: *Self, output: *Output) void {
|
||||
|
@ -1184,8 +1218,8 @@ const Args = struct {
|
|||
border: u32 = 0x000000FF,
|
||||
selection: u32 = 0x00000000,
|
||||
choice: u32 = 0xFFFFFF40,
|
||||
format: ?[]const u8 = "%x,%y %wx%h\n",
|
||||
@"font-family": ?[]const u8 = "sans-serif",
|
||||
format: []const u8 = "%x,%y %wx%h\n",
|
||||
@"font-family": [:0]const u8 = "sans-serif",
|
||||
@"border-weight": u32 = 2,
|
||||
@"single-point": bool = false,
|
||||
@"output-boxes": bool = false,
|
||||
|
@ -1280,3 +1314,114 @@ pub fn run(ally: std.mem.Allocator) !void {
|
|||
pub fn main() !void {
|
||||
try run(std.heap.c_allocator);
|
||||
}
|
||||
|
||||
const OutputFormat = struct {
|
||||
const Self = @This();
|
||||
|
||||
const Arg = enum {
|
||||
X,
|
||||
Y,
|
||||
Width,
|
||||
Height,
|
||||
XRel,
|
||||
YRel,
|
||||
WidthClamped,
|
||||
HeightClamped,
|
||||
// TODO:
|
||||
// OutputName,
|
||||
// SelectionName,
|
||||
|
||||
fn fromChar(c: u8) ?Arg {
|
||||
switch (c) {
|
||||
'x' => {return .X;},
|
||||
'y' => {return .Y;},
|
||||
'X' => {return .XRel;},
|
||||
'Y' => {return .YRel;},
|
||||
'w' => {return .Width;},
|
||||
'h' => {return .Height;},
|
||||
'W' => {return .WidthClamped;},
|
||||
'H' => {return .HeightClamped;},
|
||||
else => {return null;},
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
const Entry = struct {piece: ?[]const u8, arg: Arg};
|
||||
|
||||
list: std.ArrayList(Entry),
|
||||
last_piece: ?[]const u8,
|
||||
|
||||
const Iterator = struct {
|
||||
format: Self,
|
||||
i: usize = 0,
|
||||
|
||||
pub fn next(self: *@This()) ?struct {piece: ?[]const u8, arg: ?Arg} {
|
||||
const items = self.format.list.items;
|
||||
if (self.i < items.len) {
|
||||
const item = &items[self.i];
|
||||
self.i += 1;
|
||||
|
||||
return .{.piece = item.piece, .arg = item.arg};
|
||||
} else if (self.i == items.len and self.format.last_piece != null) {
|
||||
self.i += 1;
|
||||
return .{.piece = self.format.last_piece, .arg = null};
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
fn iter(self: Self) Iterator {
|
||||
return .{
|
||||
.format = self,
|
||||
};
|
||||
}
|
||||
|
||||
fn deinit(self: Self) void {
|
||||
self.list.deinit();
|
||||
}
|
||||
|
||||
/// this does not copy! returned object is only valid as long as 'str' is valid.
|
||||
fn fromFormatStr(ally: std.mem.Allocator, str: []const u8) !Self {
|
||||
var window: struct {start: usize, end: usize} = .{.start = 0, .end = 0};
|
||||
var pieces = std.ArrayList(Entry).init(ally);
|
||||
|
||||
var i: usize = 0;
|
||||
while (i < str.len) {
|
||||
defer i += 1;
|
||||
const c = str[i];
|
||||
|
||||
window.end = i;
|
||||
|
||||
if (c == '%') {
|
||||
if (str.len > i) {
|
||||
i += 1;
|
||||
if (Arg.fromChar(str[i])) |arg| {
|
||||
const piece = if (window.start != window.end) str[window.start..window.end] else null;
|
||||
window.start = i + 1;
|
||||
window.end = i + 1;
|
||||
|
||||
std.debug.print("piece: '{?s}', arg: {?}\n", .{piece, arg});
|
||||
try pieces.append(.{.piece = piece, .arg = arg});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const last_piece = if (window.start != window.end) str[window.start..window.end] else null;
|
||||
std.debug.print("piece: '{?s}'\n", .{last_piece});
|
||||
|
||||
return Self{
|
||||
.list = pieces,
|
||||
.last_piece = last_piece,
|
||||
};
|
||||
}
|
||||
};
|
||||
|
||||
test "format parsing" {
|
||||
const ally = std.testing.allocator;
|
||||
const a = try OutputFormat.fromFormatStr(ally, "%x,%y blob %wx%h");
|
||||
defer a.deinit();
|
||||
const b = try OutputFormat.fromFormatStr(ally, "%t,%y blob %wx%h");
|
||||
defer b.deinit();
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue