Port LookingGlass console to ST widgets

* Style aspects like colors and fonts are moved into gnome-shell.css.
* Scrolling is adding using StScrollView.

Based on a patch from Colin Walters
https://bugzilla.gnome.org/show_bug.cgi?id=591245
This commit is contained in:
Owen W. Taylor 2009-09-10 01:38:13 -04:00
parent a37c86636b
commit 25f1246b6f
2 changed files with 103 additions and 104 deletions

View File

@ -60,3 +60,39 @@ StScrollBar StButton#vhandle:hover
{ {
border-image: url("scroll-vhandle.png") 5; border-image: url("scroll-vhandle.png") 5;
} }
/* LookingGlass */
#LookingGlassDialog
{
background-color: rgba(0,0,0,0.85);
spacing: 4px;
padding: 4px;
border: 1px solid rgba(0,0,172,0.85);
border-radius: 4px;
font-family: Monospace;
color: #88ff66;
}
#LookingGlassDialog > #Toolbar
{
border: 1px solid grey;
border-radius: 4px;
}
#LookingGlassDialog StLabel
{
color: #88ff66;
}
#LookingGlassDialog StEntry
{
color: #88ff66;
}
#LookingGlassDialog StBoxLayout#EvalBox
{
padding: 4px;
spacing: 4px;
}

View File

@ -4,6 +4,7 @@ const Big = imports.gi.Big;
const Clutter = imports.gi.Clutter; const Clutter = imports.gi.Clutter;
const Gio = imports.gi.Gio; const Gio = imports.gi.Gio;
const Pango = imports.gi.Pango; const Pango = imports.gi.Pango;
const St = imports.gi.St;
const Shell = imports.gi.Shell; const Shell = imports.gi.Shell;
const Signals = imports.signals; const Signals = imports.signals;
const Lang = imports.lang; const Lang = imports.lang;
@ -12,17 +13,6 @@ const Mainloop = imports.mainloop;
const Tweener = imports.ui.tweener; const Tweener = imports.ui.tweener;
const Main = imports.ui.main; const Main = imports.ui.main;
const LG_BORDER_COLOR = new Clutter.Color();
LG_BORDER_COLOR.from_pixel(0x0000aca0);
const LG_BACKGROUND_COLOR = new Clutter.Color();
LG_BACKGROUND_COLOR.from_pixel(0x000000d5);
const GREY = new Clutter.Color();
GREY.from_pixel(0xAFAFAFFF);
const MATRIX_GREEN = new Clutter.Color();
MATRIX_GREEN.from_pixel(0x88ff66ff);
// FIXME pull from GConf
const MATRIX_FONT = 'Monospace 10';
/* Imports...feel free to add here as needed */ /* Imports...feel free to add here as needed */
var commandHeader = "const Clutter = imports.gi.Clutter; " + var commandHeader = "const Clutter = imports.gi.Clutter; " +
"const GLib = imports.gi.GLib; " + "const GLib = imports.gi.GLib; " +
@ -47,7 +37,7 @@ function Notebook() {
Notebook.prototype = { Notebook.prototype = {
_init: function() { _init: function() {
this.actor = new Big.Box(); this.actor = new St.BoxLayout({ vertical: true });
this.tabControls = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL, this.tabControls = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL,
spacing: 4, padding: 2 }); spacing: 4, padding: 2 });
@ -58,21 +48,24 @@ Notebook.prototype = {
appendPage: function(name, child) { appendPage: function(name, child) {
let labelOuterBox = new Big.Box({ padding: 2 }); let labelOuterBox = new Big.Box({ padding: 2 });
let labelBox = new Big.Box({ padding: 2, border_color: MATRIX_GREEN, let labelBox = new St.BoxLayout({ reactive: true });
reactive: true });
labelOuterBox.append(labelBox, Big.BoxPackFlags.NONE); labelOuterBox.append(labelBox, Big.BoxPackFlags.NONE);
let label = new Clutter.Text({ color: MATRIX_GREEN, let label = new St.Label({ text: name });
font_name: MATRIX_FONT,
text: name });
labelBox.connect('button-press-event', Lang.bind(this, function () { labelBox.connect('button-press-event', Lang.bind(this, function () {
this.selectChild(child); this.selectChild(child);
return true; return true;
})); }));
labelBox.append(label, Big.BoxPackFlags.EXPAND); labelBox.add(label, { expand: true });
this._tabs.push([child, labelBox]);
child.hide();
this.actor.append(child, Big.BoxPackFlags.EXPAND);
this.tabControls.append(labelOuterBox, Big.BoxPackFlags.NONE); this.tabControls.append(labelOuterBox, Big.BoxPackFlags.NONE);
let scrollview = new St.ScrollView({ x_fill: true, y_fill: true });
scrollview.get_hscroll_bar().hide();
scrollview.add_actor(child);
this._tabs.push([child, labelBox, scrollview]);
scrollview.hide();
this.actor.add(scrollview, { expand: true });
if (this._selectedIndex == -1) if (this._selectedIndex == -1)
this.selectIndex(0); this.selectIndex(0);
}, },
@ -80,10 +73,10 @@ Notebook.prototype = {
_unselect: function() { _unselect: function() {
if (this._selectedIndex < 0) if (this._selectedIndex < 0)
return; return;
let [child, labelBox] = this._tabs[this._selectedIndex]; let [child, labelBox, scrollview] = this._tabs[this._selectedIndex];
labelBox.padding = 2; labelBox.padding = 2;
labelBox.border = 0; labelBox.border = 0;
child.hide(); scrollview.hide();
this._selectedIndex = -1; this._selectedIndex = -1;
}, },
@ -95,10 +88,10 @@ Notebook.prototype = {
this.emit('selection', null); this.emit('selection', null);
return; return;
} }
let [child, labelBox] = this._tabs[index]; let [child, labelBox, scrollview] = this._tabs[index];
labelBox.padding = 1; labelBox.padding = 1;
labelBox.border = 1; labelBox.border = 1;
child.show(); scrollview.show();
this._selectedIndex = index; this._selectedIndex = index;
this.emit('selection', child); this.emit('selection', child);
}, },
@ -108,7 +101,7 @@ Notebook.prototype = {
this.selectIndex(-1); this.selectIndex(-1);
else { else {
for (let i = 0; i < this._tabs.length; i++) { for (let i = 0; i < this._tabs.length; i++) {
let [tabChild, labelBox] = this._tabs[i]; let [tabChild, labelBox, scrollview] = this._tabs[i];
if (tabChild == child) { if (tabChild == child) {
this.selectIndex(i); this.selectIndex(i);
return; return;
@ -130,20 +123,19 @@ Result.prototype = {
this.actor = new Big.Box(); this.actor = new Big.Box();
let cmdTxt = new Clutter.Text({ color: MATRIX_GREEN, let cmdTxt = new St.Label({ text: command });
font_name: MATRIX_FONT, cmdTxt.ellipsize = Pango.EllipsizeMode.END;
ellipsize: Pango.EllipsizeMode.END,
text: command });
this.actor.append(cmdTxt, Big.BoxPackFlags.NONE); this.actor.append(cmdTxt, Big.BoxPackFlags.NONE);
let resultTxt = new Clutter.Text({ color: MATRIX_GREEN, let resultTxt = new St.Label({ text: "r(" + index + ") = " + o });
font_name: MATRIX_FONT, resultTxt.ellipsize = Pango.EllipsizeMode.END;
ellipsize: Pango.EllipsizeMode.END,
text: "r(" + index + ") = " + o });
this.actor.append(resultTxt, Big.BoxPackFlags.NONE); this.actor.append(resultTxt, Big.BoxPackFlags.NONE);
let line = new Big.Box({ border_color: GREY, let line = new Clutter.Rectangle({ name: "Separator",
border_bottom: 1, height: 1 });
height: 8 }); let padBin = new St.Bin({ name: "Separator", x_fill: true, y_fill: true });
this.actor.append(line, Big.BoxPackFlags.NONE); padBin.add_actor(line);
this.actor.append(padBin, Big.BoxPackFlags.NONE);
} }
} }
@ -158,17 +150,14 @@ ActorHierarchy.prototype = {
this._parentList = []; this._parentList = [];
this.actor = new Big.Box({ spacing: 4, this.actor = new St.BoxLayout({ name: "ActorHierarchy", vertical: true });
border: 1,
padding: 4,
border_color: GREY });
}, },
setTarget: function(actor) { setTarget: function(actor) {
this._previousTarget = this._target; this._previousTarget = this._target;
this.target = actor; this.target = actor;
this.actor.remove_all(); this.actor.get_children().forEach(function (child) { child.destroy(); });
if (!(actor instanceof Clutter.Actor)) if (!(actor instanceof Clutter.Actor))
return; return;
@ -181,11 +170,9 @@ ActorHierarchy.prototype = {
while ((parent = parent.get_parent()) != null) { while ((parent = parent.get_parent()) != null) {
this._parentList.push(parent); this._parentList.push(parent);
let link = new Clutter.Text({ color: MATRIX_GREEN, let link = new St.Label({ reactive: true,
font_name: MATRIX_FONT,
reactive: true,
text: "" + parent }); text: "" + parent });
this.actor.append(link, Big.BoxPackFlags.IF_FITS); this.actor.add_actor(link);
let parentTarget = parent; let parentTarget = parent;
link.connect('button-press-event', Lang.bind(this, function () { link.connect('button-press-event', Lang.bind(this, function () {
this._selectByActor(parentTarget); this._selectByActor(parentTarget);
@ -214,16 +201,13 @@ PropertyInspector.prototype = {
this._parentList = []; this._parentList = [];
this.actor = new Big.Box({ spacing: 4, this.actor = new St.BoxLayout({ name: "PropertyInspector", vertical: true });
border: 1,
padding: 4,
border_color: GREY });
}, },
setTarget: function(actor) { setTarget: function(actor) {
this.target = actor; this.target = actor;
this.actor.remove_all(); this.actor.get_children().forEach(function (child) { child.destroy(); });
for (let propName in actor) { for (let propName in actor) {
let valueStr; let valueStr;
@ -233,11 +217,9 @@ PropertyInspector.prototype = {
valueStr = '<error>'; valueStr = '<error>';
} }
let propText = propName + ": " + valueStr; let propText = propName + ": " + valueStr;
let propDisplay = new Clutter.Text({ color: MATRIX_GREEN, let propDisplay = new St.Label({ reactive: true,
font_name: MATRIX_FONT,
reactive: true,
text: propText }); text: propText });
this.actor.append(propDisplay, Big.BoxPackFlags.IF_FITS); this.actor.add_actor(propDisplay);
} }
} }
} }
@ -249,20 +231,16 @@ function Inspector() {
Inspector.prototype = { Inspector.prototype = {
_init: function() { _init: function() {
let width = 150; let width = 150;
let eventHandler = new Big.Box({ background_color: LG_BACKGROUND_COLOR, let eventHandler = new St.BoxLayout({ name: "LookingGlassDialog",
border: 1, vertical: false,
border_color: LG_BORDER_COLOR, y: Math.floor(global.stage.height/2),
corner_radius: 4, reactive: true });
y: global.stage.height/2,
reactive: true
});
eventHandler.connect('notify::allocation', Lang.bind(this, function () { eventHandler.connect('notify::allocation', Lang.bind(this, function () {
eventHandler.x = Math.floor((global.stage.width)/2 - (eventHandler.width)/2); eventHandler.x = Math.floor((global.stage.width)/2 - (eventHandler.width)/2);
})); }));
global.stage.add_actor(eventHandler); global.stage.add_actor(eventHandler);
let displayText = new Clutter.Text({ color: MATRIX_GREEN, let displayText = new St.Label();
font_name: MATRIX_FONT, text: '' }); eventHandler.add(displayText, { expand: true });
eventHandler.append(displayText, Big.BoxPackFlags.EXPAND);
let borderPaintTarget = null; let borderPaintTarget = null;
let borderPaintId = null; let borderPaintId = null;
@ -321,29 +299,19 @@ LookingGlass.prototype = {
this._offset = 0; this._offset = 0;
this._results = []; this._results = [];
// TODO replace with scrolling or something better // Sort of magic, but...eh.
this._maxItems = 10; this._maxItems = 150;
this.actor = new Big.Box({ background_color: LG_BACKGROUND_COLOR, this.actor = new St.BoxLayout({ name: "LookingGlassDialog",
border: 1, vertical: true,
border_color: LG_BORDER_COLOR, visible: false });
corner_radius: 4,
padding_top: 8,
padding_left: 4,
padding_right: 4,
padding_bottom: 4,
spacing: 4,
visible: false
});
global.stage.add_actor(this.actor); global.stage.add_actor(this.actor);
let toolbar = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL, let toolbar = new St.BoxLayout({ name: "Toolbar" });
border: 1, border_color: GREY, this.actor.add_actor(toolbar);
corner_radius: 4 });
this.actor.append(toolbar, Big.BoxPackFlags.NONE);
let inspectIcon = Shell.TextureCache.get_default().load_gicon(new Gio.ThemedIcon({ name: 'gtk-color-picker' }), let inspectIcon = Shell.TextureCache.get_default().load_gicon(new Gio.ThemedIcon({ name: 'gtk-color-picker' }),
24); 24);
toolbar.append(inspectIcon, Big.BoxPackFlags.NONE); toolbar.add_actor(inspectIcon);
inspectIcon.reactive = true; inspectIcon.reactive = true;
inspectIcon.connect('button-press-event', Lang.bind(this, function () { inspectIcon.connect('button-press-event', Lang.bind(this, function () {
let inspector = new Inspector(); let inspector = new Inspector();
@ -361,31 +329,26 @@ LookingGlass.prototype = {
})); }));
let notebook = new Notebook(); let notebook = new Notebook();
this.actor.append(notebook.actor, Big.BoxPackFlags.EXPAND); this.actor.add(notebook.actor, { expand: true });
toolbar.append(notebook.tabControls, Big.BoxPackFlags.END);
this._evalBox = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL, let emptyBox = new St.Bin();
spacing: 4 }); toolbar.add(emptyBox, { expand: true });
toolbar.add_actor(notebook.tabControls);
this._evalBox = new St.BoxLayout({ name: "EvalBox", vertical: true });
notebook.appendPage('Evaluator', this._evalBox); notebook.appendPage('Evaluator', this._evalBox);
this._resultsArea = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL, this._resultsArea = new Big.Box({ orientation: Big.BoxOrientation.VERTICAL,
spacing: 4 }); spacing: 4 });
this._evalBox.append(this._resultsArea, Big.BoxPackFlags.EXPAND); this._evalBox.add(this._resultsArea, { expand: true });
let entryArea = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL }); let entryArea = new Big.Box({ orientation: Big.BoxOrientation.HORIZONTAL });
this._evalBox.append(entryArea, Big.BoxPackFlags.NONE); this._evalBox.add_actor(entryArea);
let label = new Clutter.Text({ color: MATRIX_GREEN, let label = new St.Label({ text: 'js>>> ' });
font_name: MATRIX_FONT,
text: 'js>>> ' });
entryArea.append(label, Big.BoxPackFlags.NONE); entryArea.append(label, Big.BoxPackFlags.NONE);
this._entry = new Clutter.Text({ color: MATRIX_GREEN, this._entry = new St.Entry();
font_name: MATRIX_FONT,
editable: true,
activatable: true,
singleLineMode: true,
text: ''});
/* unmapping the edit box will un-focus it, undo that */ /* unmapping the edit box will un-focus it, undo that */
notebook.connect('selection', Lang.bind(this, function (nb, child) { notebook.connect('selection', Lang.bind(this, function (nb, child) {
if (child == this._evalBox) if (child == this._evalBox)
@ -403,7 +366,7 @@ LookingGlass.prototype = {
notebook.selectIndex(0); notebook.selectIndex(0);
})); }));
this._entry.connect('activate', Lang.bind(this, function (o, e) { this._entry.clutter_text.connect('activate', Lang.bind(this, function (o, e) {
let text = o.get_text(); let text = o.get_text();
// Ensure we don't get newlines in the command; the history file is // Ensure we don't get newlines in the command; the history file is
// newline-separated. // newline-separated.
@ -416,7 +379,7 @@ LookingGlass.prototype = {
this._historyNavIndex = -1; this._historyNavIndex = -1;
return true; return true;
})); }));
this._entry.connect('key-press-event', Lang.bind(this, function(o, e) { this._entry.clutter_text.connect('key-press-event', Lang.bind(this, function(o, e) {
let symbol = e.get_key_symbol(); let symbol = e.get_key_symbol();
if (symbol == Clutter.Escape) { if (symbol == Clutter.Escape) {
this.close(); this.close();