mirror of
https://github.com/ZoiteChat/zoitechat.git
synced 2026-03-10 07:50:19 +00:00
feat: merge GTK3 Theme into Appearance (new Advanced section); fix+scale chat bg image + use FileChooserNative picker
This commit is contained in:
@@ -118,11 +118,43 @@ pixmap_load_from_file_real (char *file)
|
|||||||
{
|
{
|
||||||
GdkPixbuf *img;
|
GdkPixbuf *img;
|
||||||
cairo_surface_t *surface;
|
cairo_surface_t *surface;
|
||||||
|
int width;
|
||||||
|
int height;
|
||||||
|
const int max_dimension = 4096;
|
||||||
|
|
||||||
img = gdk_pixbuf_new_from_file (file, 0);
|
img = gdk_pixbuf_new_from_file (file, 0);
|
||||||
if (!img)
|
if (!img)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
width = gdk_pixbuf_get_width (img);
|
||||||
|
height = gdk_pixbuf_get_height (img);
|
||||||
|
if (width > max_dimension || height > max_dimension)
|
||||||
|
{
|
||||||
|
GdkPixbuf *scaled;
|
||||||
|
double scale;
|
||||||
|
int target_width;
|
||||||
|
int target_height;
|
||||||
|
|
||||||
|
if (width >= height)
|
||||||
|
scale = (double)max_dimension / (double)width;
|
||||||
|
else
|
||||||
|
scale = (double)max_dimension / (double)height;
|
||||||
|
|
||||||
|
target_width = (int)(width * scale);
|
||||||
|
target_height = (int)(height * scale);
|
||||||
|
if (target_width < 1)
|
||||||
|
target_width = 1;
|
||||||
|
if (target_height < 1)
|
||||||
|
target_height = 1;
|
||||||
|
|
||||||
|
scaled = gdk_pixbuf_scale_simple (img, target_width, target_height, GDK_INTERP_BILINEAR);
|
||||||
|
if (scaled)
|
||||||
|
{
|
||||||
|
g_object_unref (img);
|
||||||
|
img = scaled;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
surface = pixbuf_to_cairo_surface (img);
|
surface = pixbuf_to_cairo_surface (img);
|
||||||
g_object_unref (img);
|
g_object_unref (img);
|
||||||
|
|
||||||
|
|||||||
@@ -161,10 +161,6 @@ static const setting appearance_settings[] =
|
|||||||
{ST_TOGGLE, N_("Colored nick names"), P_OFFINTNL(hex_text_color_nicks), N_("Give each person on IRC a different color"),0,0},
|
{ST_TOGGLE, N_("Colored nick names"), P_OFFINTNL(hex_text_color_nicks), N_("Give each person on IRC a different color"),0,0},
|
||||||
{ST_TOGGLR, N_("Indent nick names"), P_OFFINTNL(hex_text_indent), N_("Make nick names right-justified"),0,0},
|
{ST_TOGGLR, N_("Indent nick names"), P_OFFINTNL(hex_text_indent), N_("Make nick names right-justified"),0,0},
|
||||||
{ST_TOGGLE, N_ ("Show marker line"), P_OFFINTNL (hex_text_show_marker), N_ ("Insert a red line after the last read text."), 0, 0},
|
{ST_TOGGLE, N_ ("Show marker line"), P_OFFINTNL (hex_text_show_marker), N_ ("Insert a red line after the last read text."), 0, 0},
|
||||||
{ST_EFILE, N_ ("Background image:"), P_OFFSETNL (hex_text_background), 0, 0, sizeof prefs.hex_text_background},
|
|
||||||
|
|
||||||
{ST_HEADER, N_("Transparency Settings"), 0,0,0},
|
|
||||||
{ST_HSCALE, N_("Window opacity:"), P_OFFINTNL(hex_gui_transparency),0,0,0},
|
|
||||||
|
|
||||||
{ST_HEADER, N_("Timestamps"),0,0,0},
|
{ST_HEADER, N_("Timestamps"),0,0,0},
|
||||||
{ST_TOGGLE, N_("Enable timestamps"), P_OFFINTNL(hex_stamp_text),0,0,1},
|
{ST_TOGGLE, N_("Enable timestamps"), P_OFFINTNL(hex_stamp_text),0,0,1},
|
||||||
@@ -183,6 +179,15 @@ static const setting appearance_settings[] =
|
|||||||
{ST_END, 0, 0, 0, 0, 0}
|
{ST_END, 0, 0, 0, 0, 0}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const setting appearance_advanced_settings[] =
|
||||||
|
{
|
||||||
|
{ST_HEADER, N_("Advanced"),0,0,0},
|
||||||
|
{ST_EFILE, N_ ("Background image:"), P_OFFSETNL (hex_text_background), 0, 0, sizeof prefs.hex_text_background},
|
||||||
|
{ST_HSCALE, N_("Window opacity:"), P_OFFINTNL(hex_gui_transparency),0,0,0},
|
||||||
|
|
||||||
|
{ST_END, 0, 0, 0, 0, 0}
|
||||||
|
};
|
||||||
|
|
||||||
static const char *const tabcompmenu[] =
|
static const char *const tabcompmenu[] =
|
||||||
{
|
{
|
||||||
N_("A-Z"),
|
N_("A-Z"),
|
||||||
@@ -1141,22 +1146,64 @@ setup_filereq_cb (GtkWidget *entry, char *file)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
setup_browsefile_response_cb (GtkNativeDialog *dialog, gint response, gpointer user_data)
|
||||||
|
{
|
||||||
|
GtkWidget *entry = user_data;
|
||||||
|
|
||||||
|
if (response == GTK_RESPONSE_ACCEPT)
|
||||||
|
{
|
||||||
|
char *file = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog));
|
||||||
|
setup_filereq_cb (entry, file);
|
||||||
|
g_free (file);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_unref (dialog);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
setup_browsefile_cb (GtkWidget *button, GtkWidget *entry)
|
setup_browsefile_cb (GtkWidget *button, GtkWidget *entry)
|
||||||
{
|
{
|
||||||
/* used for background image only */
|
GtkFileChooserNative *dialog;
|
||||||
char *filter;
|
GtkFileFilter *filefilter;
|
||||||
int filter_type;
|
const char *current;
|
||||||
|
char *dirname;
|
||||||
|
|
||||||
|
(void)button;
|
||||||
|
dialog = gtk_file_chooser_native_new (_("Select an Image File"),
|
||||||
|
GTK_WINDOW (setup_window),
|
||||||
|
GTK_FILE_CHOOSER_ACTION_OPEN,
|
||||||
|
_("_Open"),
|
||||||
|
_("_Cancel"));
|
||||||
|
gtk_native_dialog_set_modal (GTK_NATIVE_DIALOG (dialog), TRUE);
|
||||||
|
|
||||||
|
current = gtk_entry_get_text (GTK_ENTRY (entry));
|
||||||
|
if (current && current[0])
|
||||||
|
{
|
||||||
|
dirname = g_path_get_dirname (current);
|
||||||
|
if (dirname && dirname[0] && g_file_test (dirname, G_FILE_TEST_IS_DIR))
|
||||||
|
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), dirname);
|
||||||
|
else if (g_file_test (current, G_FILE_TEST_IS_DIR))
|
||||||
|
gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), current);
|
||||||
|
g_free (dirname);
|
||||||
|
}
|
||||||
|
|
||||||
|
filefilter = gtk_file_filter_new ();
|
||||||
#ifdef WIN32
|
#ifdef WIN32
|
||||||
filter = "*png;*.tiff;*.gif;*.jpeg;*.jpg";
|
gtk_file_filter_add_pattern (filefilter, "*.png");
|
||||||
filter_type = FRF_EXTENSIONS;
|
gtk_file_filter_add_pattern (filefilter, "*.tiff");
|
||||||
|
gtk_file_filter_add_pattern (filefilter, "*.gif");
|
||||||
|
gtk_file_filter_add_pattern (filefilter, "*.jpeg");
|
||||||
|
gtk_file_filter_add_pattern (filefilter, "*.jpg");
|
||||||
#else
|
#else
|
||||||
filter = "image/*";
|
gtk_file_filter_add_mime_type (filefilter, "image/*");
|
||||||
filter_type = FRF_MIMETYPES;
|
|
||||||
#endif
|
#endif
|
||||||
gtkutil_file_req (GTK_WINDOW (setup_window), _("Select an Image File"), setup_filereq_cb,
|
gtk_file_filter_set_name (filefilter, _("Images"));
|
||||||
entry, NULL, filter, filter_type|FRF_RECENTLYUSED|FRF_MODAL);
|
gtk_file_chooser_set_filter (GTK_FILE_CHOOSER (dialog), filefilter);
|
||||||
|
|
||||||
|
g_signal_connect (G_OBJECT (dialog), "response",
|
||||||
|
G_CALLBACK (setup_browsefile_response_cb), entry);
|
||||||
|
gtk_native_dialog_show (GTK_NATIVE_DIALOG (dialog));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -1442,6 +1489,41 @@ setup_create_theme_page (void)
|
|||||||
&color_change);
|
&color_change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static GtkWidget *
|
||||||
|
setup_create_appearance_page (void)
|
||||||
|
{
|
||||||
|
GtkWidget *box;
|
||||||
|
GtkWidget *appearance_page;
|
||||||
|
GtkWidget *theme_label;
|
||||||
|
GtkWidget *theme_page;
|
||||||
|
GtkWidget *advanced_page;
|
||||||
|
|
||||||
|
box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 6);
|
||||||
|
appearance_page = setup_create_page (appearance_settings);
|
||||||
|
theme_label = gtk_label_new (NULL);
|
||||||
|
theme_page = setup_create_theme_page ();
|
||||||
|
advanced_page = setup_create_page (appearance_advanced_settings);
|
||||||
|
|
||||||
|
{
|
||||||
|
char *markup = g_markup_printf_escaped ("<b>%s</b>", _("GTK3 Theme"));
|
||||||
|
gtk_label_set_markup (GTK_LABEL (theme_label), markup);
|
||||||
|
g_free (markup);
|
||||||
|
}
|
||||||
|
gtk_widget_set_halign (theme_label, GTK_ALIGN_START);
|
||||||
|
gtk_widget_set_valign (theme_label, GTK_ALIGN_CENTER);
|
||||||
|
gtk_widget_set_margin_start (theme_label, 2);
|
||||||
|
gtk_widget_set_margin_end (theme_label, 2);
|
||||||
|
gtk_widget_set_margin_top (theme_label, 1);
|
||||||
|
gtk_widget_set_margin_bottom (theme_label, 1);
|
||||||
|
|
||||||
|
gtk_box_pack_start (GTK_BOX (box), appearance_page, FALSE, FALSE, 0);
|
||||||
|
gtk_box_pack_start (GTK_BOX (box), theme_label, FALSE, FALSE, 2);
|
||||||
|
gtk_box_pack_start (GTK_BOX (box), theme_page, FALSE, FALSE, 0);
|
||||||
|
gtk_box_pack_start (GTK_BOX (box), advanced_page, FALSE, FALSE, 0);
|
||||||
|
|
||||||
|
return box;
|
||||||
|
}
|
||||||
|
|
||||||
/* === GLOBALS for sound GUI === */
|
/* === GLOBALS for sound GUI === */
|
||||||
|
|
||||||
static GtkWidget *sndfile_entry;
|
static GtkWidget *sndfile_entry;
|
||||||
@@ -1729,7 +1811,6 @@ static const char *const cata_interface[] =
|
|||||||
N_("Input box"),
|
N_("Input box"),
|
||||||
N_("User list"),
|
N_("User list"),
|
||||||
N_("Channel switcher"),
|
N_("Channel switcher"),
|
||||||
N_("GTK3 Theme"),
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1755,15 +1836,15 @@ static GtkWidget *
|
|||||||
setup_create_pages (GtkWidget *box)
|
setup_create_pages (GtkWidget *box)
|
||||||
{
|
{
|
||||||
GtkWidget *book;
|
GtkWidget *book;
|
||||||
GtkWindow *win = GTK_WINDOW(gtk_widget_get_toplevel (box));
|
GtkWindow *win = GTK_WINDOW (setup_window);
|
||||||
|
|
||||||
|
(void)box;
|
||||||
book = gtk_notebook_new ();
|
book = gtk_notebook_new ();
|
||||||
|
|
||||||
setup_add_page (cata_interface[0], book, setup_create_page (appearance_settings));
|
setup_add_page (cata_interface[0], book, setup_create_appearance_page ());
|
||||||
setup_add_page (cata_interface[1], book, setup_create_page (inputbox_settings));
|
setup_add_page (cata_interface[1], book, setup_create_page (inputbox_settings));
|
||||||
setup_add_page (cata_interface[2], book, setup_create_page (userlist_settings));
|
setup_add_page (cata_interface[2], book, setup_create_page (userlist_settings));
|
||||||
setup_add_page (cata_interface[3], book, setup_create_page (tabs_settings));
|
setup_add_page (cata_interface[3], book, setup_create_page (tabs_settings));
|
||||||
setup_add_page (cata_interface[4], book, setup_create_theme_page ());
|
|
||||||
|
|
||||||
setup_add_page (cata_chatting[0], book, setup_create_page (general_settings));
|
setup_add_page (cata_chatting[0], book, setup_create_page (general_settings));
|
||||||
|
|
||||||
@@ -2124,6 +2205,7 @@ setup_window_open (void)
|
|||||||
|
|
||||||
g_snprintf(buf, sizeof(buf), _("Preferences - %s"), _(DISPLAY_NAME));
|
g_snprintf(buf, sizeof(buf), _("Preferences - %s"), _(DISPLAY_NAME));
|
||||||
win = gtkutil_window_new (buf, "prefs", 0, 600, 2);
|
win = gtkutil_window_new (buf, "prefs", 0, 600, 2);
|
||||||
|
setup_window = win;
|
||||||
|
|
||||||
vbox = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 5);
|
vbox = gtkutil_box_new (GTK_ORIENTATION_VERTICAL, FALSE, 5);
|
||||||
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
|
gtk_container_set_border_width (GTK_CONTAINER (vbox), 6);
|
||||||
|
|||||||
@@ -689,12 +689,15 @@ settings_apply_from_file (const char *theme_root, const char *css_dir)
|
|||||||
for (i = 0; keys && i < n_keys; i++)
|
for (i = 0; keys && i < n_keys; i++)
|
||||||
{
|
{
|
||||||
char *raw_value;
|
char *raw_value;
|
||||||
|
char *value;
|
||||||
|
|
||||||
raw_value = g_key_file_get_value (keyfile, "Settings", keys[i], NULL);
|
raw_value = g_key_file_get_value (keyfile, "Settings", keys[i], NULL);
|
||||||
if (!raw_value)
|
if (!raw_value)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
settings_apply_property (settings, keys[i], raw_value);
|
value = g_strstrip (raw_value);
|
||||||
|
if (value[0] != '\0')
|
||||||
|
settings_apply_property (settings, keys[i], value);
|
||||||
g_free (raw_value);
|
g_free (raw_value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -364,20 +364,30 @@ xtext_draw_bg_offset (GtkXText *xtext, int x, int y, int width, int height, int
|
|||||||
|
|
||||||
if (xtext->background_surface)
|
if (xtext->background_surface)
|
||||||
{
|
{
|
||||||
int clip_x = xtext->clip_x;
|
GtkAllocation allocation;
|
||||||
int clip_y = xtext->clip_y;
|
int clip_x;
|
||||||
int clip_w = xtext->clip_x2 - xtext->clip_x;
|
int clip_y;
|
||||||
int clip_h = xtext->clip_y2 - xtext->clip_y;
|
int clip_w;
|
||||||
|
int clip_h;
|
||||||
|
|
||||||
if (clip_w < 1 || clip_h < 1)
|
if (cairo_surface_status (xtext->background_surface) != CAIRO_STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
GtkAllocation allocation;
|
xtext_draw_rectangle (xtext, cr, &xtext->bgc, x, y, width, height);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
gtk_widget_get_allocation (GTK_WIDGET (xtext), &allocation);
|
gtk_widget_get_allocation (GTK_WIDGET (xtext), &allocation);
|
||||||
clip_x = 0;
|
clip_x = 0;
|
||||||
clip_y = 0;
|
clip_y = 0;
|
||||||
clip_w = allocation.width;
|
clip_w = allocation.width;
|
||||||
clip_h = allocation.height;
|
clip_h = allocation.height;
|
||||||
|
|
||||||
|
if (clip_w < 1 || clip_h < 1 || clip_w > 8192 || clip_h > 8192)
|
||||||
|
{
|
||||||
|
xtext_draw_rectangle (xtext, cr, &xtext->bgc, x, y, width, height);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (xtext->background_clip_surface == NULL ||
|
if (xtext->background_clip_surface == NULL ||
|
||||||
@@ -396,11 +406,54 @@ xtext_draw_bg_offset (GtkXText *xtext, int x, int y, int width, int height, int
|
|||||||
}
|
}
|
||||||
|
|
||||||
xtext->background_clip_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, clip_w, clip_h);
|
xtext->background_clip_surface = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, clip_w, clip_h);
|
||||||
|
if (cairo_surface_status (xtext->background_clip_surface) != CAIRO_STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
cairo_surface_destroy (xtext->background_clip_surface);
|
||||||
|
xtext->background_clip_surface = NULL;
|
||||||
|
xtext_draw_rectangle (xtext, cr, &xtext->bgc, x, y, width, height);
|
||||||
|
cairo_destroy (cr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
bg_cr = cairo_create (xtext->background_clip_surface);
|
bg_cr = cairo_create (xtext->background_clip_surface);
|
||||||
cairo_set_source_surface (bg_cr, xtext->background_surface, tile_x - clip_x, tile_y - clip_y);
|
if (cairo_surface_get_type (xtext->background_surface) == CAIRO_SURFACE_TYPE_IMAGE)
|
||||||
cairo_pattern_set_extend (cairo_get_source (bg_cr), CAIRO_EXTEND_REPEAT);
|
{
|
||||||
cairo_rectangle (bg_cr, 0.0, 0.0, (double)clip_w, (double)clip_h);
|
int src_w = cairo_image_surface_get_width (xtext->background_surface);
|
||||||
cairo_fill (bg_cr);
|
int src_h = cairo_image_surface_get_height (xtext->background_surface);
|
||||||
|
if (src_w > 0 && src_h > 0)
|
||||||
|
{
|
||||||
|
double scale_x = (double)clip_w / (double)src_w;
|
||||||
|
double scale_y = (double)clip_h / (double)src_h;
|
||||||
|
double scale = scale_x < scale_y ? scale_x : scale_y;
|
||||||
|
double draw_w = src_w * scale;
|
||||||
|
double draw_h = src_h * scale;
|
||||||
|
double draw_x = ((double)clip_w - draw_w) / 2.0;
|
||||||
|
double draw_y = ((double)clip_h - draw_h) / 2.0;
|
||||||
|
cairo_set_source_rgb (bg_cr, 0.0, 0.0, 0.0);
|
||||||
|
cairo_paint (bg_cr);
|
||||||
|
cairo_save (bg_cr);
|
||||||
|
cairo_translate (bg_cr, draw_x, draw_y);
|
||||||
|
cairo_scale (bg_cr, scale, scale);
|
||||||
|
cairo_set_source_surface (bg_cr, xtext->background_surface, 0.0, 0.0);
|
||||||
|
cairo_pattern_set_extend (cairo_get_source (bg_cr), CAIRO_EXTEND_NONE);
|
||||||
|
cairo_rectangle (bg_cr, 0.0, 0.0, (double)src_w, (double)src_h);
|
||||||
|
cairo_fill (bg_cr);
|
||||||
|
cairo_restore (bg_cr);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cairo_set_source_surface (bg_cr, xtext->background_surface, tile_x - clip_x, tile_y - clip_y);
|
||||||
|
cairo_pattern_set_extend (cairo_get_source (bg_cr), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle (bg_cr, 0.0, 0.0, (double)clip_w, (double)clip_h);
|
||||||
|
cairo_fill (bg_cr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cairo_set_source_surface (bg_cr, xtext->background_surface, tile_x - clip_x, tile_y - clip_y);
|
||||||
|
cairo_pattern_set_extend (cairo_get_source (bg_cr), CAIRO_EXTEND_REPEAT);
|
||||||
|
cairo_rectangle (bg_cr, 0.0, 0.0, (double)clip_w, (double)clip_h);
|
||||||
|
cairo_fill (bg_cr);
|
||||||
|
}
|
||||||
cairo_destroy (bg_cr);
|
cairo_destroy (bg_cr);
|
||||||
|
|
||||||
xtext->background_clip_x = clip_x;
|
xtext->background_clip_x = clip_x;
|
||||||
|
|||||||
Reference in New Issue
Block a user