/* * Remmina - The GTK+ Remote Desktop Client * Copyright (C) 2009 - Vic Lee * * 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. */ #include #include #include "remminachainbutton.h" #include "remminascaler.h" G_DEFINE_TYPE (RemminaScaler, remmina_scaler, GTK_TYPE_TABLE) #define MIN_SCALE_VALUE 0.05 struct _RemminaScalerPriv { GtkWidget *hscale_widget; GtkWidget *vscale_widget; GtkWidget *aspectscale_button; }; enum { SCALED_SIGNAL, LAST_SIGNAL }; static guint remmina_scaler_signals[LAST_SIGNAL] = { 0 }; static void remmina_scaler_class_init (RemminaScalerClass *klass) { remmina_scaler_signals[SCALED_SIGNAL] = g_signal_new ("scaled", G_TYPE_FROM_CLASS (klass), G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION, G_STRUCT_OFFSET (RemminaScalerClass, scaled), NULL, NULL, g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0); } static gchar* remmina_scaler_format_scale_value (GtkScale *scale, gdouble value, gpointer user_data) { if (value <= MIN_SCALE_VALUE) { return g_strdup (_("Fit window size")); } else { return g_strdup_printf ("%.2f", value); } } static void remmina_scaler_on_chain_changed (RemminaChainButton *cb, RemminaScaler *scaler) { scaler->aspectscale = cb->chained; if (cb->chained) { gtk_range_set_value (GTK_RANGE (scaler->priv->vscale_widget), gtk_range_get_value (GTK_RANGE (scaler->priv->hscale_widget))); } g_signal_emit (G_OBJECT (scaler), remmina_scaler_signals[SCALED_SIGNAL], 0); } static void remmina_scaler_on_hscale_value_changed (GtkWidget *widget, RemminaScaler *scaler) { gdouble value; value = gtk_range_get_value (GTK_RANGE (scaler->priv->hscale_widget)); scaler->hscale = (value <= MIN_SCALE_VALUE ? 0 : (gint) (value * 100.0)); if (REMMINA_CHAIN_BUTTON (scaler->priv->aspectscale_button)->chained && gtk_range_get_value (GTK_RANGE (scaler->priv->hscale_widget)) != gtk_range_get_value (GTK_RANGE (scaler->priv->vscale_widget))) { gtk_range_set_value (GTK_RANGE (scaler->priv->vscale_widget), gtk_range_get_value (GTK_RANGE (scaler->priv->hscale_widget))); } g_signal_emit (G_OBJECT (scaler), remmina_scaler_signals[SCALED_SIGNAL], 0); } static void remmina_scaler_on_vscale_value_changed (GtkWidget *widget, RemminaScaler *scaler) { gdouble value; value = gtk_range_get_value (GTK_RANGE (scaler->priv->vscale_widget)); scaler->vscale = (value <= MIN_SCALE_VALUE ? 0 : (gint) (value * 100.0)); if (REMMINA_CHAIN_BUTTON (scaler->priv->aspectscale_button)->chained && gtk_range_get_value (GTK_RANGE (scaler->priv->hscale_widget)) != gtk_range_get_value (GTK_RANGE (scaler->priv->vscale_widget))) { gtk_range_set_value (GTK_RANGE (scaler->priv->hscale_widget), gtk_range_get_value (GTK_RANGE (scaler->priv->vscale_widget))); } g_signal_emit (G_OBJECT (scaler), remmina_scaler_signals[SCALED_SIGNAL], 0); } static void remmina_scaler_destroy (RemminaScaler *scaler, gpointer data) { g_free (scaler->priv); } static void remmina_scaler_init (RemminaScaler *scaler) { RemminaScalerPriv *priv; GtkWidget *widget; priv = g_new (RemminaScalerPriv, 1); scaler->priv = priv; scaler->hscale = 0; scaler->vscale = 0; scaler->aspectscale = FALSE; gtk_table_resize (GTK_TABLE (scaler), 2, 2); widget = gtk_hscale_new_with_range (MIN_SCALE_VALUE, 1.0, 0.01); gtk_widget_show (widget); gtk_widget_set_tooltip_text (widget, _("Horizontal scale")); gtk_table_attach_defaults (GTK_TABLE (scaler), widget, 1, 2, 0, 1); g_signal_connect (G_OBJECT (widget), "format-value", G_CALLBACK (remmina_scaler_format_scale_value), NULL); priv->hscale_widget = widget; widget = gtk_hscale_new_with_range (MIN_SCALE_VALUE, 1.0, 0.01); gtk_widget_show (widget); gtk_widget_set_tooltip_text (widget, _("Vertical scale")); gtk_table_attach_defaults (GTK_TABLE (scaler), widget, 1, 2, 1, 2); g_signal_connect (G_OBJECT (widget), "format-value", G_CALLBACK (remmina_scaler_format_scale_value), NULL); priv->vscale_widget = widget; g_signal_connect (G_OBJECT (priv->hscale_widget), "value-changed", G_CALLBACK (remmina_scaler_on_hscale_value_changed), scaler); g_signal_connect (G_OBJECT (priv->vscale_widget), "value-changed", G_CALLBACK (remmina_scaler_on_vscale_value_changed), scaler); widget = remmina_chain_button_new (); gtk_widget_show (widget); gtk_table_attach (GTK_TABLE (scaler), widget, 2, 3, 0, 2, 0, 0, 0, 0); g_signal_connect (G_OBJECT (widget), "chain-toggled", G_CALLBACK (remmina_scaler_on_chain_changed), scaler); priv->aspectscale_button = widget; g_signal_connect (G_OBJECT (scaler), "destroy", G_CALLBACK (remmina_scaler_destroy), NULL); } GtkWidget* remmina_scaler_new (void) { return GTK_WIDGET (g_object_new (REMMINA_TYPE_SCALER, NULL)); } void remmina_scaler_set (RemminaScaler *scaler, gint hscale, gint vscale, gboolean chained) { gtk_range_set_value (GTK_RANGE (scaler->priv->hscale_widget), ((gdouble) hscale) / 100.0); gtk_range_set_value (GTK_RANGE (scaler->priv->vscale_widget), ((gdouble) vscale) / 100.0); remmina_chain_button_set (REMMINA_CHAIN_BUTTON (scaler->priv->aspectscale_button), chained); } void remmina_scaler_set_draw_value (RemminaScaler *scaler, gboolean draw_value) { gtk_scale_set_draw_value (GTK_SCALE (scaler->priv->hscale_widget), draw_value); gtk_scale_set_draw_value (GTK_SCALE (scaler->priv->vscale_widget), draw_value); }