Enhancement: Fixes #60, Display and allow user edit of account picture

This commit is contained in:
Rory Fewell
2025-11-06 21:43:15 +00:00
parent 41c756f89a
commit 910c8322d5
30 changed files with 191 additions and 32 deletions

View File

@@ -20,6 +20,7 @@
#define USER_TILE_OFFSET_Y 6
#define USER_PIC_OFFSET 5
#define USER_PIC_SIZE 48
#define USER_NAME_OFFSET_X 75
#define USER_NAME_OFFSET_Y 25
@@ -37,6 +38,15 @@ enum
N_PROPERTIES
};
//
// PRIVATE STRUCTURES
//
typedef struct _WinTCWelcomeUserpic
{
GdkPixbuf* pixbuf;
cairo_surface_t* surface;
} WinTCWelcomeUserpic;
//
// FORWARD DECLARATIONS
//
@@ -128,8 +138,16 @@ static void wintc_welcome_user_list_set_vadjustment_values(
static void draw_user(
cairo_t* cr,
LightDMUser* user,
const gboolean selected,
const WinTCWelcomeUserList* user_list
gboolean selected,
WinTCWelcomeUserList* user_list
);
static WinTCWelcomeUserpic* wintc_welcome_user_list_get_userpic(
WinTCWelcomeUserList* user_list,
const gchar* path
);
static void free_userpic(
WinTCWelcomeUserpic* userpic
);
static void on_self_adjustment_changed(
@@ -181,13 +199,14 @@ struct _WinTCWelcomeUserList
//
GdkPixbuf* pixbuf_tile;
GdkPixbuf* pixbuf_tilehot;
GdkPixbuf* pixbuf_userpic;
GdkPixbuf* pixbuf_usersel;
cairo_surface_t* surface_tile;
cairo_surface_t* surface_tilehot;
cairo_surface_t* surface_userpic;
cairo_surface_t* surface_usersel;
GHashTable* map_path_to_userpic;
WinTCWelcomeUserpic* default_userpic;
// Geometry
//
gint item_height;
@@ -299,11 +318,6 @@ static void wintc_welcome_user_list_init(
"/uk/oddmatics/wintc/logonui/tilehot.png",
NULL // FIXME: Error reporting
);
self->pixbuf_userpic =
gdk_pixbuf_new_from_resource(
"/uk/oddmatics/wintc/logonui/userpic.png",
NULL // FIXME: Error reporting
);
self->pixbuf_usersel =
gdk_pixbuf_new_from_resource(
"/uk/oddmatics/wintc/logonui/usersel.png",
@@ -322,12 +336,6 @@ static void wintc_welcome_user_list_init(
1,
NULL
);
self->surface_userpic =
gdk_cairo_surface_create_from_pixbuf(
self->pixbuf_userpic,
1,
NULL
);
self->surface_usersel =
gdk_cairo_surface_create_from_pixbuf(
self->pixbuf_usersel,
@@ -335,6 +343,30 @@ static void wintc_welcome_user_list_init(
NULL
);
// Set up userpic map and default userpic
//
self->map_path_to_userpic =
g_hash_table_new_full(
g_str_hash,
g_str_equal,
(GDestroyNotify) g_free,
(GDestroyNotify) free_userpic
);
self->default_userpic = g_new(WinTCWelcomeUserpic, 1);
self->default_userpic->pixbuf =
gdk_pixbuf_new_from_resource(
"/uk/oddmatics/wintc/logonui/userpic.png",
NULL // FIXME: Error reporting
);
self->default_userpic->surface =
gdk_cairo_surface_create_from_pixbuf(
self->default_userpic->pixbuf,
1,
NULL
);
// Set up widgets
//
self->box_auth = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
@@ -422,11 +454,9 @@ static void wintc_welcome_user_list_finalize(
cairo_surface_destroy(user_list->surface_tile);
cairo_surface_destroy(user_list->surface_tilehot);
cairo_surface_destroy(user_list->surface_userpic);
cairo_surface_destroy(user_list->surface_usersel);
g_clear_object(&user_list->pixbuf_tile);
g_clear_object(&user_list->pixbuf_tilehot);
g_clear_object(&user_list->pixbuf_userpic);
g_clear_object(&user_list->pixbuf_usersel);
(G_OBJECT_CLASS(wintc_welcome_user_list_parent_class))->finalize(gobject);
@@ -956,8 +986,8 @@ static void wintc_welcome_user_list_set_vadjustment_values(
static void draw_user(
cairo_t* cr,
LightDMUser* user,
const gboolean selected,
const WinTCWelcomeUserList* user_list
gboolean selected,
WinTCWelcomeUserList* user_list
)
{
//const gchar* text = lightdm_user_get_name(user);
@@ -984,6 +1014,12 @@ static void draw_user(
// Render userpic
//
WinTCWelcomeUserpic* userpic =
wintc_welcome_user_list_get_userpic(
user_list,
lightdm_user_get_image(user)
);
cairo_set_source_surface(
cr,
selected ?
@@ -996,7 +1032,7 @@ static void draw_user(
cairo_set_source_surface(
cr,
user_list->surface_userpic,
userpic->surface,
USER_TILE_OFFSET_X + USER_PIC_OFFSET,
USER_TILE_OFFSET_Y + USER_PIC_OFFSET + origin_y
);
@@ -1020,9 +1056,73 @@ static void draw_user(
cairo_show_text(cr, lightdm_user_get_name(user));
}
static WinTCWelcomeUserpic* wintc_welcome_user_list_get_userpic(
WinTCWelcomeUserList* user_list,
const gchar* path
)
{
WinTCWelcomeUserpic* userpic;
if (!path)
{
return user_list->default_userpic;
}
userpic =
g_hash_table_lookup(
user_list->map_path_to_userpic,
path
);
if (userpic)
{
return userpic;
}
// Load the userpic
//
GdkPixbuf* pixbuf =
gdk_pixbuf_new_from_file_at_scale(
path,
USER_PIC_SIZE,
USER_PIC_SIZE,
FALSE,
NULL
);
if (!pixbuf)
{
return user_list->default_userpic;
}
// All good, create the userpic mapping
//
userpic = g_new(WinTCWelcomeUserpic, 1);
userpic->pixbuf = pixbuf;
userpic->surface = gdk_cairo_surface_create_from_pixbuf(pixbuf, 1, NULL);
g_hash_table_insert(
user_list->map_path_to_userpic,
g_strdup(path),
userpic
);
return userpic;
}
//
// CALLBACKS
//
static void free_userpic(
WinTCWelcomeUserpic* userpic
)
{
cairo_surface_destroy(userpic->surface);
g_object_unref(userpic->pixbuf);
g_free(userpic);
}
static void on_self_adjustment_changed(
WINTC_UNUSED(GtkAdjustment* adjustment),
WinTCWelcomeUserList* user_list

View File

@@ -0,0 +1,32 @@
cmake_minimum_required(VERSION 3.12)
project(
wintc-user-pictures
VERSION 1.0
DESCRIPTION "Windows Total Conversion user pictures."
LANGUAGES C
)
set(PROJECT_ANYARCH true)
set(PROJECT_FREESTATUS false)
set(PROJECT_MAINTAINER "Rory Fewell <roryf@oddmatics.uk>")
set(PROJECT_ROOT ${CMAKE_CURRENT_LIST_DIR})
include(GNUInstallDirs)
include(../../packaging/cmake-inc/common/CMakeLists.txt)
include(../../packaging/cmake-inc/packaging/CMakeLists.txt)
# Installation
#
wintc_configure_and_install_packaging()
install(
DIRECTORY ${PROJECT_ROOT}/default/
DESTINATION ${WINTC_ASSETS_INSTALL_DIR}/userpics/default
)
install(
FILES ${PROJECT_ROOT}/guest.bmp
DESTINATION ${WINTC_ASSETS_INSTALL_DIR}/userpics
)

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

BIN
enduser/userpics/guest.bmp Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

View File

@@ -7,6 +7,7 @@
<file>start-menu.css</file>
<file>task-buttons.css</file>
<file>taskbutton-ctx-menu.ui</file>
<file>userpic.bmp</file>
<file>volume-popup.css</file>
</gresource>
</gresources>

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

@@ -925,22 +925,48 @@ static void refresh_userpic(
WinTCToolbarStart* toolbar_start
)
{
// TODO: Read from AccountsService or whatever on DBus? Default to the
// flower pic -- for now we're just displaying the FPO image
//
static const gchar* css =
"* { background-image: url('"
WINTC_ASSETS_DIR "/shell-res/fpo-userpic.png"
"'); }";
static const gchar* s_path_face = NULL;
// Give GTK a bump that we want to update the pic
if (!s_path_face)
{
s_path_face =
g_build_path(
G_DIR_SEPARATOR_S,
g_get_home_dir(),
".face",
NULL
);
}
// Update the pic CSS if we have a face, otherwise default to the built-in
// pic
//
const gchar* actual_path;
gchar* css;
if (g_file_test(s_path_face, G_FILE_TEST_IS_REGULAR))
{
actual_path = s_path_face;
}
else
{
actual_path = "resource:///uk/oddmatics/wintc/taskband/userpic.bmp";
}
css =
g_strdup_printf(
"* { background-image: url('%s'); }",
actual_path
);
gtk_css_provider_load_from_data(
GTK_CSS_PROVIDER(toolbar_start->personal.style_userpic),
css,
-1,
NULL
);
g_free(css);
}
static void update_personal_menu_mfu_items(