tangled
alpha
login
or
join now
rockorager.dev
/
comlink
2
fork
atom
an experimental irc client
2
fork
atom
overview
issues
pulls
pipelines
channel: improve name drawing
rockorager.dev
1 year ago
ffdfcdf8
d1ec276f
+51
-25
2 changed files
expand all
collapse all
unified
split
src
app.zig
irc.zig
+1
-12
src/app.zig
···
287
287
}
288
288
i += 1;
289
289
for (client.channels.items) |channel| {
290
290
-
if (i == idx and i == cursor) {
291
291
-
return .{
292
292
-
.userdata = channel,
293
293
-
.drawFn = irc.Channel.drawNameSelected,
294
294
-
};
295
295
-
}
296
296
-
if (i == idx) {
297
297
-
return .{
298
298
-
.userdata = channel,
299
299
-
.drawFn = irc.Channel.drawName,
300
300
-
};
301
301
-
}
290
290
+
if (i == idx) return channel.nameWidget(i == cursor);
302
291
i += 1;
303
292
}
304
293
}
+50
-13
src/irc.zig
···
117
117
has_unread: bool = false,
118
118
has_unread_highlight: bool = false,
119
119
120
120
+
has_mouse: bool = false,
121
121
+
120
122
pub const Member = struct {
121
123
user: *User,
122
124
···
168
170
return l < r;
169
171
}
170
172
171
171
-
pub fn drawName(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
173
173
+
pub fn nameWidget(self: *Channel, selected: bool) vxfw.Widget {
174
174
+
return .{
175
175
+
.userdata = self,
176
176
+
.eventHandler = Channel.typeErasedEventHandler,
177
177
+
.drawFn = if (selected)
178
178
+
Channel.typeErasedDrawNameSelected
179
179
+
else
180
180
+
Channel.typeErasedDrawName,
181
181
+
};
182
182
+
}
183
183
+
184
184
+
fn typeErasedEventHandler(ptr: *anyopaque, ctx: *vxfw.EventContext, event: vxfw.Event) anyerror!void {
172
185
const self: *Channel = @ptrCast(@alignCast(ptr));
186
186
+
switch (event) {
187
187
+
.mouse => {
188
188
+
try ctx.setMouseShape(.pointer);
189
189
+
},
190
190
+
.mouse_enter => {
191
191
+
try ctx.setMouseShape(.pointer);
192
192
+
self.has_mouse = true;
193
193
+
},
194
194
+
.mouse_leave => {
195
195
+
try ctx.setMouseShape(.default);
196
196
+
self.has_mouse = false;
197
197
+
},
198
198
+
else => {},
199
199
+
}
200
200
+
}
201
201
+
202
202
+
pub fn drawName(self: *Channel, ctx: vxfw.DrawContext, selected: bool) Allocator.Error!vxfw.Surface {
203
203
+
const style: vaxis.Style = if (selected)
204
204
+
.{ .reverse = true }
205
205
+
else if (self.has_mouse)
206
206
+
.{ .bg = .{ .index = 8 } }
207
207
+
else
208
208
+
.{};
173
209
const text: vxfw.RichText = .{
174
210
.text = &.{
175
175
-
.{ .text = " " },
176
176
-
.{ .text = self.name },
211
211
+
.{ .text = " ", .style = style },
212
212
+
.{ .text = self.name, .style = style },
177
213
},
178
214
.softwrap = false,
179
215
};
180
180
-
return text.draw(ctx);
216
216
+
var surface = try text.draw(ctx);
217
217
+
// Replace the widget reference so we can handle the events
218
218
+
surface.widget = self.nameWidget(selected);
219
219
+
return surface;
220
220
+
}
221
221
+
222
222
+
fn typeErasedDrawName(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
223
223
+
const self: *Channel = @ptrCast(@alignCast(ptr));
224
224
+
return self.drawName(ctx, false);
181
225
}
182
226
183
183
-
pub fn drawNameSelected(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
227
227
+
fn typeErasedDrawNameSelected(ptr: *anyopaque, ctx: vxfw.DrawContext) Allocator.Error!vxfw.Surface {
184
228
const self: *Channel = @ptrCast(@alignCast(ptr));
185
185
-
const text: vxfw.RichText = .{
186
186
-
.text = &.{
187
187
-
.{ .text = " ", .style = .{ .reverse = true } },
188
188
-
.{ .text = self.name, .style = .{ .reverse = true } },
189
189
-
},
190
190
-
.softwrap = false,
191
191
-
};
192
192
-
return text.draw(ctx);
229
229
+
return self.drawName(ctx, true);
193
230
}
194
231
195
232
pub fn sortMembers(self: *Channel) void {