Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file modified BinaryClock.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
244 changes: 193 additions & 51 deletions [email protected]/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,98 +5,240 @@
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/

// show the time label (11:23) in the date menu:
const TimePosition = {
// * not at all?
NONE: 0,
// * above the date label ("Wednesday November 7, 2012")?
ABOVE_DATE: 1,
// * below the date label?
BELOW_DATE: 2
};

////// CONFIGURE //////
// show the time label (11:23) in the date menu:
// * above the date label ("Wednesday November 7, 2012")?
// * below the date label?
// * not at all?
let timePosition = TimePosition.BELOW_DATE;

////// CODE //////

const Main = imports.ui.main;
const Lang = imports.lang;
const Mainloop = imports.mainloop;
const PanelMenu = imports.ui.panelMenu;
const Panel = imports.ui.panel;
const St = imports.gi.St;
const Clutter = imports.gi.Clutter;
const Clutter = imports.gi.Clutter;
const Cairo = imports.cairo;
const Gio = imports.gi.Gio;


const UPDATE_INTERVAL = 500;
const UPDATE_INTERVAL = 1000;
// width of lines between the squares (px)
const LINE_WIDTH = 2;
// marging around the entire clock top & bottom (px)
const MARGIN = 1;
// padding square and the black centre
const PADDING = 2;

// compatibility GNOME 3.2, 3.4, 3.6
function _getDateMenu() {
return Main.panel._dateMenu || Main.panel.statusArea.dateMenu;
}
function _getClockActor() {
let dm = _getDateMenu();
return dm._clockDisplay || dm._clock;
}
function insert_child_above(container, child, sibling) {
if (container.insert_child_above) {
container.insert_child_above(child, sibling);
} else { // gnome 3.2
container.add_actor(child);
container.raise_child(child, sibling);
}
}
function insert_child_below(container, child, sibling) {
if (container.insert_child_below) {
container.insert_child_below(child, sibling);
} else { // gnome 3.2
container.insert_child_at_index(child);
container.lower_child(child, sibling);
}
}

// -------------------------------
function BinaryClock() {
this._init();
}

BinaryClock.prototype = {
_init: function() {
let now = new Date();
this.display_time = [now.getHours(), now.getMinutes()];
let date_menu = Main.panel._dateMenu;
this._clock = date_menu._clock;
_init: function () {
this.display_time = [-1, -1];
//this.time_format = "%R:%S"; // Safe fallback

this.date_menu = _getDateMenu();
this.orig_clock = _getClockActor();
this.binary_clock = new St.DrawingArea();
this.date = new St.Label({ style_class: "datemenu-date-label", text: this._clock.get_text() });

this.bs = Math.floor(Main.panel.button.height/2)-2*MARGIN; // Box size

this.binary_clock.set_width(MARGIN*2 + (this.bs + MARGIN + LINE_WIDTH)*6);
this.binary_clock.set_height(Main.panel.button.height);
date_menu.actor.add_actor(this.binary_clock);

this.binary_clock.connect("repaint", Lang.bind(this, this.paint_clock));
this.binary_clock.queue_repaint();

let children = date_menu.menu.box.get_children();
for each(let c in children) {
if(c.name == "calendarArea") {
c.get_children()[0].insert_actor(this.date, 0);
break;
}

// Box size. Should be *even* and integer but still fit vertically.
this.bs = Math.floor((Panel.PANEL_ICON_SIZE - 2 * MARGIN - LINE_WIDTH) / 2);
if (this.bs % 2) {
this.bs -= 1;
}
let height = 2 * this.bs + LINE_WIDTH;
this.binary_clock.set_width(6 * this.bs + 5 * LINE_WIDTH);
this.binary_clock.set_height(height);

this.repaint = this.binary_clock.connect("repaint",
Lang.bind(this, this.paint_clock));
},

Run: function() {
Mainloop.timeout_add(UPDATE_INTERVAL, Lang.bind(this, this.on_timeout));

Run: function () {
this.run = true;
this.on_timeout();
Mainloop.timeout_add(UPDATE_INTERVAL, Lang.bind(this, this.on_timeout));
},

on_timeout: function() {
this.date.set_text(this._clock.get_text());


on_timeout: function () {
let now = new Date();
//this.time_label.set_text(now.toLocaleFormat(this.time_format))
let display_time = [now.getHours(), now.getMinutes()];

if ((this.display_time[0] != display_time[0]) || (this.display_time[1] != display_time[1])) {

if ((this.display_time[0] !== display_time[0]) ||
(this.display_time[1] !== display_time[1])) {
this.display_time = display_time;
this.binary_clock.queue_repaint();
}

return true;
},


// to avoid fuzziness in cairo. If the line width is even you have to start
// drawing on integer coordinates, otherwise on integer + 0.5 coordinates.
paint_clock: function (area) {
let cr = area.get_context();
let theme_node = this.binary_clock.get_theme_node();


let area_height = area.get_height();
let area_width = area.get_width();

// Draw background
Clutter.cairo_set_source_color(cr, theme_node.get_foreground_color());
for (let p in cr) global.log(p);
cr.setLineWidth(LINE_WIDTH);

for (let p in this.display_time) {
for (let i=0; i<6; ++i) {
cr.rectangle(MARGIN + LINE_WIDTH/2 + (this.bs + MARGIN + LINE_WIDTH)*i, LINE_WIDTH/2 + (this.bs + MARGIN + LINE_WIDTH)*p, this.bs, this.bs);
cr.rectangle(0, 0, area_width, area_height);
cr.fill();

// Draw grid
cr.setSourceRGBA(0, 0, 0, 0);
cr.setOperator(Cairo.Operator.CLEAR);
// ensure no fuzziness
let halfHeight = Math.floor(area_height / 2) + (LINE_WIDTH % 2 ? 0.5 : 0);
cr.moveTo(0, halfHeight);
cr.lineTo(area_width, halfHeight);
cr.stroke();

// Draw dots (precache some stuff)
let dim = this.bs - 2 * LINE_WIDTH, // dimension of internal box
halfLineWidth = LINE_WIDTH / 2,
blockWidth = this.bs + LINE_WIDTH;
for (let p = 0; p < this.display_time.length; ++p) {
for (let i = 0; i < 6; ++i) {
let startx = i * blockWidth;
let borderx = startx + this.bs + halfLineWidth; // FOR SURE

// draw the border
cr.moveTo(borderx, 0);
cr.lineTo(borderx, area_height);
cr.stroke();
if (!(this.display_time[p] & (1 << (5-i)))) {
cr.rectangle(MARGIN + LINE_WIDTH/2 + (this.bs + MARGIN + LINE_WIDTH)*i, + LINE_WIDTH/2 + (this.bs + MARGIN + LINE_WIDTH)*p, this.bs, this.bs);

// draw the rectangle.
if ((this.display_time[p] & (1 << (5 - i)))) {
cr.rectangle(
startx + PADDING,
p * blockWidth + PADDING,
dim,
dim
);
cr.fill();
}
}
}

},

getShowDate: function () {
if (this.date_menu._clock.time_only !== undefined) {
return !this.date_menu._clock.time_only;
} else {
return this.date_menu._clockSettings.get_boolean('show-date');
}
},

toggleShowDate: function (state) {
if (this.getShowDate() === state) {
return;
}
if (this.date_menu._clock.time_only !== undefined) {
this.date_menu._clock.time_only = !state;
} else {
this.date_menu._clockSettings.set_boolean('show-date', state);

}
},

enable: function () {
this.date_menu.actor.remove_actor(this.orig_clock);
this.date_menu.actor.add_actor(this.binary_clock);
this.date_menu.actor.add_style_class_name("binary-clock");

this.binary_clock.queue_repaint();

// show the time label in the date menu (or no at all)
this._originalShowDate = this.getShowDate();
if (timePosition !== TimePosition.NONE) {
this.toggleShowDate(false);
this.orig_clock.add_style_class_name('datemenu-date-label');
let children = this.date_menu.menu.box.get_children();
for (let i = 0; i < children.length; ++i) {
let c = children[i];
if (c.name === "calendarArea") {
let vbox = c.get_children()[0];
if (timePosition === TimePosition.BELOW_DATE) {
// note - since the box layout packs vertically downwards
// to get the label visually below _date we insert_child_above.
insert_child_above(vbox, this.orig_clock, this.date_menu._date);
} else {
insert_child_below(vbox, this.orig_clock, this.date_menu._date);
}
vbox.child_set(this.orig_clock, {x_align: St.Align.MIDDLE, x_fill: false});
break;
}
}
this.Run();
}
},

disable: function () {
this.run = false;
this.date_menu.actor.remove_style_class_name("binary-clock");
this.date_menu.actor.remove_actor(this.binary_clock);

this.toggleShowDate(this._originalShowDate);
this.orig_clock.reparent(this.date_menu.actor);
this.orig_clock.remove_style_class_name('datemenu-date-label');
}
}
};

function main() {
(new BinaryClock()).Run();
function init() {
return new BinaryClock();
}
10 changes: 8 additions & 2 deletions [email protected]/metadata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
{
"shell-version": ["3.0.2"],
"shell-version": [
"3.2",
"3.4",
"3.6"
],
"uuid": "[email protected]",
"name": "Binary Clock",
"description": "Shows a binary clock on panel instead of the default one"
"description": "Shows a binary clock on panel instead of the default one",
"url": "http://github.com/ojo/gnome-shell-extension-binaryclock",
"author": "Aleksander Zdyb"
}
3 changes: 3 additions & 0 deletions [email protected]/stylesheet.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
.binary-clock {
padding-top: 1px;
}
Binary file modified BinaryClockMenu.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 6 additions & 3 deletions README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ What it looks like?

Everybody loves screenshots, right?

.. image:: http://img191.imageshack.us/img191/1846/binaryclock.png
.. image:: http://img687.imageshack.us/img687/1846/binaryclock.png
:alt: BinaryClock

.. image:: http://img5.imageshack.us/img5/5193/binaryclockmenu.png
.. image:: http://img805.imageshack.us/img805/5193/binaryclockmenu.png
:alt: BinaryClock (menu)


Expand All @@ -40,6 +40,9 @@ or::

$ cp BinaryClock\@zdyb.tk ~/.local/share/gnome-shell/extensions/

Please do not forget to enable the newly installed extension using for example gnome-tweak-tool_.

.. _gnome-tweak-tool: http://live.gnome.org/GnomeTweakTool

License
=======
Expand All @@ -56,4 +59,4 @@ WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with
this program. If not, see http://www.gnu.org/licenses/.
this program. If not, see http://www.gnu.org/licenses/.