2025-02-10 09:12:59 +01:00
|
|
|
/* vi:set et ai sw=2 sts=2 ts=2: */
|
|
|
|
|
/*-
|
|
|
|
|
* Copyright (c) 2022 Amrit Borah <elessar1802@gmail.com>
|
|
|
|
|
*
|
|
|
|
|
* 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 2 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, write to the Free Software Foundation, Inc., 59 Temple
|
|
|
|
|
* Place, Suite 330, Boston, MA 02111-1307 USA
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
#include "thunar/thunar-text-renderer.h"
|
|
|
|
|
#include "thunar/thunar-util.h"
|
2026-04-29 17:18:16 +03:00
|
|
|
#include <math.h>
|
|
|
|
|
|
|
|
|
|
#define USAGE_BAR_HEIGHT 4
|
|
|
|
|
#define USAGE_BAR_TOP_PAD 2
|
|
|
|
|
#define USAGE_BAR_RADIUS 2
|
2025-02-10 09:12:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
|
{
|
|
|
|
|
PROP_0,
|
|
|
|
|
PROP_HIGHLIGHT_COLOR,
|
|
|
|
|
PROP_ROUNDED_CORNERS,
|
|
|
|
|
PROP_HIGHLIGHTING_ENABLED,
|
2026-04-29 17:18:16 +03:00
|
|
|
PROP_USAGE_PERCENT,
|
2025-02-10 09:12:59 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_finalize (GObject *object);
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_get_property (GObject *object,
|
|
|
|
|
guint prop_id,
|
|
|
|
|
GValue *value,
|
|
|
|
|
GParamSpec *pspec);
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_set_property (GObject *object,
|
|
|
|
|
guint prop_id,
|
|
|
|
|
const GValue *value,
|
|
|
|
|
GParamSpec *pspec);
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_render (GtkCellRenderer *renderer,
|
|
|
|
|
cairo_t *cr,
|
|
|
|
|
GtkWidget *widget,
|
|
|
|
|
const GdkRectangle *background_area,
|
|
|
|
|
const GdkRectangle *cell_area,
|
|
|
|
|
GtkCellRendererState flags);
|
2026-04-29 17:18:16 +03:00
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_get_preferred_height (GtkCellRenderer *cell,
|
|
|
|
|
GtkWidget *widget,
|
|
|
|
|
gint *minimum,
|
|
|
|
|
gint *natural);
|
2025-02-10 09:12:59 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct _ThunarTextRendererClass
|
|
|
|
|
{
|
|
|
|
|
GtkCellRendererTextClass __parent__;
|
|
|
|
|
|
|
|
|
|
void (*default_render_function) (GtkCellRenderer *cell,
|
|
|
|
|
cairo_t *cr,
|
|
|
|
|
GtkWidget *widget,
|
|
|
|
|
const GdkRectangle *background_area,
|
|
|
|
|
const GdkRectangle *cell_area,
|
|
|
|
|
GtkCellRendererState flags);
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct _ThunarTextRenderer
|
|
|
|
|
{
|
|
|
|
|
GtkCellRendererText __parent__;
|
|
|
|
|
|
|
|
|
|
gchar *highlight_color;
|
|
|
|
|
gboolean rounded_corners;
|
|
|
|
|
gboolean highlighting_enabled;
|
2026-04-29 17:18:16 +03:00
|
|
|
gint usage_percent; /* -1 = no bar, 0..100 = percent used */
|
2025-02-10 09:12:59 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
G_DEFINE_TYPE (ThunarTextRenderer, thunar_text_renderer, GTK_TYPE_CELL_RENDERER_TEXT);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_class_init (ThunarTextRendererClass *klass)
|
|
|
|
|
{
|
|
|
|
|
GObjectClass *object_class = G_OBJECT_CLASS (klass);
|
|
|
|
|
GtkCellRendererClass *cell_class = GTK_CELL_RENDERER_CLASS (klass);
|
|
|
|
|
|
|
|
|
|
object_class->finalize = thunar_text_renderer_finalize;
|
|
|
|
|
|
|
|
|
|
object_class->get_property = thunar_text_renderer_get_property;
|
|
|
|
|
object_class->set_property = thunar_text_renderer_set_property;
|
|
|
|
|
|
|
|
|
|
klass->default_render_function = cell_class->render;
|
|
|
|
|
cell_class->render = thunar_text_renderer_render;
|
2026-04-29 17:18:16 +03:00
|
|
|
cell_class->get_preferred_height = thunar_text_renderer_get_preferred_height;
|
2025-02-10 09:12:59 +01:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* ThunarTextRenderer:highlight-color:
|
|
|
|
|
*
|
|
|
|
|
* The color with which the cell should be highlighted.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property (object_class,
|
|
|
|
|
PROP_HIGHLIGHT_COLOR,
|
|
|
|
|
g_param_spec_string ("highlight-color", "highlight-color", "highlight-color",
|
|
|
|
|
NULL,
|
|
|
|
|
EXO_PARAM_READWRITE));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* ThunarTextRenderer:rounded-corners:
|
|
|
|
|
*
|
|
|
|
|
* Determines if the cell should be clipped to rounded corners.
|
|
|
|
|
* Useful when highlighting is enabled & a highlight color is set.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property (object_class,
|
|
|
|
|
PROP_ROUNDED_CORNERS,
|
|
|
|
|
g_param_spec_boolean ("rounded-corners", "rounded-corners", "rounded-corners",
|
|
|
|
|
FALSE,
|
|
|
|
|
EXO_PARAM_READWRITE));
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* ThunarTextRenderer:highlighting-enabled:
|
|
|
|
|
*
|
|
|
|
|
* Determines if the cell background should be drawn with highlight color.
|
|
|
|
|
**/
|
|
|
|
|
g_object_class_install_property (object_class,
|
|
|
|
|
PROP_HIGHLIGHTING_ENABLED,
|
|
|
|
|
g_param_spec_boolean ("highlighting-enabled", "highlighting-enabled", "highlighting-enabled",
|
|
|
|
|
FALSE,
|
|
|
|
|
EXO_PARAM_READWRITE));
|
2026-04-29 17:18:16 +03:00
|
|
|
|
|
|
|
|
g_object_class_install_property (object_class,
|
|
|
|
|
PROP_USAGE_PERCENT,
|
|
|
|
|
g_param_spec_int ("usage-percent", "usage-percent",
|
|
|
|
|
"Disk usage percentage (0-100, -1 = hidden)",
|
|
|
|
|
-1, 100, -1,
|
|
|
|
|
G_PARAM_READWRITE));
|
2025-02-10 09:12:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_init (ThunarTextRenderer *text_renderer)
|
|
|
|
|
{
|
|
|
|
|
text_renderer->highlight_color = NULL;
|
2026-04-29 17:18:16 +03:00
|
|
|
text_renderer->usage_percent = -1;
|
2025-02-10 09:12:59 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_finalize (GObject *object)
|
|
|
|
|
{
|
|
|
|
|
ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (object);
|
|
|
|
|
|
|
|
|
|
g_free (text_renderer->highlight_color);
|
|
|
|
|
|
|
|
|
|
G_OBJECT_CLASS (thunar_text_renderer_parent_class)->finalize (object);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_get_property (GObject *object,
|
|
|
|
|
guint prop_id,
|
|
|
|
|
GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (object);
|
|
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
|
{
|
|
|
|
|
case PROP_HIGHLIGHT_COLOR:
|
|
|
|
|
g_value_set_string (value, text_renderer->highlight_color);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PROP_ROUNDED_CORNERS:
|
|
|
|
|
g_value_set_boolean (value, text_renderer->rounded_corners);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PROP_HIGHLIGHTING_ENABLED:
|
|
|
|
|
g_value_set_boolean (value, text_renderer->highlighting_enabled);
|
|
|
|
|
break;
|
|
|
|
|
|
2026-04-29 17:18:16 +03:00
|
|
|
case PROP_USAGE_PERCENT:
|
|
|
|
|
g_value_set_int (value, text_renderer->usage_percent);
|
|
|
|
|
break;
|
|
|
|
|
|
2025-02-10 09:12:59 +01:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_set_property (GObject *object,
|
|
|
|
|
guint prop_id,
|
|
|
|
|
const GValue *value,
|
|
|
|
|
GParamSpec *pspec)
|
|
|
|
|
{
|
|
|
|
|
ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (object);
|
|
|
|
|
|
|
|
|
|
switch (prop_id)
|
|
|
|
|
{
|
|
|
|
|
case PROP_HIGHLIGHT_COLOR:
|
|
|
|
|
g_free (text_renderer->highlight_color);
|
|
|
|
|
text_renderer->highlight_color = g_value_dup_string (value);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PROP_ROUNDED_CORNERS:
|
|
|
|
|
text_renderer->rounded_corners = g_value_get_boolean (value);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case PROP_HIGHLIGHTING_ENABLED:
|
|
|
|
|
text_renderer->highlighting_enabled = g_value_get_boolean (value);
|
|
|
|
|
break;
|
|
|
|
|
|
2026-04-29 17:18:16 +03:00
|
|
|
case PROP_USAGE_PERCENT:
|
|
|
|
|
text_renderer->usage_percent = g_value_get_int (value);
|
|
|
|
|
break;
|
|
|
|
|
|
2025-02-10 09:12:59 +01:00
|
|
|
default:
|
|
|
|
|
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* thunar_text_renderer_new:
|
|
|
|
|
*
|
|
|
|
|
* Creates a new #ThunarTextRenderer. Adjust rendering
|
|
|
|
|
* parameters using object properties. Object properties can be
|
|
|
|
|
* set globally with #g_object_set. Also, with #GtkTreeViewColumn,
|
|
|
|
|
* you can bind a property to a value in a #GtkTreeModel.
|
|
|
|
|
*
|
|
|
|
|
* Return value: (transfer full) The newly allocated #ThunarTextRenderer.
|
|
|
|
|
**/
|
|
|
|
|
GtkCellRenderer *
|
|
|
|
|
thunar_text_renderer_new (void)
|
|
|
|
|
{
|
|
|
|
|
return g_object_new (THUNAR_TYPE_TEXT_RENDERER, NULL);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2026-04-29 17:18:16 +03:00
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_get_preferred_height (GtkCellRenderer *cell,
|
|
|
|
|
GtkWidget *widget,
|
|
|
|
|
gint *minimum,
|
|
|
|
|
gint *natural)
|
|
|
|
|
{
|
|
|
|
|
gint min_h = 0, nat_h = 0;
|
|
|
|
|
|
|
|
|
|
GTK_CELL_RENDERER_CLASS (thunar_text_renderer_parent_class)->get_preferred_height (cell, widget, &min_h, &nat_h);
|
|
|
|
|
|
|
|
|
|
if (minimum != NULL) *minimum = min_h;
|
|
|
|
|
if (natural != NULL) *natural = nat_h;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_draw_usage_bar (cairo_t *cr,
|
|
|
|
|
GtkWidget *widget,
|
|
|
|
|
const GdkRectangle *cell_area,
|
|
|
|
|
gint usage_percent)
|
|
|
|
|
{
|
|
|
|
|
GtkStyleContext *context;
|
|
|
|
|
GdkRGBA bar_bg = { 0.5, 0.5, 0.5, 0.3 };
|
|
|
|
|
GdkRGBA bar_fg;
|
|
|
|
|
gint xpad = 2;
|
|
|
|
|
gdouble x = cell_area->x + xpad;
|
|
|
|
|
gdouble y = cell_area->y + cell_area->height - USAGE_BAR_HEIGHT;
|
|
|
|
|
gdouble w = cell_area->width - 2 * xpad;
|
|
|
|
|
gdouble h = USAGE_BAR_HEIGHT;
|
|
|
|
|
gdouble r = USAGE_BAR_RADIUS;
|
|
|
|
|
gdouble fw;
|
|
|
|
|
|
|
|
|
|
if (w <= 0)
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
|
context = gtk_widget_get_style_context (widget);
|
|
|
|
|
|
|
|
|
|
if (usage_percent > 90)
|
|
|
|
|
{
|
|
|
|
|
bar_fg.red = 0.85; bar_fg.green = 0.2; bar_fg.blue = 0.2; bar_fg.alpha = 0.9;
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
if (!gtk_style_context_lookup_color (context, "theme_selected_bg_color", &bar_fg)
|
|
|
|
|
|| bar_fg.alpha < 0.01)
|
|
|
|
|
{ bar_fg.red = 0.3; bar_fg.green = 0.5; bar_fg.blue = 0.8; }
|
|
|
|
|
bar_fg.alpha = 0.9;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cairo_save (cr);
|
|
|
|
|
|
|
|
|
|
/* background track */
|
|
|
|
|
cairo_new_sub_path (cr);
|
|
|
|
|
cairo_arc (cr, x + w - r, y + r, r, -G_PI_2, 0);
|
|
|
|
|
cairo_arc (cr, x + w - r, y + h - r, r, 0, G_PI_2);
|
|
|
|
|
cairo_arc (cr, x + r, y + h - r, r, G_PI_2, G_PI);
|
|
|
|
|
cairo_arc (cr, x + r, y + r, r, G_PI, 3 * G_PI_2);
|
|
|
|
|
cairo_close_path (cr);
|
|
|
|
|
gdk_cairo_set_source_rgba (cr, &bar_bg);
|
|
|
|
|
cairo_fill (cr);
|
|
|
|
|
|
|
|
|
|
/* filled portion */
|
|
|
|
|
if (usage_percent > 0)
|
|
|
|
|
{
|
|
|
|
|
fw = w * usage_percent / 100.0;
|
|
|
|
|
r = USAGE_BAR_RADIUS;
|
|
|
|
|
if (fw < 2 * r) r = fw / 2.0;
|
|
|
|
|
if (r < 0.5) r = 0;
|
|
|
|
|
|
|
|
|
|
cairo_new_sub_path (cr);
|
|
|
|
|
cairo_arc (cr, x + fw - r, y + r, r, -G_PI_2, 0);
|
|
|
|
|
cairo_arc (cr, x + fw - r, y + h - r, r, 0, G_PI_2);
|
|
|
|
|
cairo_arc (cr, x + r, y + h - r, r, G_PI_2, G_PI);
|
|
|
|
|
cairo_arc (cr, x + r, y + r, r, G_PI, 3 * G_PI_2);
|
|
|
|
|
cairo_close_path (cr);
|
|
|
|
|
gdk_cairo_set_source_rgba (cr, &bar_fg);
|
|
|
|
|
cairo_fill (cr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
cairo_restore (cr);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2025-02-10 09:12:59 +01:00
|
|
|
static void
|
|
|
|
|
thunar_text_renderer_render (GtkCellRenderer *cell,
|
|
|
|
|
cairo_t *cr,
|
|
|
|
|
GtkWidget *widget,
|
|
|
|
|
const GdkRectangle *background_area,
|
|
|
|
|
const GdkRectangle *cell_area,
|
|
|
|
|
GtkCellRendererState flags)
|
|
|
|
|
{
|
2026-04-29 17:18:16 +03:00
|
|
|
ThunarTextRenderer *text_renderer = THUNAR_TEXT_RENDERER (cell);
|
|
|
|
|
|
|
|
|
|
if (text_renderer->highlighting_enabled)
|
2025-02-10 09:12:59 +01:00
|
|
|
thunar_util_clip_view_background (cell, cr, background_area, widget, flags);
|
|
|
|
|
|
2026-04-29 17:18:16 +03:00
|
|
|
/* draw text normally */
|
|
|
|
|
THUNAR_TEXT_RENDERER_GET_CLASS (text_renderer)
|
2025-02-10 09:12:59 +01:00
|
|
|
->default_render_function (cell, cr, widget, background_area, cell_area, flags);
|
2026-04-29 17:18:16 +03:00
|
|
|
|
|
|
|
|
/* draw usage bar at the very bottom of the cell, overlapping if needed */
|
|
|
|
|
if (text_renderer->usage_percent >= 0)
|
|
|
|
|
thunar_text_renderer_draw_usage_bar (cr, widget, cell_area, text_renderer->usage_percent);
|
2025-02-10 09:12:59 +01:00
|
|
|
}
|