diff --git a/modules/digitalclock/clocks.go b/modules/digitalclock/clocks.go new file mode 100644 index 00000000..ccc3f5b0 --- /dev/null +++ b/modules/digitalclock/clocks.go @@ -0,0 +1,81 @@ +package digitalclock + +import ( + "fmt" + "strconv" + "time" +) + +// AM defines the AM string format +const AM = "A" + +// PM defines the PM string format +const PM = "P" +const minRowsForBorder = 3 + +// Converts integer to string along with makes sure the lenght of string is > 2 +func intStrConv(val int) string { + valStr := strconv.Itoa(val) + + if len(valStr) < 2 { + valStr = "0" + valStr + } + return valStr +} + +// Returns Hour + minute + AM/PM information based on the settings +func getHourMinute(hourFormat string) string { + strHours := intStrConv(time.Now().Hour()) + AMPM := " " + + if hourFormat == "12" { + hour := time.Now().Hour() + strHours = intStrConv(hour % 12) + if (hour % 12) == hour { + AMPM = AM + } else { + AMPM = PM + } + + } + + strMintues := intStrConv(time.Now().Minute()) + fmt.Println(AMPM) + strMintues = strMintues + AMPM + return strHours + getColon() + strMintues +} + +// Returns the : with blinking based on the seconds +func getColon() string { + if time.Now().Second()%2 == 0 { + return ":" + } + return " " +} + +func getDate() string { + return fmt.Sprintf("Date: %s", time.Now().Format("Monday January 02 2006")) +} + +func getUTC() string { + return fmt.Sprintf("UTC: %s", time.Now().UTC().Format(time.RFC3339)) +} + +func getEpoch() string { + return fmt.Sprintf("Epoch: %d", time.Now().Unix()) +} + +// Renders the clock as string by accessing appropriate font from configured in settings +func renderClock(widgetSettings Settings) (string, bool) { + var digFont ClockFont + clockTime := getHourMinute(widgetSettings.hourFormat) + digFont = getFont(widgetSettings) + + chars := [][]string{} + for _, char := range clockTime { + chars = append(chars, digFont.get(string(char))) + } + + needBorder := digFont.fontRows <= minRowsForBorder + return fontsJoin(chars, digFont.fontRows, widgetSettings.color), needBorder +} diff --git a/modules/digitalclock/display.go b/modules/digitalclock/display.go new file mode 100644 index 00000000..9db6ba3f --- /dev/null +++ b/modules/digitalclock/display.go @@ -0,0 +1,28 @@ +package digitalclock + +import "strings" + +func mergeLines(outString []string) string { + return strings.Join(outString[:], "\n") +} + +func renderWidget(widgetSettings Settings) string { + outputStrings := []string{} + clockString, needBorder := renderClock(widgetSettings) + if needBorder { + outputStrings = append(outputStrings, mergeLines([]string{"", clockString, ""})) + } else { + outputStrings = append(outputStrings, clockString) + } + outputStrings = append(outputStrings, getDate()) + outputStrings = append(outputStrings, getUTC()) + outputStrings = append(outputStrings, getEpoch()) + return mergeLines(outputStrings) +} + +func (widget *Widget) display(dateFormat string, timeFormat string) { + widget.Redraw(func() (string, string, bool) { + return widget.CommonSettings().Title, renderWidget(*widget.settings), false + }) + +} diff --git a/modules/digitalclock/fonts.go b/modules/digitalclock/fonts.go new file mode 100644 index 00000000..52fa37b3 --- /dev/null +++ b/modules/digitalclock/fonts.go @@ -0,0 +1,92 @@ +package digitalclock + +import ( + "fmt" + "strings" +) + +// ClockFontInterface to makes sure all fonts implement join and get methods +type ClockFontInterface interface { + join() string + get() string +} + +// ClockFont struct to hold the font info +type ClockFont struct { + fontRows int + fonts map[string][]string +} + +// function to join fonts, since the fonts have multi rows +func fontsJoin(fontCharArray [][]string, rows int, color string) string { + outString := "" + + for i := 0; i < rows; i++ { + outString += fmt.Sprintf("[%s]", color) + for _, charFont := range fontCharArray { + outString += " " + fmt.Sprintf("[%s]%s", color, charFont[i]) + } + outString += "\n" + } + return strings.TrimSuffix(outString, "\n") +} + +func (font *ClockFont) get(char string) []string { + return font.fonts[char] +} + +func getDigitalFont() ClockFont { + fontsMap := map[string][]string{ + "1": {"▄█ ", " █ ", "▄█▄"}, + "2": {"█▀█", " ▄▀", "█▄▄"}, + "3": {"█▀▀█", " ▀▄", "█▄▄█"}, + "4": {" █▀█ ", "█▄▄█▄", " █ "}, + "5": {"█▀▀", "▀▀▄", "▄▄▀"}, + "6": {"▄▀▀▄", "█▄▄ ", "▀▄▄▀"}, + "7": {"▀▀▀█", " █ ", " ▐▌ "}, + "8": {"▄▀▀▄", "▄▀▀▄", "▀▄▄▀"}, + "9": {"▄▀▀▄", "▀▄▄█", " ▄▄▀"}, + "0": {"█▀▀█", "█ █", "█▄▄█"}, + ":": {"█", " ", "█"}, + // "A": {" ", " ", "█▀█ █▀█▀█"}, + // "P": {" ", " ", "█▀ █▀█▀█"}, + " ": {" ", " ", " "}, + "A": {"", "", "AM"}, + "P": {"", "", "PM"}, + } + + digitalFont := ClockFont{fontRows: 3, fonts: fontsMap} + return digitalFont +} + +func getBigFont() ClockFont { + fontsMap := map[string][]string{ + "1": {" ┏┓ ", "┏┛┃ ", "┗┓┃ ", " ┃┃ ", "┏┛┗┓", "┗━━┛"}, + "2": {"┏━━━┓", "┃┏━┓┃", "┗┛┏┛┃", "┏━┛┏┛", "┃ ┗━┓", "┗━━━┛"}, + "3": {"┏━━━┓", "┃┏━┓┃", "┗┛┏┛┃", "┏┓┗┓┃", "┃┗━┛┃", "┗━━━┛"}, + "4": {"┏┓ ┏┓", "┃┃ ┃┃", "┃┗━┛┃", "┗━━┓┃", " ┃┃", " ┗┛"}, + "5": {"┏━━━┓", "┃┏━━┛", "┃┗━━┓", "┗━━┓┃", "┏━━┛┃", "┗━━━┛"}, + "6": {"┏━━━┓", "┃┏━━┛", "┃┗━━┓", "┃┏━┓┃", "┃┗━┛┃", "┗━━━┛"}, + "7": {"┏━━━┓", "┃┏━┓┃", "┗┛┏┛┃", " ┃┏┛", " ┃┃ ", " ┗┛ "}, + "8": {"┏━━━┓", "┃┏━┓┃", "┃┗━┛┃", "┃┏━┓┃", "┃┗━┛┃", "┗━━━┛"}, + "9": {"┏━━━┓", "┃┏━┓┃", "┃┗━┛┃", "┗━━┓┃", "┏━━┛┃", "┗━━━┛"}, + "0": {"┏━━━┓", "┃┏━┓┃", "┃┃ ┃┃", "┃┃ ┃┃", "┃┗━┛┃", "┗━━━┛"}, + ":": {" ", "┏━┓", "┗━┛", "┏━┓", "┗━┛", " "}, + // "A": {" ", " ", " ", "┏━━┓ ┏┓┏┓", "┃┏━┛ ┃┗┛┃", "┗┛ ┗┻┻┛"}, + // "P": {" ", " ", " ", "┏━━┓ ┏┓┏┓", "┃┏┓┃ ┃┗┛┃", "┗┛┗┛ ┗┻┻┛"}, + " ": {" ", " ", " ", " ", " ", " "}, + "A": {"", "", "", "", "", "AM"}, + "P": {"", "", "", "", "", "PM"}, + } + + bigFont := ClockFont{fontRows: 6, fonts: fontsMap} + return bigFont +} + +// getFont returns appropriate font map based on the font settings +func getFont(widgetSettings Settings) ClockFont { + if strings.ToLower(widgetSettings.font) == "digitalfont" { + return getDigitalFont() + } + return getBigFont() +} diff --git a/modules/digitalclock/settings.go b/modules/digitalclock/settings.go new file mode 100644 index 00000000..11222fbf --- /dev/null +++ b/modules/digitalclock/settings.go @@ -0,0 +1,31 @@ +package digitalclock + +import ( + "github.com/olebedev/config" + "github.com/wtfutil/wtf/cfg" +) + +const defaultTitle = "Clocks" + +// Settings struct to define settings got digital clock +type Settings struct { + // hello + common *cfg.Common + + hourFormat string `help:"The format of the clock." values:"12 or 24"` + color string `help:"The color of the clock."` + font string `help:"The font of the clock." values:"bigfont or digitalfont"` +} + +// NewSettingsFromYAML functino to create setting instance from yaml file +func NewSettingsFromYAML(name string, ymlConfig *config.Config, globalConfig *config.Config) *Settings { + + settings := Settings{ + common: cfg.NewCommonSettingsFromModule(name, defaultTitle, ymlConfig, globalConfig), + color: ymlConfig.UString("color"), + font: ymlConfig.UString("font"), + hourFormat: ymlConfig.UString("hourFormat"), + } + + return &settings +} diff --git a/modules/digitalclock/widget.go b/modules/digitalclock/widget.go new file mode 100644 index 00000000..c0974f62 --- /dev/null +++ b/modules/digitalclock/widget.go @@ -0,0 +1,38 @@ +package digitalclock + +import ( + "github.com/rivo/tview" + "github.com/wtfutil/wtf/view" +) + +type Widget struct { + view.TextWidget + + app *tview.Application + dateFormat string + timeFormat string + settings *Settings +} + +func NewWidget(app *tview.Application, settings *Settings) *Widget { + + widget := Widget{ + TextWidget: view.NewTextWidget(app, settings.common, false), + + app: app, + settings: settings, + } + + return &widget +} + +/* -------------------- Exported Functions -------------------- */ + +// Refresh updates the onscreen contents of the widget +func (widget *Widget) Refresh() { + widget.app.QueueUpdateDraw(func() { + widget.display(widget.dateFormat, widget.timeFormat) + }) +} + +/* -------------------- Unexported Functions -------------------- */