Private
Public Access
1
0

attempt to resolve scaling issues on 2x displays

This commit is contained in:
2025-04-30 21:19:24 -07:00
parent a7e88bd3c3
commit f80d1a609b
2 changed files with 63 additions and 45 deletions

View File

@@ -1,6 +1,24 @@
using Gtk; using Gtk;
using Gee; using Gee;
private struct MessageLayoutConstants {
public float tail_width;
public float tail_curve_offset;
public float tail_side_offset;
public float tail_bottom_padding;
public float corner_radius;
public float text_padding;
public MessageLayoutConstants(float scale_factor) {
tail_width = 15.0f / scale_factor;
tail_curve_offset = 2.5f / scale_factor;
tail_side_offset = 0.0f / scale_factor;
tail_bottom_padding = 4.0f / scale_factor;
corner_radius = 32.0f / scale_factor;
text_padding = 18.0f / scale_factor;
}
}
private class MessageLayout : Object private class MessageLayout : Object
{ {
public Message message; public Message message;
@@ -8,25 +26,25 @@ private class MessageLayout : Object
private float max_width; private float max_width;
private Pango.Layout layout; private Pango.Layout layout;
private Widget parent; private Widget parent;
private MessageLayoutConstants constants;
const float tail_width = 15.0f;
const float tail_curve_offset = 2.5f;
const float tail_side_offset = 0.0f;
const float tail_bottom_padding = 4.0f;
const float corner_radius = 32.0f;
const float text_padding = 18.0f;
const string font_description = "Sans 13";
public MessageLayout(Message message, Widget parent, float max_width) { public MessageLayout(Message message, Widget parent, float max_width) {
this.message = message; this.message = message;
this.max_width = max_width; this.max_width = max_width;
this.parent = parent; this.parent = parent;
this.constants = MessageLayoutConstants(parent.get_scale_factor());
layout = parent.create_pango_layout(message.text); layout = parent.create_pango_layout(message.text);
// Set text attributes // Get the system font settings
var font_desc = Pango.FontDescription.from_string(font_description); var settings = Gtk.Settings.get_default();
var font_name = settings.gtk_font_name;
// Create font description from system font
var font_desc = Pango.FontDescription.from_string(font_name);
var size = font_desc.get_size();
font_desc.set_size((int)(size));
layout.set_font_description(font_desc); layout.set_font_description(font_desc);
// Set max width // Set max width
@@ -41,20 +59,20 @@ private class MessageLayout : Object
private float text_available_width { private float text_available_width {
get { get {
return max_width - text_x_offset - text_padding; return max_width - text_x_offset - constants.text_padding;
} }
} }
private float text_x_offset { private float text_x_offset {
get { get {
return from_me ? text_padding : tail_width + text_padding; return from_me ? constants.text_padding : constants.tail_width + constants.text_padding;
} }
} }
private float text_x_padding { private float text_x_padding {
get { get {
// Opposite of text_x_offset // Opposite of text_x_offset
return from_me ? tail_width + text_padding : text_padding; return from_me ? constants.tail_width + constants.text_padding : constants.text_padding;
} }
} }
@@ -73,7 +91,7 @@ private class MessageLayout : Object
Pango.Rectangle ink_rect, logical_rect; Pango.Rectangle ink_rect, logical_rect;
layout.get_pixel_extents(out ink_rect, out logical_rect); layout.get_pixel_extents(out ink_rect, out logical_rect);
return logical_rect.height + corner_radius + tail_bottom_padding; return logical_rect.height + constants.corner_radius + constants.tail_bottom_padding;
} }
public float get_width() { public float get_width() {
@@ -98,7 +116,7 @@ private class MessageLayout : Object
layout.get_pixel_extents(out ink_rect, out logical_rect); layout.get_pixel_extents(out ink_rect, out logical_rect);
snapshot.translate(Graphene.Point() { snapshot.translate(Graphene.Point() {
x = text_x_offset, x = text_x_offset,
y = ((get_height() - tail_bottom_padding) - logical_rect.height) / 2 y = ((get_height() - constants.tail_bottom_padding) - logical_rect.height) / 2
}); });
snapshot.append_layout(layout, Gdk.RGBA() { snapshot.append_layout(layout, Gdk.RGBA() {
@@ -151,11 +169,11 @@ private class MessageLayout : Object
{ {
var builder = new Gsk.PathBuilder(); var builder = new Gsk.PathBuilder();
float bubble_width = width - tail_width; float bubble_width = width - constants.tail_width;
float bubble_height = height - tail_bottom_padding; float bubble_height = height - constants.tail_bottom_padding;
// Base position adjustments based on tail position // Base position adjustments based on tail position
float x = tail_on_right ? 0.0f : tail_width; float x = tail_on_right ? 0.0f : constants.tail_width;
float y = 0.0f; float y = 0.0f;
// Calculate tail direction multiplier (-1 for left, 1 for right) // Calculate tail direction multiplier (-1 for left, 1 for right)
@@ -165,38 +183,38 @@ private class MessageLayout : Object
float tail_side_x = tail_on_right ? (x + bubble_width) : x; float tail_side_x = tail_on_right ? (x + bubble_width) : x;
// Start at top corner opposite to the tail // Start at top corner opposite to the tail
builder.move_to(tail_on_right ? (x + corner_radius) : (x + bubble_width - corner_radius), y); builder.move_to(tail_on_right ? (x + constants.corner_radius) : (x + bubble_width - constants.corner_radius), y);
// Top edge // Top edge
builder.line_to(tail_on_right ? (x + bubble_width - corner_radius) : (x + corner_radius), y); builder.line_to(tail_on_right ? (x + bubble_width - constants.corner_radius) : (x + constants.corner_radius), y);
// Top corner on tail side // Top corner on tail side
if (tail_on_right) { if (tail_on_right) {
builder.html_arc_to(x + bubble_width, y, builder.html_arc_to(x + bubble_width, y,
x + bubble_width, y + corner_radius, x + bubble_width, y + constants.corner_radius,
corner_radius); constants.corner_radius);
} else { } else {
builder.html_arc_to(x, y, builder.html_arc_to(x, y,
x, y + corner_radius, x, y + constants.corner_radius,
corner_radius); constants.corner_radius);
} }
// Side edge on tail side // Side edge on tail side
builder.line_to(tail_side_x, y + bubble_height - corner_radius); builder.line_to(tail_side_x, y + bubble_height - constants.corner_radius);
// Corner with tail // Corner with tail
float tail_tip_x = tail_side_x + (dir * (tail_width - tail_curve_offset)); float tail_tip_x = tail_side_x + (dir * (constants.tail_width - constants.tail_curve_offset));
float tail_tip_y = y + bubble_height; float tail_tip_y = y + bubble_height;
// Control points for the bezier curve // Control points for the bezier curve
float ctrl_point1_x = tail_side_x + (dir * tail_side_offset); float ctrl_point1_x = tail_side_x + (dir * constants.tail_side_offset);
float ctrl_point1_y = y + bubble_height - corner_radius/3; float ctrl_point1_y = y + bubble_height - constants.corner_radius/3;
float ctrl_point2_x = tail_side_x + (dir * (tail_width / 2.0f)); float ctrl_point2_x = tail_side_x + (dir * (constants.tail_width / 2.0f));
float ctrl_point2_y = y + bubble_height - 2; float ctrl_point2_y = y + bubble_height - 2;
// Point where the tail meets the bottom edge // Point where the tail meets the bottom edge
float tail_base_x = tail_side_x - (dir * corner_radius/2); float tail_base_x = tail_side_x - (dir * constants.corner_radius/2);
float tail_base_y = y + bubble_height; float tail_base_y = y + bubble_height;
// Draw the corner with tail using bezier curves // Draw the corner with tail using bezier curves
@@ -204,39 +222,39 @@ private class MessageLayout : Object
ctrl_point2_x, ctrl_point2_y, ctrl_point2_x, ctrl_point2_y,
tail_tip_x, tail_tip_y); tail_tip_x, tail_tip_y);
builder.cubic_to(tail_tip_x - (dir * tail_curve_offset), tail_tip_y + tail_curve_offset, builder.cubic_to(tail_tip_x - (dir * constants.tail_curve_offset), tail_tip_y + constants.tail_curve_offset,
tail_base_x + (dir * tail_width), tail_base_y, tail_base_x + (dir * constants.tail_width), tail_base_y,
tail_base_x, tail_base_y); tail_base_x, tail_base_y);
// Bottom edge // Bottom edge
builder.line_to(tail_on_right ? (x + corner_radius) : (x + bubble_width - corner_radius), y + bubble_height); builder.line_to(tail_on_right ? (x + constants.corner_radius) : (x + bubble_width - constants.corner_radius), y + bubble_height);
// Bottom corner opposite to tail // Bottom corner opposite to tail
if (tail_on_right) { if (tail_on_right) {
builder.html_arc_to(x, y + bubble_height, builder.html_arc_to(x, y + bubble_height,
x, y + bubble_height - corner_radius, x, y + bubble_height - constants.corner_radius,
corner_radius); constants.corner_radius);
} else { } else {
builder.html_arc_to(x + bubble_width, y + bubble_height, builder.html_arc_to(x + bubble_width, y + bubble_height,
x + bubble_width, y + bubble_height - corner_radius, x + bubble_width, y + bubble_height - constants.corner_radius,
corner_radius); constants.corner_radius);
} }
// Side edge opposite to tail // Side edge opposite to tail
if (tail_on_right) { if (tail_on_right) {
builder.line_to(x, y + corner_radius); builder.line_to(x, y + constants.corner_radius);
// Top corner to close path // Top corner to close path
builder.html_arc_to(x, y, builder.html_arc_to(x, y,
x + corner_radius, y, x + constants.corner_radius, y,
corner_radius); constants.corner_radius);
} else { } else {
builder.line_to(x + bubble_width, y + corner_radius); builder.line_to(x + bubble_width, y + constants.corner_radius);
// Top corner to close path // Top corner to close path
builder.html_arc_to(x + bubble_width, y, builder.html_arc_to(x + bubble_width, y,
x + bubble_width - corner_radius, y, x + bubble_width - constants.corner_radius, y,
corner_radius); constants.corner_radius);
} }
// Close the path // Close the path

View File

@@ -1,7 +1,7 @@
/* Kordophone application styles */ /* Kordophone application styles */
.conversation-row { .conversation-row {
padding: 8px 12px; padding: 6px 10px;
border-bottom: 1px solid alpha(#000, 0.1); border-bottom: 1px solid alpha(#000, 0.1);
} }