Skip to content

Commit

Permalink
PointerLocator: inline namespace (#2244)
Browse files Browse the repository at this point in the history
  • Loading branch information
lenemter authored Jan 25, 2025
1 parent 74716d5 commit 42443b2
Showing 1 changed file with 123 additions and 137 deletions.
260 changes: 123 additions & 137 deletions src/Widgets/PointerLocator.vala
Original file line number Diff line number Diff line change
@@ -1,165 +1,151 @@
//
// Copyright 2020 elementary, Inc. (https://elementary.io)
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//

namespace Gala {
public class PointerLocator : Clutter.Actor, Clutter.Animatable {
private const int WIDTH_PX = 300;
private const int HEIGHT_PX = 300;
private const int ANIMATION_TIME_MS = 300;

private const int BORDER_WIDTH_PX = 1;

private const double BACKGROUND_OPACITY = 0.7;

public Meta.Display display { get; construct; }

private float scaling_factor = 1.0f;
private int surface_width = WIDTH_PX;
private int surface_height = HEIGHT_PX;

private GLib.Settings settings;
private Cogl.Pipeline pipeline;
private Cairo.ImageSurface surface;
private Cairo.Pattern stroke_color;
private Cairo.Pattern fill_color;

public PointerLocator (Meta.Display display) {
Object (display: display);
}
/*
* SPDX-License-Identifier: GPL-3.0-or-later
* SPDX-FileCopyrightText: 2020-2025 elementary, Inc. (https://elementary.io)
*/

public class Gala.PointerLocator : Clutter.Actor, Clutter.Animatable {
private const int WIDTH_PX = 300;
private const int HEIGHT_PX = 300;
private const int ANIMATION_TIME_MS = 300;

private const int BORDER_WIDTH_PX = 1;

private const double BACKGROUND_OPACITY = 0.7;

construct {
visible = false;
reactive = false;
public Meta.Display display { get; construct; }

private float scaling_factor = 1.0f;
private int surface_width = WIDTH_PX;
private int surface_height = HEIGHT_PX;

private GLib.Settings settings;
private Cogl.Pipeline pipeline;
private Cairo.ImageSurface surface;
private Cairo.Pattern stroke_color;
private Cairo.Pattern fill_color;

public PointerLocator (Meta.Display display) {
Object (display: display);
}

settings = new GLib.Settings ("org.gnome.desktop.interface");
construct {
visible = false;
reactive = false;

settings = new GLib.Settings ("org.gnome.desktop.interface");

#if HAS_MUTTER47
unowned var ctx = context.get_backend ().get_cogl_context ();
unowned var ctx = context.get_backend ().get_cogl_context ();
#else
unowned var ctx = Clutter.get_default_backend ().get_cogl_context ();
unowned var ctx = Clutter.get_default_backend ().get_cogl_context ();
#endif
pipeline = new Cogl.Pipeline (ctx);
pipeline = new Cogl.Pipeline (ctx);

var pivot = Graphene.Point ();
pivot.init (0.5f, 0.5f);
pivot_point = pivot;
}
var pivot = Graphene.Point ();
pivot.init (0.5f, 0.5f);
pivot_point = pivot;
}

private void update_surface (float cur_scale) {
if (surface == null || cur_scale != scaling_factor) {
scaling_factor = cur_scale;
surface_width = InternalUtils.scale_to_int (WIDTH_PX, scaling_factor);
surface_height = InternalUtils.scale_to_int (HEIGHT_PX, scaling_factor);
private void update_surface (float cur_scale) {
if (surface == null || cur_scale != scaling_factor) {
scaling_factor = cur_scale;
surface_width = InternalUtils.scale_to_int (WIDTH_PX, scaling_factor);
surface_height = InternalUtils.scale_to_int (HEIGHT_PX, scaling_factor);

surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, surface_width, surface_height);
surface = new Cairo.ImageSurface (Cairo.Format.ARGB32, surface_width, surface_height);

set_size (surface_width, surface_height);
}
set_size (surface_width, surface_height);
}
}

public override void paint (Clutter.PaintContext context) {
var radius = int.min (surface_width / 2, surface_height / 2);
public override void paint (Clutter.PaintContext context) {
var radius = int.min (surface_width / 2, surface_height / 2);

var cr = new Cairo.Context (surface);
var border_width = InternalUtils.scale_to_int (BORDER_WIDTH_PX, scaling_factor);
var cr = new Cairo.Context (surface);
var border_width = InternalUtils.scale_to_int (BORDER_WIDTH_PX, scaling_factor);

// Clear the surface
cr.save ();
cr.set_source_rgba (0, 0, 0, 0);
cr.set_operator (Cairo.Operator.SOURCE);
cr.paint ();
cr.restore ();
// Clear the surface
cr.save ();
cr.set_source_rgba (0, 0, 0, 0);
cr.set_operator (Cairo.Operator.SOURCE);
cr.paint ();
cr.restore ();

cr.set_line_cap (Cairo.LineCap.ROUND);
cr.set_line_join (Cairo.LineJoin.ROUND);
cr.translate (surface_width / 2, surface_height / 2);
cr.set_line_cap (Cairo.LineCap.ROUND);
cr.set_line_join (Cairo.LineJoin.ROUND);
cr.translate (surface_width / 2, surface_height / 2);

cr.move_to (radius - BORDER_WIDTH_PX, 0);
cr.arc (0, 0, radius - border_width, 0, 2 * Math.PI);
cr.close_path ();
cr.move_to (radius - BORDER_WIDTH_PX, 0);
cr.arc (0, 0, radius - border_width, 0, 2 * Math.PI);
cr.close_path ();

cr.set_line_width (0);
cr.set_source (fill_color);
cr.fill_preserve ();
cr.set_line_width (0);
cr.set_source (fill_color);
cr.fill_preserve ();

cr.set_line_width (border_width);
cr.set_source (stroke_color);
cr.stroke ();
cr.set_line_width (border_width);
cr.set_source (stroke_color);
cr.stroke ();

var cogl_context = context.get_framebuffer ().get_context ();
var cogl_context = context.get_framebuffer ().get_context ();

try {
var texture = new Cogl.Texture2D.from_data (cogl_context, surface_width, surface_height,
Cogl.PixelFormat.BGRA_8888_PRE, surface.get_stride (), surface.get_data ());
try {
var texture = new Cogl.Texture2D.from_data (cogl_context, surface_width, surface_height,
Cogl.PixelFormat.BGRA_8888_PRE, surface.get_stride (), surface.get_data ());

pipeline.set_layer_texture (0, texture);
pipeline.set_layer_texture (0, texture);

context.get_framebuffer ().draw_rectangle (pipeline, 0, 0, surface_width, surface_height);
} catch (Error e) {}
context.get_framebuffer ().draw_rectangle (pipeline, 0, 0, surface_width, surface_height);
} catch (Error e) {}

base.paint (context);
base.paint (context);
}

public void show_ripple () {
if (!settings.get_boolean ("locate-pointer")) {
return;
}

public void show_ripple () {
if (!settings.get_boolean ("locate-pointer")) {
return;
}

unowned var old_transition = get_transition ("circle");
if (old_transition != null) {
old_transition.stop ();
}

var transition = new Clutter.TransitionGroup ();
transition.remove_on_complete = true;
var transition_x = new Clutter.PropertyTransition ("scale-x");
var transition_y = new Clutter.PropertyTransition ("scale-y");
var start_val = Value (typeof (double));
start_val.set_double (1);
var stop_val = Value (typeof (double));
stop_val.set_double (0);
transition_x.set_from_value (start_val);
transition_y.set_from_value (start_val);
transition_x.set_to_value (stop_val);
transition_y.set_to_value (stop_val);
transition.progress_mode = Clutter.AnimationMode.EASE_OUT_QUAD;
transition.duration = ANIMATION_TIME_MS;
transition.add_transition (transition_x);
transition.add_transition (transition_y);
transition.stopped.connect (() => { visible = false; });
transition.started.connect (() => { visible = true; });
add_transition ("circle", transition);

var rgba = Drawing.StyleManager.get_instance ().theme_accent_color;

/* Don't use alpha from the stylesheet to ensure contrast */
stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue);
fill_color = new Cairo.Pattern.rgba (rgba.red, rgba.green, rgba.blue, BACKGROUND_OPACITY);

unowned var tracker = display.get_cursor_tracker ();
Graphene.Point coords = {};
tracker.get_pointer (out coords, null);

update_surface (display.get_monitor_scale (display.get_current_monitor ()));

x = coords.x - (width / 2);
y = coords.y - (width / 2);

transition.start ();
unowned var old_transition = get_transition ("circle");
if (old_transition != null) {
old_transition.stop ();
}

var transition = new Clutter.TransitionGroup ();
transition.remove_on_complete = true;
var transition_x = new Clutter.PropertyTransition ("scale-x");
var transition_y = new Clutter.PropertyTransition ("scale-y");
var start_val = Value (typeof (double));
start_val.set_double (1);
var stop_val = Value (typeof (double));
stop_val.set_double (0);
transition_x.set_from_value (start_val);
transition_y.set_from_value (start_val);
transition_x.set_to_value (stop_val);
transition_y.set_to_value (stop_val);
transition.progress_mode = Clutter.AnimationMode.EASE_OUT_QUAD;
transition.duration = ANIMATION_TIME_MS;
transition.add_transition (transition_x);
transition.add_transition (transition_y);
transition.stopped.connect (() => { visible = false; });
transition.started.connect (() => { visible = true; });
add_transition ("circle", transition);

var rgba = Drawing.StyleManager.get_instance ().theme_accent_color;

/* Don't use alpha from the stylesheet to ensure contrast */
stroke_color = new Cairo.Pattern.rgb (rgba.red, rgba.green, rgba.blue);
fill_color = new Cairo.Pattern.rgba (rgba.red, rgba.green, rgba.blue, BACKGROUND_OPACITY);

unowned var tracker = display.get_cursor_tracker ();
Graphene.Point coords = {};
tracker.get_pointer (out coords, null);

update_surface (display.get_monitor_scale (display.get_current_monitor ()));

x = coords.x - (width / 2);
y = coords.y - (width / 2);

transition.start ();
}
}

0 comments on commit 42443b2

Please sign in to comment.