Add a checkbox widget

gnome-keyring dialogs need checkboxes, and while it is possible to
get pretty close using CSS tricks, a dedicated widgets yields better
results.

https://bugzilla.gnome.org/show_bug.cgi?id=669811
This commit is contained in:
Florian Müllner 2012-02-14 00:13:57 +01:00
parent ed465a6ffe
commit e2726f3e38
5 changed files with 185 additions and 0 deletions

View File

@ -22,6 +22,7 @@ dist_theme_DATA = \
theme/calendar-arrow-left.svg \
theme/calendar-arrow-right.svg \
theme/calendar-today.svg \
theme/check-box.svg \
theme/close-window.svg \
theme/close.svg \
theme/corner-ripple-ltr.png \

67
data/theme/check-box.svg Normal file
View File

@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:cc="http://creativecommons.org/ns#"
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:svg="http://www.w3.org/2000/svg"
xmlns="http://www.w3.org/2000/svg"
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
width="16"
height="16"
id="svg2"
version="1.1"
inkscape:version="0.48.2 r9819"
sodipodi:docname="check-box.svg">
<defs
id="defs4" />
<sodipodi:namedview
id="base"
pagecolor="#ffffff"
bordercolor="#666666"
borderopacity="1.0"
inkscape:pageopacity="0.0"
inkscape:pageshadow="2"
inkscape:zoom="22.4"
inkscape:cx="1.1673316"
inkscape:cy="8.9737722"
inkscape:document-units="px"
inkscape:current-layer="layer1"
showgrid="false"
inkscape:window-width="1440"
inkscape:window-height="842"
inkscape:window-x="0"
inkscape:window-y="26"
inkscape:window-maximized="1" />
<metadata
id="metadata7">
<rdf:RDF>
<cc:Work
rdf:about="">
<dc:format>image/svg+xml</dc:format>
<dc:type
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
<dc:title />
</cc:Work>
</rdf:RDF>
</metadata>
<g
inkscape:label="Layer 1"
inkscape:groupmode="layer"
id="layer1"
transform="translate(0,-1036.3622)">
<g
style="font-size:24px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#ffffff;fill-opacity:1;stroke:none;font-family:Sans"
id="text3753"
transform="matrix(0.68078575,0,0,0.68078575,2.5537141,333.3753)">
<path
d="m 14.117188,1037.7997 -4.7460942,6.3867 4.9921872,6.7383 -2.542968,0 L 8,1045.7684 l -3.8203125,5.1563 -2.5429688,0 5.0976563,-6.8672 -4.6640625,-6.2578 2.5429687,0 3.4804688,4.6758 3.480469,-4.6758 2.542969,0"
style="fill:#ffffff;fill-opacity:1"
id="path3758"
inkscape:connector-curvature="0"
sodipodi:nodetypes="ccccccccccccc" />
</g>
</g>
</svg>

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

@ -90,6 +90,25 @@ StTooltip StLabel {
text-align: center;
}
.check-box ShellGenericContainer {
spacing: .8em;
}
.check-box StBin {
width: 1.2em;
height: 1.2em;
border: 1px solid white;
border-radius: 4px;
}
.check-box:checked StBin {
background-image: url("check-box.svg");
}
.check-box:focus StBin {
border: 1px solid #3465a4;
}
/* PopupMenu */
.popup-menu-boxpointer {

View File

@ -43,6 +43,7 @@ nobase_dist_js_DATA = \
ui/autorunManager.js \
ui/boxpointer.js \
ui/calendar.js \
ui/checkBox.js \
ui/contactDisplay.js \
ui/ctrlAltTab.js \
ui/dash.js \

97
js/ui/checkBox.js Normal file
View File

@ -0,0 +1,97 @@
const Clutter = imports.gi.Clutter;
const Pango = imports.gi.Pango;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
const Lang = imports.lang;
const CheckBoxContainer = new Lang.Class({
Name: 'CheckBoxContainer',
_init: function() {
this.actor = new Shell.GenericContainer();
this.actor.connect('get-preferred-width',
Lang.bind(this, this._getPreferredWidth));
this.actor.connect('get-preferred-height',
Lang.bind(this, this._getPreferredHeight));
this.actor.connect('allocate',
Lang.bind(this, this._allocate));
this.actor.connect('style-changed', Lang.bind(this,
function() {
let node = this.actor.get_theme_node();
this._spacing = node.get_length('spacing');
}));
this.actor.request_mode = Clutter.RequestMode.HEIGHT_FOR_WIDTH;
this._box = new St.Bin();
this.actor.add_actor(this._box);
this.label = new St.Label();
this.label.clutter_text.set_line_wrap(true);
this.label.clutter_text.set_ellipsize(Pango.EllipsizeMode.NONE);
this.actor.add_actor(this.label);
this._spacing = 0;
},
_getPreferredWidth: function(actor, forHeight, alloc) {
let [minWidth, natWidth] = this._box.get_preferred_width(forHeight);
alloc.min_size = minWidth + this._spacing;
alloc.natural_size = natWidth + this._spacing;
},
_getPreferredHeight: function(actor, forWidth, alloc) {
let [minBoxHeight, natBoxHeight] =
this._box.get_preferred_height(forWidth);
let [minLabelHeight, natLabelHeight] =
this.label.get_preferred_height(forWidth);
alloc.min_size = Math.max(minBoxHeight, minLabelHeight);
alloc.natural_size = Math.max(natBoxHeight, natLabelHeight);
},
_allocate: function(actor, box, flags) {
let availWidth = box.x2 - box.x1;
let availHeight = box.y2 - box.y1;
let childBox = new Clutter.ActorBox();
let [minBoxWidth, natBoxWidth] =
this._box.get_preferred_width(-1);
let [minBoxHeight, natBoxHeight] =
this._box.get_preferred_height(-1);
childBox.x1 = box.x1;
childBox.x2 = box.x1 + natBoxWidth;
childBox.y1 = box.y1;
childBox.y2 = box.y1 + natBoxHeight;
this._box.allocate(childBox, flags);
childBox.x1 = box.x1 + natBoxWidth + this._spacing;
childBox.x2 = availWidth - childBox.x1;
childBox.y1 = box.y1;
childBox.y2 = box.y2;
this.label.allocate(childBox, flags);
}
});
const CheckBox = new Lang.Class({
Name: 'CheckBox',
_init: function(label) {
this.actor = new St.Button({ style_class: 'check-box',
button_mask: St.ButtonMask.ONE,
toggle_mode: true,
can_focus: true,
x_fill: true,
y_fill: true });
this._container = new CheckBoxContainer();
this.actor.set_child(this._container.actor);
if (label)
this.setLabel(label);
},
setLabel: function(label) {
this._container.label.set_text(label);
}
});