const St = imports.gi.St; const Gio = imports.gi.Gio const GLib = imports.gi.GLib; const Clutter = imports.gi.Clutter; const MessageTray = imports.ui.messageTray; const Main = imports.ui.main; const CheckBox = imports.ui.checkBox; 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 SOUND_PLAYER = ME.imports.lib.sound_player; 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 NUM_PICKER = ME.imports.lib.num_picker; const MULTIL_ENTRY = ME.imports.lib.multiline_entry; const IFACE = `${ME.path}/dbus/pomodoro_iface.xml`; const CACHE_FILE = '~/.cache/timepp_gnome_shell_extension/timepp_pomodoro.json'; const POMO_STARTED_MSG = _('Pomodoro'); const LONG_BREAK_MSG = _('Long Break') const SHORT_BREAK_MSG = _('Short Break') const PomoState = { STOPPED : 'STOPPED', POMO : 'POMO', LONG_BREAK : 'LONG_BREAK', SHORT_BREAK : 'SHORT_BREAK', }; const NotifStyle = { STANDARD : 0, FULLSCREEN : 1, NONE : 2, }; 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('pomo-section'); this.separate_menu = this.settings.get_boolean('pomodoro-separate-menu'); this.pomo_state = PomoState.STOPPED; this.tic_mainloop_id = null; this.cache_file = null; this.cache = null; this.notif_source = null; this.clock = 0; // microseconds this.end_time = 0; // For computing elapsed time (microseconds) this.sigm = new SIG_MANAGER.SignalManager(); this.keym = new KEY_MANAGER.KeybindingManager(this.settings); this.sound_player = new SOUND_PLAYER.SoundPlayer(); this.fullscreen = new PomodoroFullscreen(this.ext, this, this.settings.get_int('pomodoro-fullscreen-monitor-pos')); { 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/Pomodoro'); } try { this.cache_file = MISC_UTILS.file_new_for_path(CACHE_FILE); let cache_format_version = ME.metadata['cache-file-format-version'].pomodoro; if (this.cache_file.query_exists(null)) { let [, contents] = 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, pomo_counter : 0, pomo_duration : 1500, // seconds short_break : 300, // seconds long_break : 900, // seconds long_break_rate : 4, todo_task_id : '', }; } } catch (e) { logError(e); return; } // // keybindings // this.keym.add('pomodoro-keybinding-open', () => { this.ext.open_menu(this.section_name); }); this.keym.add('pomodoro-keybinding-open-fullscreen', () => { this.show_fullscreen(); }); // // panel item // this.panel_item.actor.add_style_class_name('pomodoro-panel-item'); this.panel_item.icon.gicon = MISC_UTILS.getIcon('timepp-pomodoro-symbolic'); this.panel_item.set_label(this.settings.get_boolean('pomodoro-show-seconds') ? '00:00:00' : '00:00'); this._toggle_panel_mode(); // // 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: _('Timer'), style_class: 'clock' }); this.header.add_child(this.header_label); // pomo phase label this.phase_label = new St.Label({ y_align: Clutter.ActorAlign.CENTER, style_class: 'pomo-phase-label popup-inactive-menu-item', pseudo_class: 'insensitive' }); this.header.add_child(this.phase_label); // clock this.clock_label = new St.Label({ y_align: Clutter.ActorAlign.CENTER, style_class: 'pomo-counter' }); this.header.add_child(this.clock_label); // icons this.icon_box = new St.BoxLayout({ y_align: Clutter.ActorAlign.CENTER, x_align: Clutter.ActorAlign.END, style_class: 'icon-box' }); this.header.add_actor(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); this.settings_icon = new St.Icon({ reactive: true, can_focus: true, track_hover: true, gicon : MISC_UTILS.getIcon('timepp-settings-symbolic'), style_class: 'settings-icon' }); this.icon_box.add_actor(this.settings_icon); // // buttons // this.button_box = new St.BoxLayout({ x_expand: true, style_class: 'timepp-menu-item btn-box' }); this.actor.add(this.button_box); this.button_new_pomo = new St.Button({can_focus: true, label: _('New Pomo'), x_expand: true, style_class: 'button'}); this.button_take_break = new St.Button({can_focus: true, label: _('Take Break'), x_expand: true, visible: false, style_class: 'button'}); this.button_continue = new St.Button({can_focus: true, label: _('Continue'), x_expand: true, visible: false, style_class: 'button'}); this.button_stop = new St.Button({can_focus: true, label: _('Stop'), x_expand: true, visible: false, style_class: 'button'}); this.button_box.add_actor(this.button_new_pomo); this.button_box.add_actor(this.button_take_break); this.button_box.add_actor(this.button_continue); this.button_box.add_actor(this.button_stop); // // settings container // this.settings_container = new St.Bin({x_fill: true}); this.actor.add_actor(this.settings_container); // // listen // this.sigm.connect(this.fullscreen, 'monitor-changed', () => { this.settings.set_int('pomodoro-fullscreen-monitor-pos', this.fullscreen.monitor); }); this.sigm.connect(this.settings, 'changed::pomodoro-separate-menu', () => { this.separate_menu = this.settings.get_boolean('pomodoro-separate-menu'); this.ext.update_panel_items(); }); this.sigm.connect(this.settings, 'changed::pomodoro-show-seconds', () => this._update_time_display()); this.sigm.connect(this.settings, 'changed::pomodoro-panel-mode', () => this._toggle_panel_mode()); this.sigm.connect(this.panel_item, 'middle-click', () => this.timer_toggle()); this.sigm.connect_release(this.settings_icon, Clutter.BUTTON_PRIMARY, true, () => this._show_settings()); this.sigm.connect_release(this.fullscreen_icon, Clutter.BUTTON_PRIMARY, true, () => this.show_fullscreen()); this.sigm.connect_release(this.button_continue, Clutter.BUTTON_PRIMARY, true, () => this.start_pomo()); this.sigm.connect_release(this.button_stop, Clutter.BUTTON_PRIMARY, true, () => this.stop()); this.sigm.connect_release(this.button_new_pomo, Clutter.BUTTON_PRIMARY, true, () => this.start_new_pomo()); this.sigm.connect_release(this.button_take_break, Clutter.BUTTON_PRIMARY, true, () => this.take_break()); // // finally // let count_str = String(this.cache.pomo_counter); this.clock_label.text = this.cache.pomo_counter ? count_str : ''; this.clock = this.cache.pomo_duration * 1000000; this._update_time_display(); this.header_label.text = _('Pomodoro'); } disable_section () { this.dbus_impl.unexport(); this.stop(); 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); } _show_settings () { let settings = new PomodoroSettings(this.ext, this, this.cache); this.settings_container.add_actor(settings.actor); settings.button_cancel.grab_key_focus(); this.header.hide(); this.button_box.hide(); settings.connect('ok', (_, res) => { this.cache.todo_task_id = res.todo_task_id; this.set_phase_durations( res.pomo, res.short_break, res.long_break, res.break_rate); if (this.pomo_state === PomoState.STOPPED) this.clock = this.cache.pomo_duration * 1000000; if (res.clear_counter) this.clear_pomo_counter(); this.button_box.show(); this.button_box.grab_key_focus(); settings.actor.destroy(); this.header.show(); this._update_time_display(); }); settings.connect('cancel', () => { this.button_box.show(); this.actor.grab_key_focus(); settings.actor.destroy(); this.header.show(); }); } show_fullscreen () { this.ext.menu.close(); if (! this.fullscreen) { this.fullscreen = new PomodoroFullscreen(this.ext, this, this.settings.get_int('pomodoro-fullscreen-monitor-pos')); } this.fullscreen.open(); } clear_pomo_counter () { this.cache.pomo_counter = 0; this.clock_label.text = ''; this._store_cache(); } // @pomo : int (seconds) // @short_break : int (seconds) // @long_break : int (seconds) // @break_rate : int (num of pomos until long break) set_phase_durations (pomo, short_break, long_break, break_rate) { this.cache.pomo_duration = Math.max(1, pomo); this.cache.short_break = Math.max(1, short_break); this.cache.long_break = Math.max(1, long_break); this.cache.long_break_rate = Math.max(1, break_rate); this._store_cache(); } stop () { this.clock = this.end_time - GLib.get_monotonic_time(); if (this.tic_mainloop_id) { Mainloop.source_remove(this.tic_mainloop_id); this.tic_mainloop_id = null; } if (this.pomo_state === PomoState.STOPPED) return; if (this.pomo_state !== PomoState.POMO) { this.clock = this.cache.pomo_duration; this.header_label.text = _('Pomodoro'); } this.sound_player.stop(); if (this.notif_source) this.notif_source.destroyNonResidentNotifications(); { let in_break = this.pomo_state === PomoState.LONG_BREAK || this.pomo_state === PomoState.SHORT_BREAK; this.button_continue.visible = !in_break; this.fullscreen.button_continue.visible = !in_break; this.button_new_pomo.visible = true; this.fullscreen.button_new_pomo.visible = true; this.button_stop.visible = false; this.button_take_break.visible = false; this.fullscreen.button_stop.visible = false; this.fullscreen.button_take_break.visible = false; } this.pomo_state = PomoState.STOPPED; if (!this.fullscreen.is_open && this.actor.visible) this.button_stop.grab_key_focus(); this.fullscreen.on_stop(); this._update_phase_label(); this._update_panel_item(); if (this.settings.get_enum('pomodoro-panel-mode') === PanelMode.DYNAMIC) this.panel_item.set_mode('icon'); this.dbus_impl.emit_signal('pomo_state_changed', GLib.Variant.new('(s)', [this.pomo_state])); if (this.cache.todo_task_id) { this.ext.emit_to_sections('stop-time-tracking-by-id', this.section_name, this.cache.todo_task_id); } } start_new_pomo () { this.start_pomo(this.cache.pomo_duration); } // @time: int (seconds) start_pomo (time) { if (this.tic_mainloop_id) { Mainloop.source_remove(this.tic_mainloop_id); this.tic_mainloop_id = null; } if (time) time *= 1000000; else time = this.clock; this.pomo_state = PomoState.POMO; this.end_time = GLib.get_monotonic_time() + time; this.sound_player.stop(); if (this.notif_source) this.notif_source.destroyNonResidentNotifications(); this._update_panel_item(); this._update_phase_label(); this.button_continue.visible = false; this.button_stop.visible = true; this.button_take_break.visible = true; this.button_new_pomo.visible = true; this.fullscreen.button_continue.visible = false; this.fullscreen.button_stop.visible = true; this.fullscreen.button_take_break.visible = true; this.fullscreen.button_new_pomo.visible = true; if (this.settings.get_enum('pomodoro-panel-mode') === PanelMode.DYNAMIC) this.panel_item.set_mode('icon_text'); if (!this.fullscreen.is_open && this.actor.visible) this.button_stop.grab_key_focus(); this._tic(); this.fullscreen.on_start(); this.dbus_impl.emit_signal('pomo_state_changed', GLib.Variant.new('(s)', [this.pomo_state])); if (this.cache.todo_task_id) { this.ext.emit_to_sections('start-time-tracking-by-id', this.section_name, this.cache.todo_task_id); } } take_break () { if (this.tic_mainloop_id) { Mainloop.source_remove(this.tic_mainloop_id); this.tic_mainloop_id = null; } if (this.cache.pomo_counter && (this.cache.pomo_counter % this.cache.long_break_rate) === 0) { this.pomo_state = PomoState.LONG_BREAK; this.clock = this.cache.long_break * 1000000; } else { this.pomo_state = PomoState.SHORT_BREAK; this.clock = this.cache.short_break * 1000000; } this.end_time = GLib.get_monotonic_time() + this.clock; this.sound_player.stop(); if (this.notif_source) this.notif_source.destroyNonResidentNotifications(); this._update_time_display(); this._update_phase_label(); this._update_panel_item(); this.fullscreen.on_break(); this.button_continue.visible = false; this.button_stop.visible = true; this.button_take_break.visible = false; this.fullscreen.button_continue.visible = false; this.fullscreen.button_stop.visible = true; this.fullscreen.button_take_break.visible = false; this.fullscreen.button_new_pomo.visible = true; if (this.settings.get_enum('pomodoro-panel-mode') === PanelMode.DYNAMIC) this.panel_item.set_mode('icon_text'); if (this.cache.todo_task_id) this.ext.emit_to_sections('stop-time-tracking-by-id', this.section_name, this.cache.todo_task_id); this._tic(); this.dbus_impl.emit_signal('pomo_state_changed', GLib.Variant.new('(s)', [this.pomo_state])); } timer_toggle () { if (this.pomo_state === PomoState.STOPPED) this.start_pomo(); else this.stop(); } _update_time_display () { let time = Math.ceil(this.clock / 1000000); let txt; // If the seconds are not shown, we need to make the timer '1-indexed' // with respect to minutes. I.e., 00:00:34 becomes 00:01. if (this.settings.get_boolean('pomodoro-show-seconds')) { txt = "%02d:%02d:%02d".format( Math.floor(time / 3600), Math.floor(time % 3600 / 60), time % 60 ); } else { if (time > 0 && time !== this.cache.pomo_duration) time += 60; txt = "%02d:%02d".format( Math.floor(time / 3600), Math.floor(time % 3600 / 60) ); } this.header_label.text = txt; this.panel_item.set_label(txt); this.fullscreen.set_banner_text(txt); } _update_phase_label () { switch (this.pomo_state) { case PomoState.POMO: this.phase_label.text = POMO_STARTED_MSG; this.fullscreen.phase_label.text = POMO_STARTED_MSG; break; case PomoState.LONG_BREAK: this.phase_label.text = LONG_BREAK_MSG; this.fullscreen.phase_label.text = LONG_BREAK_MSG; break; case PomoState.SHORT_BREAK: this.phase_label.text = SHORT_BREAK_MSG; this.fullscreen.phase_label.text = SHORT_BREAK_MSG; break; case PomoState.STOPPED: this.phase_label.text = ''; this.fullscreen.phase_label.text = ''; break; } } _update_panel_item () { if (this.pomo_state === PomoState.STOPPED) this.panel_item.actor.remove_style_class_name('on'); else this.panel_item.actor.add_style_class_name('on'); } _timer_expired () { if (this.pomo_state === PomoState.LONG_BREAK || this.pomo_state === PomoState.SHORT_BREAK) { this.start_new_pomo(); } else { this.cache.pomo_counter += 1; this._store_cache(); this.take_break(); this.clock_label.text = '' + this.cache.pomo_counter; } this._send_notif(); } _tic () { this.clock = this.end_time - GLib.get_monotonic_time(); if (this.clock <= 0) { this.tic_mainloop_id = null; this._timer_expired(); return; } this._update_time_display(); this.tic_mainloop_id = Mainloop.timeout_add_seconds(1, () => { this._tic(); }); } _send_notif () { let do_play_sound, msg; switch (this.pomo_state) { case PomoState.POMO: msg = POMO_STARTED_MSG; do_play_sound = this.settings.get_boolean('pomodoro-play-sound-pomo'); this.sound_player.set_sound_uri(this.settings.get_string('pomodoro-sound-file-path-pomo')); break; case PomoState.SHORT_BREAK: msg = SHORT_BREAK_MSG; do_play_sound = this.settings.get_boolean('pomodoro-play-sound-short-break'); this.sound_player.set_sound_uri(this.settings.get_string('pomodoro-sound-file-path-short-break')); break; case PomoState.LONG_BREAK: msg = LONG_BREAK_MSG; do_play_sound = this.settings.get_boolean('pomodoro-play-sound-long-break'); this.sound_player.set_sound_uri(this.settings.get_string('pomodoro-sound-file-path-long-break')); break; default: return; } let notif_style = this.settings.get_enum('pomodoro-notif-style'); if (notif_style === NotifStyle.NONE || this.fullscreen.is_open) { // do nothing } else if (notif_style === NotifStyle.FULLSCREEN) { this.fullscreen.open(); } else { if (this.notif_source) { this.notif_source.destroyNonResidentNotifications(); } this.notif_source = new MessageTray.Source(); Main.messageTray.add(this.notif_source); this.notif_source.connect('destroy', () => this.sound_player.stop()); let icon = new St.Icon({ gicon : MISC_UTILS.getIcon('timepp-pomodoro-symbolic') }); let params = { bannerMarkup : true, gicon : icon.gicon, }; let notif = new MessageTray.Notification(this.notif_source, msg, '', params); notif.setUrgency(MessageTray.Urgency.NORMAL); this.notif_source.notify(notif); } if (do_play_sound) this.sound_player.play(this.settings.get_boolean('pomodoro-do-repeat-notif-sound')); } _toggle_panel_mode () { switch (this.settings.get_enum('pomodoro-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.pomo_state === PomoState.STOPPED) this.panel_item.set_mode('icon'); else this.panel_item.set_mode('icon_text'); } } } Signals.addSignalMethods(SectionMain.prototype); // ===================================================================== // @@@ Pomodoro settings // // @delegate : obj (main section object) // @pomo_cache : obj (section cache object) // // @signals: 'ok', 'cancel' // ===================================================================== var PomodoroSettings = class PomodoroSettings { constructor (ext, delegate, pomo_cache) { this.ext = ext; this.delegate = delegate; this.actor = new St.BoxLayout({style_class: 'view-box'}); this.content_box = new St.BoxLayout({vertical: true, style_class: 'view-box-content'}); this.actor.add(this.content_box, {expand: true}); // // clear all pomodoros // this.clear_all_item = new St.BoxLayout({style_class: 'row'}); this.content_box.add_actor(this.clear_all_item); this.clear_item_label = new St.Label({text: `${_('Reset pomodoro counter?')} `, y_align: Clutter.ActorAlign.CENTER}); this.clear_all_item.add(this.clear_item_label, {expand: true}); this.clear_checkbox_bin = new St.Bin(); this.clear_all_item.add_actor(this.clear_checkbox_bin); this.clear_item_checkbox = new CheckBox.CheckBox(); this.clear_checkbox_bin.add_actor(this.clear_item_checkbox.actor); // // pomodoro duration // this.pomo_duration = new St.BoxLayout({style_class: 'row'}); this.content_box.add_actor(this.pomo_duration); this.pomo_label = new St.Label({text: `${POMO_STARTED_MSG} ${_('(min:sec)')} `, y_align: Clutter.ActorAlign.CENTER}); this.pomo_duration.add(this.pomo_label, {expand: true}); this.pomo_dur_min_picker = new NUM_PICKER.NumPicker(0, null); this.pomo_duration.add_actor(this.pomo_dur_min_picker.actor); this.pomo_dur_sec_picker = new NUM_PICKER.NumPicker(0, null); this.pomo_duration.add_actor(this.pomo_dur_sec_picker.actor); this.pomo_dur_min_picker.set_counter(Math.floor(pomo_cache.pomo_duration / 60)); this.pomo_dur_sec_picker.set_counter(pomo_cache.pomo_duration % 60); // // short break // this.short_break = new St.BoxLayout({style_class: 'row'}); this.content_box.add_actor(this.short_break); this.short_break_label = new St.Label({text: `${SHORT_BREAK_MSG} ${_('(min:sec)')} `, y_align: Clutter.ActorAlign.CENTER}); this.short_break.add(this.short_break_label, {expand: true}); this.short_break_min_picker = new NUM_PICKER.NumPicker(0, null); this.short_break.add_actor(this.short_break_min_picker.actor); this.short_break_sec_picker = new NUM_PICKER.NumPicker(0, null); this.short_break.add_actor(this.short_break_sec_picker.actor); this.short_break_min_picker.set_counter(Math.floor(pomo_cache.short_break / 60)); this.short_break_sec_picker.set_counter(pomo_cache.short_break % 60); // // long break // this.long_break = new St.BoxLayout({style_class: 'row'}); this.content_box.add_actor(this.long_break); this.long_break_label = new St.Label({text: `${LONG_BREAK_MSG} ${_('(min:sec)')} `, y_align: Clutter.ActorAlign.CENTER}); this.long_break.add(this.long_break_label, {expand: true}); this.long_break_min_picker = new NUM_PICKER.NumPicker(0, null); this.long_break.add_actor(this.long_break_min_picker.actor); this.long_break_sec_picker = new NUM_PICKER.NumPicker(0, null); this.long_break.add_actor(this.long_break_sec_picker.actor); this.long_break_min_picker.set_counter(Math.floor(pomo_cache.long_break / 60)); this.long_break_sec_picker.set_counter(pomo_cache.long_break % 60); // // how many pomodoros 'till long break // this.long_break_rate = new St.BoxLayout({style_class: 'row'}); this.content_box.add_actor(this.long_break_rate); this.long_break_rate_label = new St.Label({text: `${_('Num of pomos until long break')} `, y_align: Clutter.ActorAlign.CENTER}); this.long_break_rate.add(this.long_break_rate_label, {expand: true}); this.long_break_rate_picker = new NUM_PICKER.NumPicker(1, null); this.long_break_rate.add_actor(this.long_break_rate_picker.actor); this.long_break_rate_picker.set_counter(pomo_cache.long_break_rate); // // task id entry // if (this.ext.is_section_enabled('Todo')) { let entry_container = new St.BoxLayout({ vertical: true, x_expand: true, style_class: 'row' }); this.content_box.add_child(entry_container); this.entry = new MULTIL_ENTRY.MultiLineEntry(_('Control todo time tracker by task id...'), false, true); entry_container.add_child(this.entry.actor); this.entry.set_text(this.delegate.cache.todo_task_id); } // // buttons // this.button_box = new St.BoxLayout({ style_class: 'row btn-box' }); this.content_box.add(this.button_box, {expand: true}); this.button_ok = new St.Button({can_focus: true, label: _('Ok'), x_expand: true, style_class: 'button'}); this.button_cancel = new St.Button({can_focus: true, label: _('Cancel'), x_expand: true, style_class: 'button'}); this.button_box.add(this.button_cancel, {expand: true}); this.button_box.add(this.button_ok, {expand: true}); // // listen // this.button_ok.connect('clicked', () => { this.emit('ok', { clear_counter : this.clear_item_checkbox.actor.checked, break_rate : this.long_break_rate_picker.counter, pomo : this.pomo_dur_min_picker.counter * 60 + this.pomo_dur_sec_picker.counter, short_break : this.short_break_min_picker.counter * 60 + this.short_break_sec_picker.counter, long_break : this.long_break_min_picker.counter * 60 + this.long_break_sec_picker.counter, todo_task_id : this.entry ? this.entry.entry.get_text() : this.delegate.cache.todo_task_id, }); }); this.button_cancel.connect('clicked', () => { this.emit('cancel'); }); this.pomo_dur_min_picker.connect('spinner-changed', (_, n) => { if (n === 0 && this.pomo_dur_sec_picker.counter === 0) this.pomo_dur_min_picker.set_counter(1); }); this.pomo_dur_sec_picker.connect('spinner-changed', (_, n) => { if (n === 0 && this.pomo_dur_min_picker.counter === 0) this.pomo_dur_sec_picker.set_counter(1); }); this.long_break_min_picker.connect('spinner-changed', (_, n) => { if (n === 0 && this.long_break_sec_picker.counter === 0) this.long_break_min_picker.set_counter(1); }); this.long_break_sec_picker.connect('spinner-changed', (_, n) => { if (n === 0 && this.long_break_min_picker.counter === 0) this.long_break_sec_picker.set_counter(1); }); this.short_break_min_picker.connect('spinner-changed', (_, n) => { if (n === 0 && this.short_break_sec_picker.counter === 0) this.short_break_min_picker.set_counter(1); }); this.short_break_sec_picker.connect('spinner-changed', (_, n) => { if (n === 0 && this.short_break_min_picker.counter === 0) this.short_break_sec_picker.set_counter(1); }); } } Signals.addSignalMethods(PomodoroSettings.prototype); // ===================================================================== // @@@ Pomodoro fullscreen // // @ext : obj (main extension object) // @delegate : obj (main section object) // @monitor : int // // signals: 'monitor-changed' // ===================================================================== var PomodoroFullscreen = class PomodoroFullscreen extends FULLSCREEN.Fullscreen { constructor (ext, delegate, monitor) { super(monitor); this.ext = ext; this.delegate = delegate; this.default_style_class = this.actor.style_class; // // phase label // this.phase_label = new St.Label({ x_expand: true, x_align: Clutter.ActorAlign.CENTER, style_class: 'pomo-phase-label' }); this.middle_box.insert_child_at_index(this.phase_label, 0); // // buttons // this.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.button_box) this.button_new_pomo = new St.Button({can_focus: true, label: _('New Pomo'), visible: false, style_class: 'button'}); this.button_take_break = new St.Button({can_focus: true, label: _('Take Break'), visible: false, style_class: 'button'}); this.button_continue = new St.Button({can_focus: true, label: _('Continue'), style_class: 'button'}); this.button_stop = new St.Button({can_focus: true, label: _('Stop'), visible: false, style_class: 'button'}); this.button_box.add_child(this.button_new_pomo); this.button_box.add_child(this.button_take_break); this.button_box.add_child(this.button_continue); this.button_box.add_child(this.button_stop); // // listen // this.button_continue.connect('clicked', () => { this.delegate.start_pomo(); return Clutter.EVENT_STOP; }); this.button_stop.connect('clicked', () => { this.delegate.stop(); return Clutter.EVENT_STOP; }); this.button_new_pomo.connect('clicked',() => { this.delegate.start_new_pomo(); return Clutter.EVENT_STOP; }); this.button_take_break.connect('clicked', () => { this.delegate.take_break(); return Clutter.EVENT_STOP; }); this.actor.connect('key-release-event', (_, event) => { switch (event.get_key_symbol()) { case Clutter.KEY_space: this.delegate.timer_toggle(); return Clutter.EVENT_STOP; default: return Clutter.EVENT_PROPAGATE; } }); } close () { this.delegate.sound_player.stop(); super.close(); } on_start () { switch (this.delegate.pomo_state) { case PomoState.POMO: this.actor.style_class = this.default_style_class + ' pomo-running'; break; case PomoState.LONG_BREAK: this.actor.style_class = this.default_style_class + ' pomo-long-break'; break; case PomoState.SHORT_BREAK: this.actor.style_class = this.default_style_class + ' pomo-short-break'; break; } } on_stop () { this.actor.style_class = this.default_style_class + ' pomo-stopped'; this.phase_label.text = ''; } on_new_pomo () { this.actor.style_class = this.default_style_class + ' pomo-running'; this.phase_label.text = POMO_STARTED_MSG; } on_break () { switch (this.delegate.pomo_state) { case PomoState.LONG_BREAK: this.actor.style_class = this.default_style_class + ' pomo-long-break'; this.phase_label.text = LONG_BREAK_MSG; break; case PomoState.SHORT_BREAK: this.actor.style_class = this.default_style_class + ' pomo-short-break'; this.phase_label.text = SHORT_BREAK_MSG; break; } } } Signals.addSignalMethods(PomodoroFullscreen.prototype);