Add Farsi Bigclock (#673)

* Change config type for bigclock

* Seprates big clock's hard codes from its logic

* Adds Farsi (fa) to big clock langs

* Minor changes

* Makes requested changes
This commit is contained in:
Kian A. 2024-08-07 18:17:27 +03:30 committed by GitHub
parent 2bd0d0d4f3
commit 00c94f8ffd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 272 additions and 117 deletions

View File

@ -51,8 +51,11 @@ auth_fails = 10
# Background color id # Background color id
bg = 0x0000 bg = 0x0000
# Enable/disable big clock # Change the state and language of the big clock
bigclock = false # none -> Disabled (default)
# en -> English
# fa -> Farsi
bigclock = none
# Blank main box background # Blank main box background
# Setting to false will make it transparent # Setting to false will make it transparent

View File

@ -1,111 +1,24 @@
const std = @import("std"); const std = @import("std");
const builtin = @import("builtin");
const interop = @import("interop.zig"); const interop = @import("interop.zig");
const utils = @import("tui/utils.zig"); const utils = @import("tui/utils.zig");
const enums = @import("enums.zig");
const Lang = @import("bigclock/Lang.zig");
const en = @import("bigclock/en.zig");
const fa = @import("bigclock/fa.zig");
const termbox = interop.termbox; const termbox = interop.termbox;
const Bigclock = enums.Bigclock;
pub const WIDTH = Lang.WIDTH;
pub const HEIGHT = Lang.HEIGHT;
pub const SIZE = Lang.SIZE;
const X: u32 = if (builtin.os.tag == .linux or builtin.os.tag.isBSD()) 0x2593 else '#'; pub fn clockCell(animate: bool, char: u8, fg: u16, bg: u16, bigclock: Bigclock) [SIZE]utils.Cell {
const O: u32 = 0;
pub const WIDTH = 5;
pub const HEIGHT = 5;
pub const SIZE = WIDTH * HEIGHT;
// zig fmt: off
const ZERO = [_]u21{
X,X,X,X,X,
X,X,O,X,X,
X,X,O,X,X,
X,X,O,X,X,
X,X,X,X,X,
};
const ONE = [_]u21{
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
};
const TWO = [_]u21{
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
X,X,O,O,O,
X,X,X,X,X,
};
const THREE = [_]u21{
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
};
const FOUR = [_]u21{
X,X,O,X,X,
X,X,O,X,X,
X,X,X,X,X,
O,O,O,X,X,
O,O,O,X,X,
};
const FIVE = [_]u21{
X,X,X,X,X,
X,X,O,O,O,
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
};
const SIX = [_]u21{
X,X,X,X,X,
X,X,O,O,O,
X,X,X,X,X,
X,X,O,X,X,
X,X,X,X,X,
};
const SEVEN = [_]u21{
X,X,X,X,X,
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
};
const EIGHT = [_]u21{
X,X,X,X,X,
X,X,O,X,X,
X,X,X,X,X,
X,X,O,X,X,
X,X,X,X,X,
};
const NINE = [_]u21{
X,X,X,X,X,
X,X,O,X,X,
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
};
const S = [_]u21{
O,O,O,O,O,
O,O,X,O,O,
O,O,O,O,O,
O,O,X,O,O,
O,O,O,O,O,
};
const E = [_]u21{
O,O,O,O,O,
O,O,O,O,O,
O,O,O,O,O,
O,O,O,O,O,
O,O,O,O,O,
};
// zig fmt: on
pub fn clockCell(animate: bool, char: u8, fg: u16, bg: u16) [SIZE]utils.Cell {
var cells: [SIZE]utils.Cell = undefined; var cells: [SIZE]utils.Cell = undefined;
var tv: interop.system_time.timeval = undefined; var tv: interop.system_time.timeval = undefined;
_ = interop.system_time.gettimeofday(&tv, null); _ = interop.system_time.gettimeofday(&tv, null);
const clock_chars = toBigNumber(if (animate and char == ':' and @divTrunc(tv.tv_usec, 500000) != 0) ' ' else char); const clock_chars = toBigNumber(if (animate and char == ':' and @divTrunc(tv.tv_usec, 500000) != 0) ' ' else char, bigclock);
for (0..cells.len) |i| cells[i] = utils.initCell(clock_chars[i], fg, bg); for (0..cells.len) |i| cells[i] = utils.initCell(clock_chars[i], fg, bg);
return cells; return cells;
@ -122,19 +35,24 @@ pub fn alphaBlit(x: usize, y: usize, tb_width: usize, tb_height: usize, cells: [
} }
} }
fn toBigNumber(char: u8) []const u21 { fn toBigNumber(char: u8, bigclock: Bigclock) []const u21 {
const locale_chars = switch (bigclock) {
.fa => fa.locale_chars,
.en => en.locale_chars,
.none => unreachable,
};
return switch (char) { return switch (char) {
'0' => &ZERO, '0' => &locale_chars.ZERO,
'1' => &ONE, '1' => &locale_chars.ONE,
'2' => &TWO, '2' => &locale_chars.TWO,
'3' => &THREE, '3' => &locale_chars.THREE,
'4' => &FOUR, '4' => &locale_chars.FOUR,
'5' => &FIVE, '5' => &locale_chars.FIVE,
'6' => &SIX, '6' => &locale_chars.SIX,
'7' => &SEVEN, '7' => &locale_chars.SEVEN,
'8' => &EIGHT, '8' => &locale_chars.EIGHT,
'9' => &NINE, '9' => &locale_chars.NINE,
':' => &S, ':' => &locale_chars.S,
else => &E, else => &locale_chars.E,
}; };
} }

23
src/bigclock/Lang.zig Normal file
View File

@ -0,0 +1,23 @@
const builtin = @import("builtin");
pub const WIDTH = 5;
pub const HEIGHT = 5;
pub const SIZE = WIDTH * HEIGHT;
pub const X: u32 = if (builtin.os.tag == .linux or builtin.os.tag.isBSD()) 0x2593 else '#';
pub const O: u32 = 0;
pub const LocaleChars = struct {
ZERO: [SIZE]u21,
ONE: [SIZE]u21,
TWO: [SIZE]u21,
THREE: [SIZE]u21,
FOUR: [SIZE]u21,
FIVE: [SIZE]u21,
SIX: [SIZE]u21,
SEVEN: [SIZE]u21,
EIGHT: [SIZE]u21,
NINE: [SIZE]u21,
S: [SIZE]u21,
E: [SIZE]u21,
};

94
src/bigclock/en.zig Normal file
View File

@ -0,0 +1,94 @@
const Lang = @import("Lang.zig");
const LocaleChars = Lang.LocaleChars;
const X = Lang.X;
const O = Lang.O;
// zig fmt: off
pub const locale_chars = LocaleChars{
.ZERO = [_]u21{
X,X,X,X,X,
X,X,O,X,X,
X,X,O,X,X,
X,X,O,X,X,
X,X,X,X,X,
},
.ONE = [_]u21{
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
},
.TWO = [_]u21{
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
X,X,O,O,O,
X,X,X,X,X,
},
.THREE = [_]u21{
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
},
.FOUR = [_]u21{
X,X,O,X,X,
X,X,O,X,X,
X,X,X,X,X,
O,O,O,X,X,
O,O,O,X,X,
},
.FIVE = [_]u21{
X,X,X,X,X,
X,X,O,O,O,
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
},
.SIX = [_]u21{
X,X,X,X,X,
X,X,O,O,O,
X,X,X,X,X,
X,X,O,X,X,
X,X,X,X,X,
},
.SEVEN = [_]u21{
X,X,X,X,X,
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
O,O,O,X,X,
},
.EIGHT = [_]u21{
X,X,X,X,X,
X,X,O,X,X,
X,X,X,X,X,
X,X,O,X,X,
X,X,X,X,X,
},
.NINE = [_]u21{
X,X,X,X,X,
X,X,O,X,X,
X,X,X,X,X,
O,O,O,X,X,
X,X,X,X,X,
},
.S = [_]u21{
O,O,O,O,O,
O,O,X,O,O,
O,O,O,O,O,
O,O,X,O,O,
O,O,O,O,O,
},
.E = [_]u21{
O,O,O,O,O,
O,O,O,O,O,
O,O,O,O,O,
O,O,O,O,O,
O,O,O,O,O,
},
};
// zig fmt: on

94
src/bigclock/fa.zig Normal file
View File

@ -0,0 +1,94 @@
const Lang = @import("Lang.zig");
const LocaleChars = Lang.LocaleChars;
const X = Lang.X;
const O = Lang.O;
// zig fmt: off
pub const locale_chars = LocaleChars{
.ZERO = [_]u21{
O,O,O,O,O,
O,O,X,O,O,
O,X,O,X,O,
O,O,X,O,O,
O,O,O,O,O,
},
.ONE = [_]u21{
O,O,X,O,O,
O,X,X,O,O,
O,O,X,O,O,
O,O,X,O,O,
O,O,X,O,O,
},
.TWO = [_]u21{
O,X,O,X,O,
O,X,X,X,O,
O,X,O,O,O,
O,X,O,O,O,
O,X,O,O,O,
},
.THREE = [_]u21{
X,O,X,O,X,
X,X,X,X,X,
X,O,O,O,O,
X,O,O,O,O,
X,O,O,O,O,
},
.FOUR = [_]u21{
O,X,O,X,X,
O,X,X,O,O,
O,X,X,X,X,
O,X,O,O,O,
O,X,O,O,O,
},
.FIVE = [_]u21{
O,O,X,X,O,
O,X,O,O,X,
X,O,O,O,X,
X,O,X,O,X,
O,X,O,X,O,
},
.SIX = [_]u21{
O,X,X,O,O,
O,X,O,O,X,
O,O,X,O,O,
O,X,O,O,O,
X,O,O,O,O,
},
.SEVEN = [_]u21{
X,O,O,O,X,
X,O,O,O,X,
O,X,O,X,O,
O,X,O,X,O,
O,O,X,O,O,
},
.EIGHT = [_]u21{
O,O,O,X,O,
O,O,X,O,X,
O,O,X,O,X,
O,X,O,O,X,
O,X,O,O,X,
},
.NINE = [_]u21{
O,X,X,X,O,
O,X,O,X,O,
O,X,X,X,O,
O,O,O,X,O,
O,O,O,X,O,
},
.S = [_]u21{
O,O,O,O,O,
O,O,X,O,O,
O,O,O,O,O,
O,O,X,O,O,
O,O,O,O,O,
},
.E = [_]u21{
O,O,O,O,O,
O,O,O,O,O,
O,O,O,O,O,
O,O,O,O,O,
O,O,O,O,O,
},
};
// zig fmt: on

View File

@ -4,13 +4,14 @@ const enums = @import("../enums.zig");
const Animation = enums.Animation; const Animation = enums.Animation;
const Input = enums.Input; const Input = enums.Input;
const ViMode = enums.ViMode; const ViMode = enums.ViMode;
const Bigclock = enums.Bigclock;
animation: Animation = .none, animation: Animation = .none,
animation_timeout_sec: u12 = 0, animation_timeout_sec: u12 = 0,
asterisk: ?u8 = '*', asterisk: ?u8 = '*',
auth_fails: u64 = 10, auth_fails: u64 = 10,
bg: u16 = 0, bg: u16 = 0,
bigclock: bool = false, bigclock: Bigclock = .none,
blank_box: bool = true, blank_box: bool = true,
border_fg: u16 = 8, border_fg: u16 = 8,
box_title: ?[]const u8 = null, box_title: ?[]const u8 = null,

View File

@ -85,6 +85,22 @@ pub fn configFieldHandler(_: std.mem.Allocator, field: ini.IniField) ?ini.IniFie
return null; return null;
} }
if (std.mem.eql(u8, field.key, "bigclock")) {
// The option now uses a string (which then gets converted into an enum) instead of an boolean
// It also includes the ability to change active bigclock's language
var mapped_field = field;
if (std.mem.eql(u8, field.value, "true")){
mapped_field.value = "en";
mapped_config_fields = true;
}else if (std.mem.eql(u8, field.value, "false")){
mapped_field.value = "none";
mapped_config_fields = true;
}
return mapped_field;
}
return field; return field;
} }

View File

@ -22,3 +22,9 @@ pub const ViMode = enum {
normal, normal,
insert, insert,
}; };
pub const Bigclock = enum {
none,
en,
fa,
};

View File

@ -385,7 +385,7 @@ pub fn main() !void {
} }
} }
if (config.bigclock and buffer.box_height + (bigclock.HEIGHT + 2) * 2 < buffer.height) draw_big_clock: { if (config.bigclock != .none and buffer.box_height + (bigclock.HEIGHT + 2) * 2 < buffer.height) draw_big_clock: {
const format = "%H:%M"; const format = "%H:%M";
const xo = buffer.width / 2 - @min(buffer.width, (format.len * (bigclock.WIDTH + 1))) / 2; const xo = buffer.width / 2 - @min(buffer.width, (format.len * (bigclock.WIDTH + 1))) / 2;
const yo = (buffer.height - buffer.box_height) / 2 - bigclock.HEIGHT - 2; const yo = (buffer.height - buffer.box_height) / 2 - bigclock.HEIGHT - 2;
@ -396,7 +396,7 @@ pub fn main() !void {
}; };
for (clock_str, 0..) |c, i| { for (clock_str, 0..) |c, i| {
const clock_cell = bigclock.clockCell(animate, c, buffer.fg, buffer.bg); const clock_cell = bigclock.clockCell(animate, c, buffer.fg, buffer.bg, config.bigclock);
bigclock.alphaBlit(xo + i * (bigclock.WIDTH + 1), yo, buffer.width, buffer.height, clock_cell); bigclock.alphaBlit(xo + i * (bigclock.WIDTH + 1), yo, buffer.width, buffer.height, clock_cell);
} }
} }
@ -544,7 +544,7 @@ pub fn main() !void {
.matrix => matrix.deinit(), .matrix => matrix.deinit(),
} }
} }
} else if (config.bigclock and config.clock == null) { } else if (config.bigclock != .none and config.clock == null) {
var tv: interop.system_time.timeval = undefined; var tv: interop.system_time.timeval = undefined;
_ = interop.system_time.gettimeofday(&tv, null); _ = interop.system_time.gettimeofday(&tv, null);