From c90a4e48493072f02b87c2538b395b1549353b34 Mon Sep 17 00:00:00 2001 From: Didier Roche Date: Thu, 8 Feb 2018 19:04:42 +0100 Subject: [PATCH] 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. --- data/theme/gnome-shell-sass/_common.scss | 12 +-- js/js-resources.gresource.xml | 1 + js/ui/barLevel.js | 131 +++++++++++++++++++++++ js/ui/slider.js | 101 +++-------------- 4 files changed, 152 insertions(+), 93 deletions(-) create mode 100644 js/ui/barLevel.js diff --git a/data/theme/gnome-shell-sass/_common.scss b/data/theme/gnome-shell-sass/_common.scss index 594badc63..de107d7b7 100644 --- a/data/theme/gnome-shell-sass/_common.scss +++ b/data/theme/gnome-shell-sass/_common.scss @@ -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; } diff --git a/js/js-resources.gresource.xml b/js/js-resources.gresource.xml index cc1da4461..3c0feab60 100644 --- a/js/js-resources.gresource.xml +++ b/js/js-resources.gresource.xml @@ -43,6 +43,7 @@ ui/audioDeviceSelection.js ui/backgroundMenu.js ui/background.js + ui/barLevel.js ui/boxpointer.js ui/calendar.js ui/checkBox.js diff --git a/js/ui/barLevel.js b/js/ui/barLevel.js new file mode 100644 index 000000000..c018ef31b --- /dev/null +++ b/js/ui/barLevel.js @@ -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); diff --git a/js/ui/slider.js b/js/ui/slider.js index 9853929eb..c1e2ea6a6 100644 --- a/js/ui/slider.js +++ b/js/ui/slider.js @@ -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);