661 lines
22 KiB
JavaScript
661 lines
22 KiB
JavaScript
|
const St = imports.gi.St;
|
||
|
const Gio = imports.gi.Gio
|
||
|
const Gtk = imports.gi.Gtk;
|
||
|
const GLib = imports.gi.GLib;
|
||
|
const Clutter = imports.gi.Clutter;
|
||
|
const Main = imports.ui.main;
|
||
|
const ByteArray = imports.byteArray;
|
||
|
const Signals = imports.signals;
|
||
|
const Mainloop = imports.mainloop;
|
||
|
|
||
|
|
||
|
const ME = imports.misc.extensionUtils.getCurrentExtension();
|
||
|
|
||
|
|
||
|
const Gettext = imports.gettext.domain(ME.metadata['gettext-domain']);
|
||
|
const _ = Gettext.gettext;
|
||
|
const ngettext = Gettext.ngettext;
|
||
|
|
||
|
|
||
|
const MISC_UTILS = ME.imports.lib.misc_utils;
|
||
|
const FULLSCREEN = ME.imports.lib.fullscreen;
|
||
|
const SIG_MANAGER = ME.imports.lib.signal_manager;
|
||
|
const KEY_MANAGER = ME.imports.lib.keybinding_manager;
|
||
|
const PANEL_ITEM = ME.imports.lib.panel_item;
|
||
|
|
||
|
|
||
|
const IFACE = `${ME.path}/dbus/stopwatch_iface.xml`;
|
||
|
|
||
|
|
||
|
const CACHE_FILE = '~/.cache/timepp_gnome_shell_extension/timepp_stopwatch.json';
|
||
|
|
||
|
|
||
|
const StopwatchState = {
|
||
|
RUNNING : 'RUNNING',
|
||
|
STOPPED : 'STOPPED',
|
||
|
RESET : 'RESET',
|
||
|
};
|
||
|
|
||
|
|
||
|
const ClockFormat = {
|
||
|
H_M : 0,
|
||
|
H_M_S : 1,
|
||
|
H_M_S_CS : 2,
|
||
|
};
|
||
|
|
||
|
|
||
|
const NotifStyle = {
|
||
|
STANDARD : 0,
|
||
|
FULLSCREEN : 1,
|
||
|
};
|
||
|
|
||
|
|
||
|
const PanelMode = {
|
||
|
ICON : 0,
|
||
|
TEXT : 1,
|
||
|
ICON_TEXT : 2,
|
||
|
DYNAMIC : 3,
|
||
|
};
|
||
|
|
||
|
|
||
|
// =====================================================================
|
||
|
// @@@ Main
|
||
|
//
|
||
|
// @ext : obj (main extension object)
|
||
|
// @settings : obj (extension settings)
|
||
|
// =====================================================================
|
||
|
var SectionMain = class SectionMain extends ME.imports.sections.section_base.SectionBase{
|
||
|
constructor (section_name, ext, settings) {
|
||
|
super(section_name, ext, settings);
|
||
|
|
||
|
this.actor.add_style_class_name('stopwatch-section');
|
||
|
|
||
|
this.separate_menu = this.settings.get_boolean('stopwatch-separate-menu');
|
||
|
|
||
|
this.clock_format = this.settings.get_enum('stopwatch-clock-format');
|
||
|
this.start_time = 0; // for computing elapsed time (microseconds)
|
||
|
this.cache_file = null;
|
||
|
this.cache = null;
|
||
|
this.tic_mainloop_id = null;
|
||
|
this.time_backup_mainloop_id = null;
|
||
|
|
||
|
this.stopwatch_state = StopwatchState.RESET;
|
||
|
|
||
|
{
|
||
|
let [,xml,] = Gio.file_new_for_path(IFACE).load_contents(null);
|
||
|
xml = '' + ByteArray.toString(xml);
|
||
|
this.dbus_impl = Gio.DBusExportedObject.wrapJSObject(xml, this);
|
||
|
this.dbus_impl.export(Gio.DBus.session, '/timepp/zagortenay333/Stopwatch');
|
||
|
}
|
||
|
|
||
|
this.fullscreen = new StopwatchFullscreen(this.ext, this,
|
||
|
this.settings.get_int('stopwatch-fullscreen-monitor-pos'));
|
||
|
|
||
|
this.sigm = new SIG_MANAGER.SignalManager();
|
||
|
this.keym = new KEY_MANAGER.KeybindingManager(this.settings);
|
||
|
|
||
|
|
||
|
try {
|
||
|
this.cache_file = MISC_UTILS.file_new_for_path(CACHE_FILE);
|
||
|
|
||
|
let cache_format_version =
|
||
|
ME.metadata['cache-file-format-version'].stopwatch;
|
||
|
|
||
|
if (this.cache_file.query_exists(null)) {
|
||
|
let [a, contents, b] = this.cache_file.load_contents(null);
|
||
|
this.cache = JSON.parse(ByteArray.toString(contents));
|
||
|
}
|
||
|
|
||
|
if (!this.cache || !this.cache.format_version ||
|
||
|
this.cache.format_version !== cache_format_version) {
|
||
|
|
||
|
this.cache = {
|
||
|
format_version : cache_format_version,
|
||
|
time : 0, // microseconds
|
||
|
laps : [],
|
||
|
};
|
||
|
}
|
||
|
} catch (e) {
|
||
|
logError(e);
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// keybindings
|
||
|
//
|
||
|
this.keym.add('stopwatch-keybinding-open', () => {
|
||
|
this.ext.open_menu(this.section_name);
|
||
|
});
|
||
|
this.keym.add('stopwatch-keybinding-open-fullscreen', () => {
|
||
|
this.show_fullscreen();
|
||
|
});
|
||
|
|
||
|
|
||
|
//
|
||
|
// panel item
|
||
|
//
|
||
|
this.panel_item.icon.gicon = MISC_UTILS.getIcon('timepp-stopwatch-symbolic');
|
||
|
this.panel_item.actor.add_style_class_name('stopwatch-panel-item');
|
||
|
this._toggle_panel_mode();
|
||
|
|
||
|
switch (this.clock_format) {
|
||
|
case ClockFormat.H_M:
|
||
|
this.panel_item.set_label('00:00');
|
||
|
this.fullscreen.set_banner_text('00:00')
|
||
|
break;
|
||
|
case ClockFormat.H_M_S:
|
||
|
this.panel_item.set_label('00:00:00');
|
||
|
this.fullscreen.set_banner_text('00:00:00')
|
||
|
break;
|
||
|
case ClockFormat.H_M_S_CS:
|
||
|
this.panel_item.set_label('00:00:00.00');
|
||
|
this.fullscreen.set_banner_text('00:00:00.00')
|
||
|
}
|
||
|
|
||
|
|
||
|
//
|
||
|
// header
|
||
|
//
|
||
|
this.header = new St.BoxLayout({ style_class: 'timepp-menu-item header' });
|
||
|
this.actor.add_actor(this.header);
|
||
|
|
||
|
this.header_label = new St.Label({ x_expand: true, text: _('Stopwatch'), style_class: 'clock' });
|
||
|
this.header.add_child(this.header_label);
|
||
|
|
||
|
this.icon_box = new St.BoxLayout({ y_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.END, style_class: 'icon-box' });
|
||
|
this.header.add_child(this.icon_box);
|
||
|
|
||
|
this.fullscreen_icon = new St.Icon({ reactive: true, can_focus: true, track_hover: true, gicon : MISC_UTILS.getIcon('timepp-fullscreen-symbolic'), style_class: 'fullscreen-icon' });
|
||
|
this.icon_box.add_actor(this.fullscreen_icon);
|
||
|
|
||
|
|
||
|
//
|
||
|
// buttons
|
||
|
//
|
||
|
this.stopwatch_button_box = new St.BoxLayout({ x_expand: true, style_class: 'timepp-menu-item btn-box' });
|
||
|
this.actor.add_child(this.stopwatch_button_box);
|
||
|
|
||
|
this.button_reset = new St.Button({ can_focus: true, label: _('Reset'), style_class: 'btn-reset button', x_expand: true, visible: false });
|
||
|
this.button_lap = new St.Button({ can_focus: true, label: _('Lap'), style_class: 'btn-lap button', x_expand: true, visible: false });
|
||
|
this.button_start = new St.Button({ can_focus: true, label: _('Start'), style_class: 'btn-start button', x_expand: true });
|
||
|
this.button_stop = new St.Button({ can_focus: true, label: _('Stop'), style_class: 'btn-stop button', x_expand: true, visible: false });
|
||
|
this.stopwatch_button_box.add_child(this.button_reset);
|
||
|
this.stopwatch_button_box.add_child(this.button_lap);
|
||
|
this.stopwatch_button_box.add_child(this.button_start);
|
||
|
this.stopwatch_button_box.add_child(this.button_stop);
|
||
|
|
||
|
|
||
|
//
|
||
|
// laps box
|
||
|
//
|
||
|
this.laps_scroll = new St.ScrollView({ visible: false, style_class: 'timepp-menu-item laps-scrollview vfade', x_fill: true, y_fill: false, y_align: St.Align.START});
|
||
|
this.actor.add_actor(this.laps_scroll);
|
||
|
|
||
|
this.laps_scroll.vscrollbar_policy = Gtk.PolicyType.NEVER;
|
||
|
this.laps_scroll.hscrollbar_policy = Gtk.PolicyType.NEVER;
|
||
|
|
||
|
this.laps_scroll_bin = new St.BoxLayout({ vertical: true, style_class: 'laps-box' });
|
||
|
this.laps_scroll.add_actor(this.laps_scroll_bin);
|
||
|
|
||
|
this.laps_string = new St.Label();
|
||
|
this.laps_scroll_bin.add_actor(this.laps_string);
|
||
|
|
||
|
|
||
|
//
|
||
|
// listen
|
||
|
//
|
||
|
this.sigm.connect(this.fullscreen, 'monitor-changed', () => {
|
||
|
this.settings.set_int('stopwatch-fullscreen-monitor-pos', this.fullscreen.monitor);
|
||
|
});
|
||
|
this.sigm.connect(this.settings, 'changed::stopwatch-separate-menu', () => {
|
||
|
this.separate_menu = this.settings.get_boolean('stopwatch-separate-menu');
|
||
|
this.ext.update_panel_items();
|
||
|
});
|
||
|
this.sigm.connect(this.settings, 'changed::stopwatch-clock-format', () => {
|
||
|
this.clock_format = this.settings.get_enum('stopwatch-clock-format');
|
||
|
let txt = this._time_format_str();
|
||
|
this.panel_item.set_label(txt);
|
||
|
this.fullscreen.set_banner_text(txt);
|
||
|
});
|
||
|
this.sigm.connect(this.laps_string, 'allocation-changed', () => {
|
||
|
this.laps_scroll.vscrollbar_policy = Gtk.PolicyType.NEVER;
|
||
|
if (ext.needs_scrollbar())
|
||
|
this.laps_scroll.vscrollbar_policy = Gtk.PolicyType.ALWAYS;
|
||
|
});
|
||
|
this.sigm.connect(this.settings, 'changed::stopwatch-panel-mode', () => this._toggle_panel_mode());
|
||
|
this.sigm.connect(this.panel_item, 'middle-click', () => this.stopwatch_toggle());
|
||
|
this.sigm.connect_release(this.fullscreen_icon, Clutter.BUTTON_PRIMARY, true, () => this.show_fullscreen());
|
||
|
this.sigm.connect_release(this.button_start, Clutter.BUTTON_PRIMARY, true, () => this.start());
|
||
|
this.sigm.connect_release(this.button_reset, Clutter.BUTTON_PRIMARY, true, () => this.reset());
|
||
|
this.sigm.connect_release(this.button_stop, Clutter.BUTTON_PRIMARY, true, () => this.stop());
|
||
|
this.sigm.connect_release(this.button_lap, Clutter.BUTTON_PRIMARY, true, () => this.lap());
|
||
|
|
||
|
|
||
|
//
|
||
|
// finally
|
||
|
//
|
||
|
if (this.cache.time > 0) {
|
||
|
this._update_laps();
|
||
|
this._update_time_display();
|
||
|
this.stopwatch_state = StopwatchState.STOPPED;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
disable_section () {
|
||
|
if (this.time_backup_mainloop_id) {
|
||
|
Mainloop.source_remove(this.time_backup_mainloop_id);
|
||
|
this.time_backup_mainloop_id = null;
|
||
|
}
|
||
|
|
||
|
if (this.stopwatch_state === StopwatchState.RUNNING) this.stop();
|
||
|
this.dbus_impl.unexport();
|
||
|
this._store_cache();
|
||
|
this.sigm.clear();
|
||
|
this.keym.clear();
|
||
|
|
||
|
if (this.fullscreen) {
|
||
|
this.fullscreen.destroy();
|
||
|
this.fullscreen = null;
|
||
|
}
|
||
|
|
||
|
super.disable_section();
|
||
|
}
|
||
|
|
||
|
_store_cache () {
|
||
|
if (! this.cache_file.query_exists(null))
|
||
|
this.cache_file.create(Gio.FileCreateFlags.NONE, null);
|
||
|
|
||
|
this.cache_file.replace_contents(JSON.stringify(this.cache, null, 2),
|
||
|
null, false, Gio.FileCreateFlags.REPLACE_DESTINATION, null);
|
||
|
}
|
||
|
|
||
|
start () {
|
||
|
this.start_time = GLib.get_monotonic_time() - this.cache.time;
|
||
|
this.stopwatch_state = StopwatchState.RUNNING;
|
||
|
|
||
|
if (!this.fullscreen.is_open && this.actor.visible)
|
||
|
this.button_stop.grab_key_focus();
|
||
|
|
||
|
this._toggle_buttons();
|
||
|
this._panel_item_UI_update();
|
||
|
this.fullscreen.on_timer_started();
|
||
|
|
||
|
if (this.settings.get_enum('stopwatch-panel-mode') === PanelMode.DYNAMIC)
|
||
|
this.panel_item.set_mode('icon_text');
|
||
|
|
||
|
if (! this.time_backup_mainloop_id) this._periodic_time_backup();
|
||
|
|
||
|
this._store_cache();
|
||
|
this._tic();
|
||
|
}
|
||
|
|
||
|
stop () {
|
||
|
if (this.start_time) this.cache.time = GLib.get_monotonic_time() - this.start_time;
|
||
|
this.stopwatch_state = StopwatchState.STOPPED;
|
||
|
|
||
|
if (this.tic_mainloop_id) {
|
||
|
Mainloop.source_remove(this.tic_mainloop_id);
|
||
|
this.tic_mainloop_id = null;
|
||
|
}
|
||
|
|
||
|
if (this.time_backup_mainloop_id) {
|
||
|
Mainloop.source_remove(this.time_backup_mainloop_id);
|
||
|
this.time_backup_mainloop_id = null;
|
||
|
}
|
||
|
|
||
|
this.fullscreen.on_timer_stopped();
|
||
|
|
||
|
if (!this.fullscreen.is_open && this.actor.visible)
|
||
|
this.button_start.grab_key_focus();
|
||
|
|
||
|
this._panel_item_UI_update();
|
||
|
this._toggle_buttons();
|
||
|
|
||
|
if (this.settings.get_enum('stopwatch-panel-mode') === PanelMode.DYNAMIC)
|
||
|
this.panel_item.set_mode('icon');
|
||
|
|
||
|
this._store_cache();
|
||
|
}
|
||
|
|
||
|
reset () {
|
||
|
this.stopwatch_state = StopwatchState.RESET;
|
||
|
|
||
|
if (this.tic_mainloop_id) {
|
||
|
Mainloop.source_remove(this.tic_mainloop_id);
|
||
|
this.tic_mainloop_id = null;
|
||
|
}
|
||
|
|
||
|
if (this.time_backup_mainloop_id) {
|
||
|
Mainloop.source_remove(this.time_backup_mainloop_id);
|
||
|
this.time_backup_mainloop_id = null;
|
||
|
}
|
||
|
|
||
|
this.fullscreen.on_timer_reset();
|
||
|
|
||
|
if (!this.fullscreen.is_open && this.actor.visible)
|
||
|
this.button_start.grab_key_focus();
|
||
|
|
||
|
this.cache.laps = [];
|
||
|
this.cache.time = 0;
|
||
|
this._destroy_laps();
|
||
|
|
||
|
this._update_time_display();
|
||
|
this._toggle_buttons();
|
||
|
this._panel_item_UI_update();
|
||
|
this.header_label.text = _('Stopwatch');
|
||
|
|
||
|
if (this.settings.get_enum('stopwatch-panel-mode') === PanelMode.DYNAMIC)
|
||
|
this.panel_item.set_mode('icon');
|
||
|
|
||
|
this._store_cache();
|
||
|
}
|
||
|
|
||
|
stopwatch_toggle () {
|
||
|
if (this.stopwatch_state === StopwatchState.RUNNING)
|
||
|
this.stop();
|
||
|
else
|
||
|
this.start();
|
||
|
}
|
||
|
|
||
|
_tic () {
|
||
|
this.cache.time = GLib.get_monotonic_time() - this.start_time;
|
||
|
|
||
|
this._update_time_display();
|
||
|
|
||
|
if (this.clock_format === ClockFormat.H_M_S_CS) {
|
||
|
this.tic_mainloop_id = Mainloop.timeout_add(10, () => this._tic());
|
||
|
} else {
|
||
|
this.tic_mainloop_id = Mainloop.timeout_add_seconds(1, () => this._tic());
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_update_time_display () {
|
||
|
let txt = this._time_format_str();
|
||
|
|
||
|
this.header_label.text = txt;
|
||
|
this.panel_item.set_label(txt);
|
||
|
this.fullscreen.set_banner_text(txt);
|
||
|
}
|
||
|
|
||
|
_time_format_str () {
|
||
|
let t = Math.floor(this.cache.time / 10000); // centiseconds
|
||
|
|
||
|
let cs = t % 100;
|
||
|
t = Math.floor(t / 100);
|
||
|
let h = Math.floor(t / 3600);
|
||
|
t = t % 3600;
|
||
|
let m = Math.floor(t / 60);
|
||
|
let s = t % 60;
|
||
|
|
||
|
switch (this.clock_format) {
|
||
|
case ClockFormat.H_M:
|
||
|
return "%02d:%02d".format(h, m);
|
||
|
case ClockFormat.H_M_S:
|
||
|
return "%02d:%02d:%02d".format(h, m, s);
|
||
|
case ClockFormat.H_M_S_CS:
|
||
|
return "%02d:%02d:%02d.%02d".format(h, m, s, cs);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
_panel_item_UI_update () {
|
||
|
if (this.stopwatch_state === StopwatchState.RUNNING)
|
||
|
this.panel_item.actor.add_style_class_name('on');
|
||
|
else
|
||
|
this.panel_item.actor.remove_style_class_name('on');
|
||
|
}
|
||
|
|
||
|
lap () {
|
||
|
if (this.stopwatch_state !== StopwatchState.RUNNING) return;
|
||
|
|
||
|
this.cache.laps.push(this._time_format_str());
|
||
|
this._store_cache();
|
||
|
this._update_laps();
|
||
|
}
|
||
|
|
||
|
_update_laps () {
|
||
|
let n = this.cache.laps.length;
|
||
|
|
||
|
if (n === 0) return;
|
||
|
|
||
|
let pad = String(n).length + 1;
|
||
|
let markup = '';
|
||
|
|
||
|
while (n--) {
|
||
|
markup += `<b>${n + 1}</b> ` +
|
||
|
Array(pad - String(n + 1).length).join(' ') +
|
||
|
`- ${this.cache.laps[n]}\n`;
|
||
|
}
|
||
|
|
||
|
markup = `<tt>${markup.slice(0, -1)}</tt>`;
|
||
|
|
||
|
this.laps_string.clutter_text.set_markup(markup);
|
||
|
this.fullscreen.laps_string.clutter_text.set_markup(markup);
|
||
|
this.laps_scroll.show();
|
||
|
this.fullscreen.laps_scroll.show();
|
||
|
}
|
||
|
|
||
|
_destroy_laps () {
|
||
|
this.laps_scroll.hide();
|
||
|
this.laps_string.text = '';
|
||
|
}
|
||
|
|
||
|
_toggle_buttons () {
|
||
|
switch (this.stopwatch_state) {
|
||
|
case StopwatchState.RESET:
|
||
|
this.button_reset.hide();
|
||
|
this.button_lap.hide();
|
||
|
this.button_start.show();
|
||
|
this.button_stop.hide();
|
||
|
this.button_start.add_style_pseudo_class('first-child');
|
||
|
this.button_start.add_style_pseudo_class('last-child');
|
||
|
this.fullscreen.button_reset.hide();
|
||
|
this.fullscreen.button_lap.hide();
|
||
|
this.fullscreen.button_start.show();
|
||
|
this.fullscreen.button_stop.hide();
|
||
|
this.fullscreen.button_start.add_style_pseudo_class('first-child');
|
||
|
this.fullscreen.button_start.add_style_pseudo_class('last-child');
|
||
|
break;
|
||
|
case StopwatchState.RUNNING:
|
||
|
this.button_reset.show();
|
||
|
this.button_lap.show();
|
||
|
this.button_start.hide();
|
||
|
this.button_stop.show();
|
||
|
this.fullscreen.button_reset.show();
|
||
|
this.fullscreen.button_lap.show();
|
||
|
this.fullscreen.button_start.hide();
|
||
|
this.fullscreen.button_stop.show();
|
||
|
break;
|
||
|
case StopwatchState.STOPPED:
|
||
|
this.button_reset.show();
|
||
|
this.button_lap.hide();
|
||
|
this.button_start.show();
|
||
|
this.button_stop.hide();
|
||
|
this.button_start.remove_style_pseudo_class('first-child');
|
||
|
this.button_start.add_style_pseudo_class('last-child');
|
||
|
this.fullscreen.button_reset.show();
|
||
|
this.fullscreen.button_lap.hide();
|
||
|
this.fullscreen.button_start.show();
|
||
|
this.fullscreen.button_stop.hide();
|
||
|
this.fullscreen.button_start.remove_style_pseudo_class('first-child');
|
||
|
this.fullscreen.button_start.add_style_pseudo_class('last-child');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
show_fullscreen () {
|
||
|
this.ext.menu.close();
|
||
|
|
||
|
if (! this.fullscreen) {
|
||
|
this.fullscreen = new StopwatchFullscreen(this.ext, this,
|
||
|
this.settings.get_int('stopwatch-fullscreen-monitor-pos'));
|
||
|
}
|
||
|
|
||
|
this.fullscreen.open();
|
||
|
}
|
||
|
|
||
|
_periodic_time_backup () {
|
||
|
this.cache.time = GLib.get_monotonic_time() - this.start_time;
|
||
|
this._store_cache();
|
||
|
|
||
|
this.time_backup_mainloop_id = Mainloop.timeout_add_seconds(60, () => {
|
||
|
this._periodic_time_backup();
|
||
|
});
|
||
|
}
|
||
|
|
||
|
_toggle_panel_mode () {
|
||
|
switch (this.settings.get_enum('stopwatch-panel-mode')) {
|
||
|
case PanelMode.ICON:
|
||
|
this.panel_item.set_mode('icon');
|
||
|
break;
|
||
|
case PanelMode.TEXT:
|
||
|
this.panel_item.set_mode('text');
|
||
|
break;
|
||
|
case PanelMode.ICON_TEXT:
|
||
|
this.panel_item.set_mode('icon_text');
|
||
|
break;
|
||
|
case PanelMode.DYNAMIC:
|
||
|
if (this.stopwatch_state === StopwatchState.RUNNING)
|
||
|
this.panel_item.set_mode('icon_text');
|
||
|
else
|
||
|
this.panel_item.set_mode('icon');
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// returns int (microseconds)
|
||
|
get_time () {
|
||
|
if (this.stopwatch_state === StopwatchState.RUNNING)
|
||
|
return GLib.get_monotonic_time() - this.start_time;
|
||
|
else
|
||
|
return this.cache.time;
|
||
|
}
|
||
|
}
|
||
|
Signals.addSignalMethods(SectionMain.prototype);
|
||
|
|
||
|
|
||
|
|
||
|
// =====================================================================
|
||
|
// @@@ Stopwatch fullscreen interface
|
||
|
//
|
||
|
// @ext : obj (main extension object)
|
||
|
// @delegate : obj (main section object)
|
||
|
// @monitor : int
|
||
|
//
|
||
|
// signals: 'monitor-changed'
|
||
|
// =====================================================================
|
||
|
var StopwatchFullscreen = class StopwatchFullscreen extends FULLSCREEN.Fullscreen{
|
||
|
constructor (ext, delegate, monitor) {
|
||
|
super(monitor);
|
||
|
this.middle_box.vertical = false;
|
||
|
|
||
|
this.ext = ext;
|
||
|
this.delegate = delegate;
|
||
|
|
||
|
this.default_style_class = this.actor.style_class;
|
||
|
|
||
|
|
||
|
//
|
||
|
// laps box
|
||
|
//
|
||
|
this.laps_scroll = new St.ScrollView({ visible: false, x_fill: true, y_fill: true, y_align: St.Align.START, style_class: 'laps-scrollview vfade' });
|
||
|
this.middle_box.add_child(this.laps_scroll);
|
||
|
|
||
|
this.laps_scroll.hscrollbar_policy = Gtk.PolicyType.NEVER;
|
||
|
|
||
|
this.laps_scroll_bin = new St.BoxLayout({ vertical: true, style_class: 'laps-box' });
|
||
|
this.laps_scroll.add_actor(this.laps_scroll_bin);
|
||
|
|
||
|
this.laps_string = new St.Label();
|
||
|
this.laps_scroll_bin.add_actor(this.laps_string);
|
||
|
|
||
|
|
||
|
//
|
||
|
// buttons
|
||
|
//
|
||
|
this.stopwatch_button_box = new St.BoxLayout({ x_expand: true, y_expand: true, style_class: 'btn-box', x_align: Clutter.ActorAlign.CENTER, y_align: Clutter.ActorAlign.CENTER, });
|
||
|
this.bottom_box.add_child(this.stopwatch_button_box);
|
||
|
|
||
|
|
||
|
this.button_reset = new St.Button({ can_focus: true, label: _('Reset'), style_class: 'btn-reset button', visible: false });
|
||
|
this.button_lap = new St.Button({ can_focus: true, label: _('Lap'), style_class: 'btn-lap button', visible: false });
|
||
|
this.button_stop = new St.Button({ can_focus: true, label: _('Stop'), style_class: 'btn-stop button', visible: false });
|
||
|
this.button_start = new St.Button({ can_focus: true, label: _('Start'), style_class: 'btn-start button' });
|
||
|
this.stopwatch_button_box.add_child(this.button_reset);
|
||
|
this.stopwatch_button_box.add_child(this.button_lap);
|
||
|
this.stopwatch_button_box.add_child(this.button_start);
|
||
|
this.stopwatch_button_box.add_child(this.button_stop);
|
||
|
|
||
|
|
||
|
//
|
||
|
// listen
|
||
|
//
|
||
|
this.button_start.connect('clicked', () => {
|
||
|
this.delegate.start();
|
||
|
return Clutter.EVENT_STOP;
|
||
|
});
|
||
|
this.button_reset.connect('clicked', () => {
|
||
|
this.delegate.reset();
|
||
|
return Clutter.EVENT_STOP;
|
||
|
});
|
||
|
this.button_stop.connect('clicked', () => {
|
||
|
this.delegate.stop();
|
||
|
return Clutter.EVENT_STOP;
|
||
|
});
|
||
|
this.button_lap.connect('clicked', () => {
|
||
|
this.delegate.lap();
|
||
|
return Clutter.EVENT_STOP;
|
||
|
});
|
||
|
this.actor.connect('key-release-event', (_, event) => {
|
||
|
switch (event.get_key_symbol()) {
|
||
|
case Clutter.KEY_space:
|
||
|
this.delegate.stopwatch_toggle();
|
||
|
return Clutter.EVENT_STOP;
|
||
|
case Clutter.KEY_l:
|
||
|
case Clutter.KEY_KP_Enter:
|
||
|
case Clutter.Return:
|
||
|
this.delegate.lap();
|
||
|
return Clutter.EVENT_STOP;
|
||
|
case Clutter.KEY_r:
|
||
|
case Clutter.KEY_BackSpace:
|
||
|
this.delegate.reset();
|
||
|
return Clutter.EVENT_STOP;
|
||
|
default:
|
||
|
return Clutter.EVENT_PROPAGATE;
|
||
|
}
|
||
|
});
|
||
|
}
|
||
|
|
||
|
close () {
|
||
|
if (this.delegate.stopwatch_state === StopwatchState.RESET) {
|
||
|
this.actor.style_class = this.default_style_class;
|
||
|
|
||
|
switch (this.delegate.clock_format) {
|
||
|
case ClockFormat.H_M:
|
||
|
this.set_banner_text('00:00')
|
||
|
break;
|
||
|
case ClockFormat.H_M_S:
|
||
|
this.set_banner_text('00:00:00')
|
||
|
break;
|
||
|
case ClockFormat.H_M_S_CS:
|
||
|
this.set_banner_text('00:00:00.00')
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
super.close();
|
||
|
}
|
||
|
|
||
|
on_timer_started () {
|
||
|
this.actor.style_class = this.default_style_class;
|
||
|
}
|
||
|
|
||
|
on_timer_stopped () {
|
||
|
this.actor.style_class = this.default_style_class + ' timer-stopped';
|
||
|
}
|
||
|
|
||
|
on_timer_reset () {
|
||
|
this.laps_scroll.hide();
|
||
|
this.laps_string.text = '';
|
||
|
}
|
||
|
}
|
||
|
Signals.addSignalMethods(StopwatchFullscreen.prototype);
|