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:
parent
f433b12d6e
commit
c90a4e4849
@ -128,12 +128,12 @@ StScrollBar {
|
|||||||
|
|
||||||
.slider {
|
.slider {
|
||||||
height: 1em;
|
height: 1em;
|
||||||
-slider-height: 0.3em;
|
-barlevel-height: 0.3em;
|
||||||
-slider-background-color: $insensitive_bg_color; //background of the trough
|
-barlevel-background-color: $insensitive_bg_color; //background of the trough
|
||||||
-slider-border-color: $borders_color; //trough border color
|
-barlevel-border-color: $borders_color; //trough border color
|
||||||
-slider-active-background-color: $selected_bg_color; //active trough fill
|
-barlevel-active-background-color: $selected_bg_color; //active trough fill
|
||||||
-slider-active-border-color: darken($selected_bg_color,10%); //active trough border
|
-barlevel-active-border-color: darken($selected_bg_color,10%); //active trough border
|
||||||
-slider-border-width: 1px;
|
-barlevel-border-width: 1px;
|
||||||
-slider-handle-radius: 6px;
|
-slider-handle-radius: 6px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,6 +43,7 @@
|
|||||||
<file>ui/audioDeviceSelection.js</file>
|
<file>ui/audioDeviceSelection.js</file>
|
||||||
<file>ui/backgroundMenu.js</file>
|
<file>ui/backgroundMenu.js</file>
|
||||||
<file>ui/background.js</file>
|
<file>ui/background.js</file>
|
||||||
|
<file>ui/barLevel.js</file>
|
||||||
<file>ui/boxpointer.js</file>
|
<file>ui/boxpointer.js</file>
|
||||||
<file>ui/calendar.js</file>
|
<file>ui/calendar.js</file>
|
||||||
<file>ui/checkBox.js</file>
|
<file>ui/checkBox.js</file>
|
||||||
|
131
js/ui/barLevel.js
Normal file
131
js/ui/barLevel.js
Normal 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);
|
101
js/ui/slider.js
101
js/ui/slider.js
@ -7,55 +7,38 @@ const Lang = imports.lang;
|
|||||||
const St = imports.gi.St;
|
const St = imports.gi.St;
|
||||||
const Signals = imports.signals;
|
const Signals = imports.signals;
|
||||||
|
|
||||||
|
const BarLevel = imports.ui.barLevel;
|
||||||
|
|
||||||
var SLIDER_SCROLL_STEP = 0.02; /* Slider scrolling step in % */
|
var SLIDER_SCROLL_STEP = 0.02; /* Slider scrolling step in % */
|
||||||
|
|
||||||
var Slider = new Lang.Class({
|
var Slider = new Lang.Class({
|
||||||
Name: "Slider",
|
Name: "Slider",
|
||||||
|
Extends: BarLevel.BarLevel,
|
||||||
|
|
||||||
_init(value) {
|
_init(value) {
|
||||||
if (isNaN(value))
|
let params = {
|
||||||
// Avoid spreading NaNs around
|
styleClass: 'slider',
|
||||||
throw TypeError('The slider value must be a number');
|
canFocus: true,
|
||||||
this._value = Math.max(Math.min(value, 1), 0);
|
reactive: true,
|
||||||
this._sliderWidth = 0;
|
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('button-press-event', this._startDragging.bind(this));
|
||||||
this.actor.connect('touch-event', this._touchDragging.bind(this));
|
this.actor.connect('touch-event', this._touchDragging.bind(this));
|
||||||
this.actor.connect('scroll-event', this._onScrollEvent.bind(this));
|
this.actor.connect('scroll-event', this._onScrollEvent.bind(this));
|
||||||
this.actor.connect('key-press-event', this.onKeyPressEvent.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._releaseId = this._motionId = 0;
|
||||||
this._dragging = false;
|
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('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) {
|
_barLevelRepaint(area) {
|
||||||
if (isNaN(value))
|
this.parent(area);
|
||||||
throw TypeError('The slider value must be a number');
|
|
||||||
|
|
||||||
this._value = Math.max(Math.min(value, 1), 0);
|
// Add handle
|
||||||
this.actor.queue_repaint();
|
|
||||||
},
|
|
||||||
|
|
||||||
_sliderRepaint(area) {
|
|
||||||
let cr = area.get_context();
|
let cr = area.get_context();
|
||||||
let themeNode = area.get_theme_node();
|
let themeNode = area.get_theme_node();
|
||||||
let [width, height] = area.get_surface_size();
|
let [width, height] = area.get_surface_size();
|
||||||
@ -66,41 +49,9 @@ var Slider = new Lang.Class({
|
|||||||
let [hasHandleColor, handleBorderColor] =
|
let [hasHandleColor, handleBorderColor] =
|
||||||
themeNode.lookup_color('-slider-handle-border-color', false);
|
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;
|
const TAU = Math.PI * 2;
|
||||||
|
|
||||||
let handleX = handleRadius + (width - 2 * handleRadius) * this._value;
|
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 handleY = height / 2;
|
||||||
|
|
||||||
let color = themeNode.get_foreground_color();
|
let color = themeNode.get_foreground_color();
|
||||||
@ -246,7 +197,7 @@ var Slider = new Lang.Class({
|
|||||||
relX = absX - sliderX;
|
relX = absX - sliderX;
|
||||||
relY = absY - sliderY;
|
relY = absY - sliderY;
|
||||||
|
|
||||||
let width = this._sliderWidth;
|
let width = this._barLevelWidth;
|
||||||
let handleRadius = this.actor.get_theme_node().get_length('-slider-handle-radius');
|
let handleRadius = this.actor.get_theme_node().get_length('-slider-handle-radius');
|
||||||
|
|
||||||
let newvalue;
|
let newvalue;
|
||||||
@ -261,33 +212,9 @@ var Slider = new Lang.Class({
|
|||||||
this.emit('value-changed', this._value);
|
this.emit('value-changed', this._value);
|
||||||
},
|
},
|
||||||
|
|
||||||
_getCurrentValue(actor) {
|
|
||||||
return this._value;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getMinimumValue(actor) {
|
|
||||||
return 0;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getMaximumValue(actor) {
|
|
||||||
return 1;
|
|
||||||
},
|
|
||||||
|
|
||||||
_getMinimumIncrement(actor) {
|
_getMinimumIncrement(actor) {
|
||||||
return 0.1;
|
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);
|
Signals.addSignalMethods(Slider.prototype);
|
||||||
|
Loading…
Reference in New Issue
Block a user