mirror of https://github.com/daleclack/My_GtkUi
Add scaling for image viewer
This commit is contained in:
parent
c5c130be9f
commit
5cb35ec046
|
@ -3,15 +3,16 @@
|
|||
|
||||
struct _ImageApp
|
||||
{
|
||||
GtkWindow parent_instance;
|
||||
GtkApplicationWindow parent_instance;
|
||||
// Child widgets
|
||||
GtkWidget *main_box, *btn_box;
|
||||
GtkWidget *image_sw;
|
||||
GtkWidget *image_scale, *btnopen;
|
||||
|
||||
// Context Menu
|
||||
GtkGesture *gesture;
|
||||
GtkPopoverMenu *image_menu;
|
||||
GtkGesture *gesture_click, *gesture_drag;
|
||||
GtkBuilder *builder;
|
||||
GtkWidget *image_menu;
|
||||
|
||||
// Main Image View
|
||||
MyImage *image_view;
|
||||
|
@ -20,13 +21,71 @@ struct _ImageApp
|
|||
G_DEFINE_TYPE(ImageApp, image_app, GTK_TYPE_APPLICATION_WINDOW)
|
||||
|
||||
static gboolean image_app_change_scale(GtkRange *range, GtkScrollType *scroll,
|
||||
double scale_value, ImageApp *app)
|
||||
double scale_value, ImageApp *app)
|
||||
{
|
||||
my_image_scale_draw(app->image_view, scale_value);
|
||||
gtk_range_set_value(range, scale_value);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static void image_app_zoom_in(GSimpleAction *action,
|
||||
GVariant *parmeter,
|
||||
gpointer data)
|
||||
{
|
||||
// Zoom in: Scale + 0.1
|
||||
ImageApp *app = IMAGE_APP(data);
|
||||
double value = gtk_range_get_value(GTK_RANGE(app->image_scale));
|
||||
value += 0.1;
|
||||
if (value > 10.0)
|
||||
{
|
||||
value = 10.0;
|
||||
}
|
||||
gtk_range_set_value(GTK_RANGE(app->image_scale), value);
|
||||
image_app_change_scale(GTK_RANGE(app->image_scale), NULL, value, app);
|
||||
}
|
||||
|
||||
static void image_app_zoom_out(GSimpleAction *action,
|
||||
GVariant *parmeter,
|
||||
gpointer data)
|
||||
{
|
||||
// Zoom Out: Scale - 0.1
|
||||
ImageApp *app = IMAGE_APP(data);
|
||||
double value = gtk_range_get_value(GTK_RANGE(app->image_scale));
|
||||
value -= 0.1;
|
||||
if (value < 0.0)
|
||||
{
|
||||
value = 0.0;
|
||||
}
|
||||
gtk_range_set_value(GTK_RANGE(app->image_scale), value);
|
||||
image_app_change_scale(GTK_RANGE(app->image_scale), NULL, value, app);
|
||||
}
|
||||
|
||||
static void image_app_zoom_reset(GSimpleAction *action,
|
||||
GVariant *parmeter,
|
||||
gpointer data)
|
||||
{
|
||||
// 1:1 Scale=1
|
||||
ImageApp *app = IMAGE_APP(data);
|
||||
gtk_range_set_value(GTK_RANGE(app->image_scale), 1.0);
|
||||
image_app_change_scale(GTK_RANGE(app->image_scale), NULL, 1.0, app);
|
||||
}
|
||||
|
||||
static void gesture_pressed(GtkGesture *gesture,
|
||||
int n_press,
|
||||
double x,
|
||||
double y,
|
||||
ImageApp *app)
|
||||
{
|
||||
GdkRectangle pos;
|
||||
pos.height = 1;
|
||||
pos.width = 1;
|
||||
pos.x = x;
|
||||
pos.y = y;
|
||||
// Set popover position and show
|
||||
gtk_popover_set_pointing_to(GTK_POPOVER(app->image_menu), &pos);
|
||||
gtk_popover_popup(GTK_POPOVER(app->image_menu));
|
||||
}
|
||||
|
||||
static void image_app_dialog_response(GObject *dialog, GAsyncResult *result, gpointer data)
|
||||
{
|
||||
GFile *file;
|
||||
|
@ -57,6 +116,16 @@ static void image_app_init(ImageApp *self)
|
|||
gtk_window_set_default_size(GTK_WINDOW(self), 800, 450);
|
||||
gtk_window_set_icon_name(GTK_WINDOW(self), "image_app");
|
||||
|
||||
// Add action for menu
|
||||
GActionEntry entries[] =
|
||||
{
|
||||
{"zoom_out", image_app_zoom_out, NULL, NULL, NULL},
|
||||
{"zoom_in", image_app_zoom_in, NULL, NULL, NULL},
|
||||
{"zoom_reset", image_app_zoom_reset, NULL, NULL, NULL},
|
||||
};
|
||||
g_action_map_add_action_entries(G_ACTION_MAP(self), entries,
|
||||
G_N_ELEMENTS(entries), self);
|
||||
|
||||
// Create child widgets
|
||||
self->main_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
|
||||
self->btn_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
|
||||
|
@ -77,6 +146,20 @@ static void image_app_init(ImageApp *self)
|
|||
gtk_scale_set_draw_value(GTK_SCALE(self->image_scale), TRUE);
|
||||
gtk_scale_set_value_pos(GTK_SCALE(self->image_scale), GTK_POS_LEFT);
|
||||
|
||||
// Add gesture for context menu
|
||||
self->gesture_click = gtk_gesture_click_new();
|
||||
gtk_gesture_single_set_button(GTK_GESTURE_SINGLE(self->gesture_click), GDK_BUTTON_SECONDARY);
|
||||
gtk_widget_add_controller(GTK_WIDGET(self->image_view), GTK_EVENT_CONTROLLER(self->gesture_click));
|
||||
g_signal_connect(self->gesture_click, "pressed", G_CALLBACK(gesture_pressed), self);
|
||||
|
||||
// Add a menu
|
||||
self->builder = gtk_builder_new_from_resource("/org/gtk/daleclack/image_appmenu.xml");
|
||||
GMenuModel *model = G_MENU_MODEL(gtk_builder_get_object(self->builder, "model"));
|
||||
self->image_menu = gtk_popover_menu_new_from_model(model);
|
||||
gtk_popover_set_has_arrow(GTK_POPOVER(self->image_menu), FALSE);
|
||||
gtk_widget_set_parent(self->image_menu, GTK_WIDGET(self->image_view));
|
||||
gtk_popover_present(GTK_POPOVER(self->image_menu));
|
||||
|
||||
// Pack Widgets
|
||||
gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(self->image_sw), GTK_WIDGET(self->image_view));
|
||||
gtk_box_append(GTK_BOX(self->main_box), self->image_sw);
|
||||
|
|
|
@ -20,12 +20,16 @@ static void my_image_draw(GtkDrawingArea *area, cairo_t *cr,
|
|||
return;
|
||||
}
|
||||
|
||||
width = gdk_pixbuf_get_width(image_view->pixbuf) / (image_view->scale_radio);
|
||||
height = gdk_pixbuf_get_height(image_view->pixbuf) / (image_view->scale_radio);
|
||||
// Get width and height for drawing area
|
||||
gtk_widget_set_size_request(GTK_WIDGET(area), width, height);
|
||||
gtk_drawing_area_set_content_width(GTK_DRAWING_AREA(data), width);
|
||||
gtk_drawing_area_set_content_height(GTK_DRAWING_AREA(data), height);
|
||||
|
||||
// Scale the image and draw
|
||||
cairo_set_source_surface(cr, image_view->surface, 0, 0);
|
||||
|
||||
|
||||
cairo_surface_set_device_scale(image_view->surface,
|
||||
image_view->scale_radio, image_view->scale_radio);
|
||||
cairo_paint(cr);
|
||||
|
@ -68,8 +72,6 @@ void my_image_set_source_pixbuf(MyImage *image, GdkPixbuf *pixbuf)
|
|||
{
|
||||
image->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, width, height);
|
||||
}
|
||||
gtk_drawing_area_set_content_width(GTK_DRAWING_AREA(image), width);
|
||||
gtk_drawing_area_set_content_height(GTK_DRAWING_AREA(image), height);
|
||||
|
||||
cairo_t *cr = cairo_create(image->surface);
|
||||
gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
|
||||
|
|
Loading…
Reference in New Issue