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:
parent
b77b205d37
commit
d4304495c6
@ -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;
|
||||||
|
}
|
||||||
|
@ -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,18 +13,7 @@ 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();
|
/* Imports...feel free to add here as needed */
|
||||||
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 */
|
|
||||||
var commandHeader = "const Clutter = imports.gi.Clutter; " +
|
var commandHeader = "const Clutter = imports.gi.Clutter; " +
|
||||||
"const GLib = imports.gi.GLib; " +
|
"const GLib = imports.gi.GLib; " +
|
||||||
"const Gtk = imports.gi.Gtk; " +
|
"const Gtk = imports.gi.Gtk; " +
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -250,20 +232,16 @@ Inspector.prototype = {
|
|||||||
_init: function() {
|
_init: function() {
|
||||||
let width = 150;
|
let width = 150;
|
||||||
let primary = global.get_primary_monitor();
|
let primary = global.get_primary_monitor();
|
||||||
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,
|
|
||||||
corner_radius: 4,
|
|
||||||
y: primary.y + Math.floor(primary.height / 2),
|
y: primary.y + Math.floor(primary.height / 2),
|
||||||
reactive: true
|
reactive: true });
|
||||||
});
|
|
||||||
eventHandler.connect('notify::allocation', Lang.bind(this, function () {
|
eventHandler.connect('notify::allocation', Lang.bind(this, function () {
|
||||||
eventHandler.x = primary.x + Math.floor((primary.width - eventHandler.width) / 2);
|
eventHandler.x = primary.x + Math.floor((primary.width - 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;
|
||||||
@ -322,29 +300,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();
|
||||||
@ -362,31 +330,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)
|
||||||
@ -404,7 +367,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.
|
||||||
@ -417,7 +380,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();
|
||||||
|
Loading…
Reference in New Issue
Block a user