levelBar: Factor out bar drawing

Split drawing logic from Slider to BarLevel subclass.
This changes part of the theme css from -slider- to -barlevel-.

https://bugzilla.gnome.org/show_bug.cgi?id=790280.
This commit is contained in:
Didier Roche 2018-02-08 19:04:42 +01:00 committed by Florian Müllner
parent f433b12d6e
commit c90a4e4849
4 changed files with 152 additions and 93 deletions

View File

@ -128,12 +128,12 @@ StScrollBar {
.slider {
height: 1em;
-slider-height: 0.3em;
-slider-background-color: $insensitive_bg_color; //background of the trough
-slider-border-color: $borders_color; //trough border color
-slider-active-background-color: $selected_bg_color; //active trough fill
-slider-active-border-color: darken($selected_bg_color,10%); //active trough border
-slider-border-width: 1px;
-barlevel-height: 0.3em;
-barlevel-background-color: $insensitive_bg_color; //background of the trough
-barlevel-border-color: $borders_color; //trough border color
-barlevel-active-background-color: $selected_bg_color; //active trough fill
-barlevel-active-border-color: darken($selected_bg_color,10%); //active trough border
-barlevel-border-width: 1px;
-slider-handle-radius: 6px;
}

View File

@ -43,6 +43,7 @@
<file>ui/audioDeviceSelection.js</file>
<file>ui/backgroundMenu.js</file>
<file>ui/background.js</file>
<file>ui/barLevel.js</file>
<file>ui/boxpointer.js</file>
<file>ui/calendar.js</file>
<file>ui/checkBox.js</file>

131
js/ui/barLevel.js Normal file
View File

@ -0,0 +1,131 @@
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
const Atk = imports.gi.Atk;
const Cairo = imports.cairo;
const Clutter = imports.gi.Clutter;
const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
var BarLevel = new Lang.Class({
Name: "BarLevel",
_init(value, params) {
if (isNaN(value))
// Avoid spreading NaNs around
throw TypeError('The bar level value must be a number');
this._value = Math.max(Math.min(value, 1), 0);
this._barLevelWidth = 0;
if (params == undefined)
params = {}
this.actor = new St.DrawingArea({ styleClass: params['styleClass'] || 'barlevel',
can_focus: params['canFocus'] || false,
reactive: params['reactive'] || false,
accessible_role: params['accessibleRole'] || Atk.Role.LEVEL_BAR });
this.actor.connect('repaint', this._barLevelRepaint.bind(this));
this.actor.connect('allocation-changed', (actor, box) => {
this._barLevelWidth = box.get_width();
});
this._customAccessible = St.GenericAccessible.new_for_actor(this.actor);
this.actor.set_accessible(this._customAccessible);
this._customAccessible.connect('get-current-value', this._getCurrentValue.bind(this));
this._customAccessible.connect('get-minimum-value', this._getMinimumValue.bind(this));
this._customAccessible.connect('get-maximum-value', this._getMaximumValue.bind(this));
this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this));
this.connect('value-changed', this._valueChanged.bind(this));
},
setValue(value) {
if (isNaN(value))
throw TypeError('The bar level value must be a number');
this._value = Math.max(Math.min(value, 1), 0);
this.actor.queue_repaint();
},
_barLevelRepaint(area) {
let cr = area.get_context();
let themeNode = area.get_theme_node();
let [width, height] = area.get_surface_size();
let barLevelHeight = themeNode.get_length('-barlevel-height');
let barLevelBorderRadius = Math.min(width, barLevelHeight) / 2;
let fgColor = themeNode.get_foreground_color();
let barLevelColor = themeNode.get_color('-barlevel-background-color');
let barLevelActiveColor = themeNode.get_color('-barlevel-active-background-color');
let barLevelBorderWidth = themeNode.get_length('-barlevel-border-width');
let barLevelBorderColor = themeNode.get_color('-barlevel-border-color');
let barLevelActiveBorderColor = themeNode.get_color('-barlevel-active-border-color');
const TAU = Math.PI * 2;
let endX = barLevelBorderRadius + (width - 2 * barLevelBorderRadius) * this._value;
/* background bar */
cr.arc(width - barLevelBorderRadius - barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
cr.lineTo(endX, (height + barLevelHeight) / 2);
cr.lineTo(endX, (height - barLevelHeight) / 2);
cr.lineTo(width - barLevelBorderRadius - barLevelBorderWidth, (height - barLevelHeight) / 2);
Clutter.cairo_set_source_color(cr, barLevelColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, barLevelBorderColor);
cr.setLineWidth(barLevelBorderWidth);
cr.stroke();
/* normal progress bar */
cr.arc(barLevelBorderRadius + barLevelBorderWidth, height / 2, barLevelBorderRadius, TAU * 1 / 4, TAU * 3 / 4);
cr.lineTo(endX, (height - barLevelHeight) / 2);
cr.lineTo(endX, (height + barLevelHeight) / 2);
cr.lineTo(barLevelBorderRadius + barLevelBorderWidth, (height + barLevelHeight) / 2);
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, barLevelActiveBorderColor);
cr.setLineWidth(barLevelBorderWidth);
cr.stroke();
/* end progress bar arc */
Clutter.cairo_set_source_color(cr, barLevelActiveColor);
cr.arc(endX, height / 2, barLevelBorderRadius, TAU * 3 / 4, TAU * 1 / 4);
cr.lineTo(Math.floor(endX), (height + barLevelHeight) / 2);
cr.lineTo(Math.floor(endX), (height - barLevelHeight) / 2);
cr.lineTo(endX, (height - barLevelHeight) / 2);
cr.fillPreserve();
cr.setLineWidth(barLevelBorderWidth);
cr.stroke();
cr.$dispose();
},
_getCurrentValue(actor) {
return this._value;
},
_getMinimumValue(actor) {
return 0;
},
_getMaximumValue(actor) {
return 1;
},
_setCurrentValue(actor, value) {
this._value = value;
},
_valueChanged(barLevel, value, property) {
this._customAccessible.notify("accessible-value");
},
get value() {
return this._value;
}
});
Signals.addSignalMethods(BarLevel.prototype);

View File

@ -7,55 +7,38 @@ const Lang = imports.lang;
const St = imports.gi.St;
const Signals = imports.signals;
const BarLevel = imports.ui.barLevel;
var SLIDER_SCROLL_STEP = 0.02; /* Slider scrolling step in % */
var Slider = new Lang.Class({
Name: "Slider",
Extends: BarLevel.BarLevel,
_init(value) {
if (isNaN(value))
// Avoid spreading NaNs around
throw TypeError('The slider value must be a number');
this._value = Math.max(Math.min(value, 1), 0);
this._sliderWidth = 0;
let params = {
styleClass: 'slider',
canFocus: true,
reactive: true,
accessibleRole: Atk.Role.SLIDER,
}
this.parent(value, params)
this.actor = new St.DrawingArea({ style_class: 'slider',
can_focus: true,
reactive: true,
accessible_role: Atk.Role.SLIDER });
this.actor.connect('repaint', this._sliderRepaint.bind(this));
this.actor.connect('button-press-event', this._startDragging.bind(this));
this.actor.connect('touch-event', this._touchDragging.bind(this));
this.actor.connect('scroll-event', this._onScrollEvent.bind(this));
this.actor.connect('key-press-event', this.onKeyPressEvent.bind(this));
this.actor.connect('allocation-changed', (actor, box) => {
this._sliderWidth = box.get_width();
});
this._releaseId = this._motionId = 0;
this._dragging = false;
this._customAccessible = St.GenericAccessible.new_for_actor(this.actor);
this.actor.set_accessible(this._customAccessible);
this._customAccessible.connect('get-current-value', this._getCurrentValue.bind(this));
this._customAccessible.connect('get-minimum-value', this._getMinimumValue.bind(this));
this._customAccessible.connect('get-maximum-value', this._getMaximumValue.bind(this));
this._customAccessible.connect('get-minimum-increment', this._getMinimumIncrement.bind(this));
this._customAccessible.connect('set-current-value', this._setCurrentValue.bind(this));
this.connect('value-changed', this._valueChanged.bind(this));
},
setValue(value) {
if (isNaN(value))
throw TypeError('The slider value must be a number');
_barLevelRepaint(area) {
this.parent(area);
this._value = Math.max(Math.min(value, 1), 0);
this.actor.queue_repaint();
},
_sliderRepaint(area) {
// Add handle
let cr = area.get_context();
let themeNode = area.get_theme_node();
let [width, height] = area.get_surface_size();
@ -66,41 +49,9 @@ var Slider = new Lang.Class({
let [hasHandleColor, handleBorderColor] =
themeNode.lookup_color('-slider-handle-border-color', false);
let sliderHeight = themeNode.get_length('-slider-height');
let sliderBorderWidth = themeNode.get_length('-slider-border-width');
let sliderBorderRadius = Math.min(width, sliderHeight) / 2;
let sliderBorderColor = themeNode.get_color('-slider-border-color');
let sliderColor = themeNode.get_color('-slider-background-color');
let sliderActiveBorderColor = themeNode.get_color('-slider-active-border-color');
let sliderActiveColor = themeNode.get_color('-slider-active-background-color');
const TAU = Math.PI * 2;
let handleX = handleRadius + (width - 2 * handleRadius) * this._value;
cr.arc(sliderBorderRadius + sliderBorderWidth, height / 2, sliderBorderRadius, TAU * 1/4, TAU * 3/4);
cr.lineTo(handleX, (height - sliderHeight) / 2);
cr.lineTo(handleX, (height + sliderHeight) / 2);
cr.lineTo(sliderBorderRadius + sliderBorderWidth, (height + sliderHeight) / 2);
Clutter.cairo_set_source_color(cr, sliderActiveColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, sliderActiveBorderColor);
cr.setLineWidth(sliderBorderWidth);
cr.stroke();
cr.arc(width - sliderBorderRadius - sliderBorderWidth, height / 2, sliderBorderRadius, TAU * 3/4, TAU * 1/4);
cr.lineTo(handleX, (height + sliderHeight) / 2);
cr.lineTo(handleX, (height - sliderHeight) / 2);
cr.lineTo(width - sliderBorderRadius - sliderBorderWidth, (height - sliderHeight) / 2);
Clutter.cairo_set_source_color(cr, sliderColor);
cr.fillPreserve();
Clutter.cairo_set_source_color(cr, sliderBorderColor);
cr.setLineWidth(sliderBorderWidth);
cr.stroke();
let handleY = height / 2;
let color = themeNode.get_foreground_color();
@ -246,7 +197,7 @@ var Slider = new Lang.Class({
relX = absX - sliderX;
relY = absY - sliderY;
let width = this._sliderWidth;
let width = this._barLevelWidth;
let handleRadius = this.actor.get_theme_node().get_length('-slider-handle-radius');
let newvalue;
@ -261,33 +212,9 @@ var Slider = new Lang.Class({
this.emit('value-changed', this._value);
},
_getCurrentValue(actor) {
return this._value;
},
_getMinimumValue(actor) {
return 0;
},
_getMaximumValue(actor) {
return 1;
},
_getMinimumIncrement(actor) {
return 0.1;
},
_setCurrentValue(actor, value) {
this._value = value;
},
_valueChanged(slider, value, property) {
this._customAccessible.notify ("accessible-value");
},
get value() {
return this._value;
}
});
Signals.addSignalMethods(Slider.prototype);