Skip to content

Commit

Permalink
Merge pull request #860 from rcalixte/dual_datetime
Browse files Browse the repository at this point in the history
dual-datetime: Initial release
  • Loading branch information
claudiux committed Jul 23, 2023
2 parents e9145cc + 422d4b6 commit f218d7e
Show file tree
Hide file tree
Showing 9 changed files with 458 additions and 0 deletions.
4 changes: 4 additions & 0 deletions dual-datetime@rcalixte/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@

### 1.0

* Initial release
60 changes: 60 additions & 0 deletions dual-datetime@rcalixte/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
DUAL DATETIME
=============

This is a simple desklet to display two datetime strings, defaulting to the time
and date. The size and format of each are configurable by changing the values
in the settings.

DESCRIPTION
-----------

Adjust the following options for each datetime value using the settings:

* Time Format
* Font
* Color
* Size

Additional desklet options include:

* Fixed Width
* Vertical or Horizontal
* Show Decorations
* Background Color

The datetime format are from the JavaScript `toLocaleFormat` function and the
possible values can be found locally in the terminal with:

```bash
$> man date
```

or online at:
[date Manual](https://man7.org/linux/man-pages/man1/date.1.html)

It is also possible to test string outputs in the terminal using the `date`
command and then copy the desired option to the settings input:

```bash
$ date +"%-H:%M"
14:27
```

For example, to add seconds to the first time format, append `:%S` like so:

```json
"Format": "%-H:%M:%S"
```

CONFIGURATION
-------------

It is possible to set a single datetime string for both the time and date if
desired. If the `Format` field is blank for either format field, that value will
not be displayed.

COMPATIBILITY
-------------

This applet has been tested to be compatible with Cinnamon 5.6+ but is
supported for Cinnamon 5.4+.
140 changes: 140 additions & 0 deletions dual-datetime@rcalixte/files/dual-datetime@rcalixte/5.4/desklet.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
const Desklet = imports.ui.desklet;
const GLib = imports.gi.GLib;
const Gettext = imports.gettext;
const Gio = imports.gi.Gio;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const Pango = imports.gi.Pango;
const Settings = imports.ui.settings;
const St = imports.gi.St;

const UUID = "dual-datetime@rcalixte";
const DATETIME_URL = "https://man7.org/linux/man-pages/man1/date.1.html";

// l10n/translation support
Gettext.bindtextdomain(UUID, GLib.get_home_dir() + "/.local/share/locale");

function _(str) {
return Gettext.dgettext(UUID, str);
}

function DateTimeDesklet(metadata, desklet_id) {
this._init(metadata, desklet_id);
}

DateTimeDesklet.prototype = {
__proto__: Desklet.Desklet.prototype,

_init: function (metadata, desklet_id) {
Desklet.Desklet.prototype._init.call(this, metadata, desklet_id);
this.metadata = metadata;
this.desklet_id = desklet_id;
this.setupUI();
},

setupUI: function () {
// initialize settings variables
this.settings = new Settings.DeskletSettings(this, UUID, this.desklet_id);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_custom1", "time_custom1", this.setupUI);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_format1", "time_format1", this.setupUI);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_font1", "time_font1", this.on_font_setting_changed, 1);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_color1", "time_color1", this.setupUI);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_size1", "time_size1", this.on_font_setting_changed, 1);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_custom2", "time_custom2", this.setupUI);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_format2", "time_format2", this.setupUI);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_font2", "time_font2", this.on_font_setting_changed, 2);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_color2", "time_color2", this.setupUI);
this.settings.bindProperty(Settings.BindingDirection.IN, "time_size2", "time_size2", this.on_font_setting_changed, 2);
this.settings.bindProperty(Settings.BindingDirection.IN, "width", "width", this.setupUI);
this.settings.bindProperty(Settings.BindingDirection.IN, "title_align", "title_align", this.setupUI);
this.settings.bindProperty(Settings.BindingDirection.IN, "show_decorations", "show_decorations", this.setupUI);
this.settings.bindProperty(Settings.BindingDirection.IN, "background_color", "background_color", this.setupUI);

// refresh style on change of global desklet setting for decorations
global.settings.connect('changed::desklet-decorations', Lang.bind(this, this.setupUI));

this.launcher = new Gio.SubprocessLauncher({
flags: (Gio.SubprocessFlags.STDIN_PIPE |
Gio.SubprocessFlags.STDOUT_PIPE |
Gio.Subprocess.STDERR_PIPE)
});

this.metadata['prevent-decorations'] = !this.show_decorations;
this._vertical = this.title_align == "vertical" ? true : false;
this._main = new St.BoxLayout({ vertical: this._vertical });

if (!this.time_custom1 && !this.time_custom2)
this.time_custom1 = true;

if (this.time_custom1 && this.time_format1)
this._setupContainer(1);

if (this.time_custom2 && this.time_format2)
this._setupContainer(2);

let _background = this.show_decorations ? `background-color: ${this.background_color}; ` : "";
this._main.style = `${_background}text-shadow: 1px 1px 2px #000; padding: 4px 10px; width: ${this.width}px;`;
this.setContent(this._main);
this._updateUI();
},

_setupContainer: function (num) {
this[`container${num}`] = new St.BoxLayout({ vertical: false });
this[`datetime${num}`] = new St.Label({ text: "" });
this[`datetime${num}`].clutterText.ellipsize = Pango.EllipsizeMode.NONE;
this[`container${num}`].add(this[`datetime${num}`]);
this[`time_font${num}`] = this[`time_font${num}`].replace(/['"`]/g, "");
this[`font${num}`] = this[`time_font${num}`] !== "" ? ` font-family: '${this["time_font" + num]}';` : "";
let _padding = this._vertical || num == 1 ? "" : "padding-left: 0.5em; ";
this[`container${num}`].style = `${_padding}color: ${this['time_color' + num]}; font-size: ${this['time_size' + num]}em;${this['font' + num]}`;
this._main.add(this[`container${num}`]);
},

_updateUI: function () {
let currentTime = new Date();
if (this.time_custom1 && this.time_format1)
this.datetime1.set_text(currentTime.toLocaleFormat(this.time_format1));
if (this.time_custom2 && this.time_format2)
this.datetime2.set_text(currentTime.toLocaleFormat(this.time_format2));
this.timeout = Mainloop.timeout_add_seconds(1, Lang.bind(this, this._updateUI));
},

on_datetime_button_clicked: function () {
this.launcher.spawnv(["xdg-open", DATETIME_URL]);
},

on_desklet_removed: function () {
Mainloop.source_remove(this.timeout);
},

on_font_setting_changed: function (value, num) {
// font settings changed; try to refresh instantly
this[`time_font${num}`] = this[`time_font${num}`].replace(/['"`]/g, "");
let argv = GLib.shell_parse_argv(`fc-list -q "${this['time_font' + num]}"`)[1];
try {
let subprocess = this.launcher.spawnv(argv);
subprocess.communicate_utf8_async(null, null, (subprocess, result) => {
try {
subprocess.communicate_utf8_finish(result);
let status = subprocess.get_exit_status();
if (status === 0) {
this[`font${num}`] = this[`time_font${num}`] !== "" ? ` font-family: '${this["time_font" + num]}';` : "";
} else {
this[`time_font${num}`] = "";
this[`font${num}`] = "";
}
} catch (e) {
global.logError(e);
} finally {
this[`container${num}`].style = `color: ${this["time_color" + num]}; font-size: ${this["time_size" + num]}em;${this["font" + num]}`;
}
});
} catch (e) {
global.logError(e);
}
}
};

function main(metadata, desklet_id) {
return new DateTimeDesklet(metadata, desklet_id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,124 @@
{
"head1": {
"type": "header",
"description": ""
},
"time_custom1": {
"type": "checkbox",
"description": "Customize First Time Value",
"default": true
},
"time_format1": {
"type": "entry",
"description": "Time Format",
"default": "%-H:%M",
"tooltip": "The datetime format to use for the output. See 'Format String Help' below for additional details.",
"dependency": "time_custom1"
},
"time_font1": {
"type": "entry",
"description": "Font Family (blank for default)",
"default": "",
"dependency": "time_custom1"
},
"time_color1": {
"type": "colorchooser",
"description": "Font Color",
"default": "rgba(255, 255, 255)",
"tooltip": "RGB or RGBA",
"dependency": "time_custom1"
},
"time_size1": {
"type": "scale",
"description": "Font Size",
"default": 2,
"min": 0.5,
"max": 20,
"step": 0.1,
"tooltip": "Increase or decrease this value to change the font size scale (1.2 = 120%)",
"dependency": "time_custom1"
},
"head2": {
"type": "header",
"description": ""
},
"time_custom2": {
"type": "checkbox",
"description": "Customize Second Time Value",
"default": true
},
"time_format2": {
"type": "entry",
"description": "Time Format",
"default": "%-A, %B %-d %Y",
"tooltip": "The datetime format to use for the output. See 'Format String Help' below for additional details.",
"dependency": "time_custom2"
},
"time_font2": {
"type": "entry",
"description": "Font Family (blank for default)",
"default": "",
"dependency": "time_custom2"
},
"time_color2": {
"type": "colorchooser",
"description": "Font Color",
"default": "rgba(255, 255, 255)",
"tooltip": "RGB or RGBA",
"dependency": "time_custom2"
},
"time_size2": {
"type": "scale",
"description": "Font Size",
"default": 2,
"min": 0.5,
"max": 20,
"step": 0.1,
"tooltip": "Increase or decrease this value to change the font size scale (1.2 = 120%)",
"dependency": "time_custom2"
},
"head3": {
"type": "header",
"description": ""
},
"datetime_button": {
"type": "button",
"description": "Format String Help",
"callback": "on_datetime_button_clicked"
},
"head4": {
"type": "header",
"description": "Additional Options"
},
"width": {
"type": "spinbutton",
"default": 400,
"min": 50,
"max": 3840,
"step": 10,
"units": "px",
"description": "Fixed width for the desklet",
"tooltip": "Increase or decrease this value to set the boundary width of the desklet"
},
"title_align": {
"type": "combobox",
"default": "vertical",
"description": "Alignment for time strings",
"options": {
"Vertical": "vertical",
"Horizontal": "horizontal"
}
},
"show_decorations": {
"type": "checkbox",
"description": "Show decorations",
"default": false
},
"background_color": {
"type": "colorchooser",
"default": "rgba(96, 96, 96, 1)",
"description": "Background color",
"tooltip": "RGB or RGBA",
"dependency": "show_decorations"
}
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions dual-datetime@rcalixte/files/dual-datetime@rcalixte/metadata.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"description": "A desklet that can display dual datetime strings",
"uuid": "dual-datetime@rcalixte",
"name": "Dual Datetime",
"cinnamon-version": [
"5.4",
"5.6",
"5.8"
],
"multiversion": true,
"max-instances": "10",
"version": "1.0"
}
Loading

0 comments on commit f218d7e

Please sign in to comment.