Add image widget for Image Viewer

This commit is contained in:
daleclack 2024-02-19 16:30:20 +08:00
parent c7b72c3b65
commit 54c798dfdb
3 changed files with 107 additions and 3 deletions

View File

@ -1,14 +1,40 @@
#include "ImageApp.h"
#include "MyImage.h"
struct _ImageApp{
GtkWindow parent_instance;
// Child widgets
GtkWidget *main_box, *btn_box;
GtkWidget *image_sw;
GtkWidget *image_scale, *btnopen;
// Context Menu
GtkGesture *gesture;
GtkPopoverMenu *image_menu;
// Main Image View
MyImage *image_view;
};
G_DEFINE_TYPE(ImageApp, image_app, GTK_TYPE_APPLICATION_WINDOW)
static void image_app_init(ImageApp *self)
{
// Initalize window
gtk_window_set_title(GTK_WINDOW(self), "Image Viewer");
gtk_window_set_default_size(GTK_WINDOW(self), 800, 450);
gtk_window_set_icon_name(GTK_WINDOW(self), "image_app");
// Create child widgets
self->main_box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 5);
self->btn_box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
self->image_view = my_image_new();
self->image_sw = gtk_scrolled_window_new();
self->image_scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0.1, 10.0, 0.1);
self->btnopen = gtk_button_new_with_label("Open Image");
// Initalize widgets
}
static void image_app_class_init(ImageAppClass *klass)

View File

@ -1,18 +1,90 @@
#include "MyImage.h"
struct _MyImage{
struct _MyImage
{
GtkDrawingArea parent_instance;
cairo_surface_t *surface;
GdkPixbuf *pixbuf;
double scale_radio;
};
G_DEFINE_TYPE(MyImage, my_image, GTK_TYPE_DRAWING_AREA)
static void my_image_draw(GtkDrawingArea *area, cairo_t *cr,
int width, int height, gpointer data)
{
MyImage *image_view = MY_IMAGE(data);
if (!image_view->pixbuf)
{
return;
}
// Get width and height for drawing area
gtk_widget_set_size_request(GTK_WIDGET(area), width, height);
// Scale the image and draw
cairo_surface_set_device_scale(image_view->surface,
image_view->scale_radio, image_view->scale_radio);
cairo_paint(cr);
}
static void my_image_init(MyImage *self)
{
self->scale_radio = 1.0;
gtk_widget_set_hexpand(GTK_WIDGET(self), TRUE);
gtk_widget_set_vexpand(GTK_WIDGET(self), TRUE);
gtk_drawing_area_set_draw_func(GTK_DRAWING_AREA(self), my_image_draw, self, NULL);
}
static void my_image_class_init(MyImageClass *klass)
{
}
}
MyImage *my_image_new()
{
return MY_IMAGE(g_object_new(my_image_get_type(), NULL));
}
void my_image_set_source_pixbuf(MyImage *image, GdkPixbuf *pixbuf)
{
if (!pixbuf)
{
return;
}
if (image->pixbuf)
{
g_object_unref(image->pixbuf);
}
image->pixbuf = pixbuf;
if (!image->surface)
{
image->surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
gdk_pixbuf_get_width(pixbuf),
gdk_pixbuf_get_height(pixbuf));
}
cairo_t *cr = cairo_create(image->surface);
gdk_cairo_set_source_pixbuf(cr, pixbuf, 0, 0);
cairo_paint(cr);
gtk_widget_queue_draw(GTK_WIDGET(image));
}
void my_image_scale_draw(MyImage *image, double scale)
{
// Set the scale radio and scale
if (scale <= 0)
{
image->scale_radio = 0.1;
return;
}
if (scale > 10.0)
{
image->scale_radio = 10.0;
return;
}
image->scale_radio = scale;
gtk_widget_queue_draw(GTK_WIDGET(image));
}

View File

@ -3,3 +3,9 @@
#include <gtk/gtk.h>
G_DECLARE_FINAL_TYPE(MyImage, my_image, MY, IMAGE, GtkDrawingArea)
MyImage *my_image_new();
void my_image_set_source_pixbuf(MyImage *image, GdkPixbuf *pixbuf);
void my_image_scale_draw(MyImage *image, double scale);