Blame js/ui/slider.js

Packit Service ed5168
/* -*- mode: js2; js2-basic-offset: 4; indent-tabs-mode: nil -*- */
Packit Service ed5168
Packit Service ed5168
const { Atk, Clutter } = imports.gi;
Packit Service ed5168
const Signals = imports.signals;
Packit Service ed5168
Packit Service ed5168
const BarLevel = imports.ui.barLevel;
Packit Service ed5168
Packit Service ed5168
var SLIDER_SCROLL_STEP = 0.02; /* Slider scrolling step in % */
Packit Service ed5168
Packit Service ed5168
var Slider = class extends BarLevel.BarLevel {
Packit Service ed5168
    constructor(value) {
Packit Service ed5168
        let params = {
Packit Service ed5168
            styleClass: 'slider',
Packit Service ed5168
            canFocus: true,
Packit Service ed5168
            reactive: true,
Packit Service ed5168
            accessibleRole: Atk.Role.SLIDER,
Packit Service ed5168
        }
Packit Service ed5168
        super(value, params)
Packit Service ed5168
Packit Service ed5168
        this.actor.connect('button-press-event', this._startDragging.bind(this));
Packit Service ed5168
        this.actor.connect('touch-event', this._touchDragging.bind(this));
Packit Service ed5168
        this.actor.connect('scroll-event', this._onScrollEvent.bind(this));
Packit Service ed5168
        this.actor.connect('key-press-event', this.onKeyPressEvent.bind(this));
Packit Service ed5168
Packit Service ed5168
        this._releaseId = this._motionId = 0;
Packit Service ed5168
        this._dragging = false;
Packit Service ed5168
Packit Service ed5168
        this._customAccessible.connect('get-minimum-increment', this._getMinimumIncrement.bind(this));
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _barLevelRepaint(area) {
Packit Service ed5168
        super._barLevelRepaint(area);
Packit Service ed5168
Packit Service ed5168
        // Add handle
Packit Service ed5168
        let cr = area.get_context();
Packit Service ed5168
        let themeNode = area.get_theme_node();
Packit Service ed5168
        let [width, height] = area.get_surface_size();
Packit Service ed5168
Packit Service ed5168
        let handleRadius = themeNode.get_length('-slider-handle-radius');
Packit Service ed5168
Packit Service ed5168
        let handleBorderWidth = themeNode.get_length('-slider-handle-border-width');
Packit Service ed5168
        let [hasHandleColor, handleBorderColor] =
Packit Service ed5168
            themeNode.lookup_color('-slider-handle-border-color', false);
Packit Service ed5168
Packit Service ed5168
        const TAU = Math.PI * 2;
Packit Service ed5168
Packit Service ed5168
        let handleX = handleRadius + (width - 2 * handleRadius) * this._value / this._maxValue;
Packit Service ed5168
        let handleY = height / 2;
Packit Service ed5168
Packit Service ed5168
        let color = themeNode.get_foreground_color();
Packit Service ed5168
        Clutter.cairo_set_source_color(cr, color);
Packit Service ed5168
        cr.arc(handleX, handleY, handleRadius, 0, 2 * Math.PI);
Packit Service ed5168
        cr.fillPreserve();
Packit Service ed5168
        if (hasHandleColor && handleBorderWidth) {
Packit Service ed5168
            Clutter.cairo_set_source_color(cr, handleBorderColor);
Packit Service ed5168
            cr.setLineWidth(handleBorderWidth);
Packit Service ed5168
            cr.stroke();
Packit Service ed5168
        }
Packit Service ed5168
        cr.$dispose();
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _startDragging(actor, event) {
Packit Service ed5168
        return this.startDragging(event);
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    startDragging(event) {
Packit Service ed5168
        if (this._dragging)
Packit Service ed5168
            return Clutter.EVENT_PROPAGATE;
Packit Service ed5168
Packit Service ed5168
        this._dragging = true;
Packit Service ed5168
Packit Service ed5168
        let device = event.get_device();
Packit Service ed5168
        let sequence = event.get_event_sequence();
Packit Service ed5168
Packit Service ed5168
        if (sequence != null)
Packit Service ed5168
            device.sequence_grab(sequence, this.actor);
Packit Service ed5168
        else
Packit Service ed5168
            device.grab(this.actor);
Packit Service ed5168
Packit Service ed5168
        this._grabbedDevice = device;
Packit Service ed5168
        this._grabbedSequence = sequence;
Packit Service ed5168
Packit Service ed5168
        if (sequence == null) {
Packit Service ed5168
            this._releaseId = this.actor.connect('button-release-event', this._endDragging.bind(this));
Packit Service ed5168
            this._motionId = this.actor.connect('motion-event', this._motionEvent.bind(this));
Packit Service ed5168
        }
Packit Service ed5168
Packit Service ed5168
        // We need to emit 'drag-begin' before moving the handle to make
Packit Service ed5168
        // sure that no 'value-changed' signal is emitted before this one.
Packit Service ed5168
        this.emit('drag-begin');
Packit Service ed5168
Packit Service ed5168
        let absX, absY;
Packit Service ed5168
        [absX, absY] = event.get_coords();
Packit Service ed5168
        this._moveHandle(absX, absY);
Packit Service ed5168
        return Clutter.EVENT_STOP;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _endDragging() {
Packit Service ed5168
        if (this._dragging) {
Packit Service ed5168
            if (this._releaseId)
Packit Service ed5168
                this.actor.disconnect(this._releaseId);
Packit Service ed5168
            if (this._motionId)
Packit Service ed5168
                this.actor.disconnect(this._motionId);
Packit Service ed5168
Packit Service ed5168
            if (this._grabbedSequence != null)
Packit Service ed5168
                this._grabbedDevice.sequence_ungrab(this._grabbedSequence);
Packit Service ed5168
            else
Packit Service ed5168
                this._grabbedDevice.ungrab();
Packit Service ed5168
Packit Service ed5168
            this._grabbedSequence = null;
Packit Service ed5168
            this._grabbedDevice = null;
Packit Service ed5168
            this._dragging = false;
Packit Service ed5168
Packit Service ed5168
            this.emit('drag-end');
Packit Service ed5168
        }
Packit Service ed5168
        return Clutter.EVENT_STOP;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _touchDragging(actor, event) {
Packit Service ed5168
        let device = event.get_device();
Packit Service ed5168
        let sequence = event.get_event_sequence();
Packit Service ed5168
Packit Service ed5168
        if (!this._dragging &&
Packit Service ed5168
            event.type() == Clutter.EventType.TOUCH_BEGIN) {
Packit Service ed5168
            this.startDragging(event);
Packit Service ed5168
            return Clutter.EVENT_STOP;
Packit Service ed5168
        } else if (device.sequence_get_grabbed_actor(sequence) == actor) {
Packit Service ed5168
            if (event.type() == Clutter.EventType.TOUCH_UPDATE)
Packit Service ed5168
                return this._motionEvent(actor, event);
Packit Service ed5168
            else if (event.type() == Clutter.EventType.TOUCH_END)
Packit Service ed5168
                return this._endDragging();
Packit Service ed5168
        }
Packit Service ed5168
Packit Service ed5168
        return Clutter.EVENT_PROPAGATE;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    scroll(event) {
Packit Service ed5168
        let direction = event.get_scroll_direction();
Packit Service ed5168
        let delta;
Packit Service ed5168
Packit Service ed5168
        if (event.is_pointer_emulated())
Packit Service ed5168
            return Clutter.EVENT_PROPAGATE;
Packit Service ed5168
Packit Service ed5168
        if (direction == Clutter.ScrollDirection.DOWN) {
Packit Service ed5168
            delta = -SLIDER_SCROLL_STEP;
Packit Service ed5168
        } else if (direction == Clutter.ScrollDirection.UP) {
Packit Service ed5168
            delta = +SLIDER_SCROLL_STEP;
Packit Service ed5168
        } else if (direction == Clutter.ScrollDirection.SMOOTH) {
Packit Service ed5168
            let [dx, dy] = event.get_scroll_delta();
Packit Service ed5168
            // Even though the slider is horizontal, use dy to match
Packit Service ed5168
            // the UP/DOWN above.
Packit Service ed5168
            delta = -dy * SLIDER_SCROLL_STEP;
Packit Service ed5168
        }
Packit Service ed5168
Packit Service ed5168
        this._value = Math.min(Math.max(0, this._value + delta), this._maxValue);
Packit Service ed5168
Packit Service ed5168
        this.actor.queue_repaint();
Packit Service ed5168
        this.emit('value-changed', this._value);
Packit Service ed5168
        return Clutter.EVENT_STOP;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _onScrollEvent(actor, event) {
Packit Service ed5168
        return this.scroll(event);
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _motionEvent(actor, event) {
Packit Service ed5168
        let absX, absY;
Packit Service ed5168
        [absX, absY] = event.get_coords();
Packit Service ed5168
        this._moveHandle(absX, absY);
Packit Service ed5168
        return Clutter.EVENT_STOP;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    onKeyPressEvent(actor, event) {
Packit Service ed5168
        let key = event.get_key_symbol();
Packit Service ed5168
        if (key == Clutter.KEY_Right || key == Clutter.KEY_Left) {
Packit Service ed5168
            let delta = key == Clutter.KEY_Right ? 0.1 : -0.1;
Packit Service ed5168
            this._value = Math.max(0, Math.min(this._value + delta, this._maxValue));
Packit Service ed5168
            this.actor.queue_repaint();
Packit Service ed5168
            this.emit('drag-begin');
Packit Service ed5168
            this.emit('value-changed', this._value);
Packit Service ed5168
            this.emit('drag-end');
Packit Service ed5168
            return Clutter.EVENT_STOP;
Packit Service ed5168
        }
Packit Service ed5168
        return Clutter.EVENT_PROPAGATE;
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _moveHandle(absX, absY) {
Packit Service ed5168
        let relX, relY, sliderX, sliderY;
Packit Service ed5168
        [sliderX, sliderY] = this.actor.get_transformed_position();
Packit Service ed5168
        relX = absX - sliderX;
Packit Service ed5168
        relY = absY - sliderY;
Packit Service ed5168
Packit Service ed5168
        let width = this._barLevelWidth;
Packit Service ed5168
        let handleRadius = this.actor.get_theme_node().get_length('-slider-handle-radius');
Packit Service ed5168
Packit Service ed5168
        let newvalue;
Packit Service ed5168
        if (relX < handleRadius)
Packit Service ed5168
            newvalue = 0;
Packit Service ed5168
        else if (relX > width - handleRadius)
Packit Service ed5168
            newvalue = 1;
Packit Service ed5168
        else
Packit Service ed5168
            newvalue = (relX - handleRadius) / (width - 2 * handleRadius);
Packit Service ed5168
        this._value = newvalue * this._maxValue;
Packit Service ed5168
        this.actor.queue_repaint();
Packit Service ed5168
        this.emit('value-changed', this._value);
Packit Service ed5168
    }
Packit Service ed5168
Packit Service ed5168
    _getMinimumIncrement(actor) {
Packit Service ed5168
        return 0.1;
Packit Service ed5168
    }
Packit Service ed5168
};
Packit Service ed5168
Signals.addSignalMethods(Slider.prototype);