mirror of https://github.com/daleclack/My_GtkUi
Add scale for image
This commit is contained in:
parent
3d98cfef6a
commit
c5c130be9f
|
@ -1,41 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <gtkmm.h>
|
|
||||||
#include "MyImage.hh"
|
|
||||||
|
|
||||||
class ImageApp : public Gtk::ApplicationWindow
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
ImageApp();
|
|
||||||
|
|
||||||
private:
|
|
||||||
// Child widgets
|
|
||||||
Gtk::ScrolledWindow sw;
|
|
||||||
MyImage image_area;
|
|
||||||
Gtk::Box main_box, btnbox;
|
|
||||||
Gtk::Button btnopen;
|
|
||||||
Gtk::Scale scale;
|
|
||||||
Gtk::Overlay overlay;
|
|
||||||
Glib::RefPtr<Gtk::Adjustment> m_adjustment, hadjustment, vadjustment;
|
|
||||||
Glib::RefPtr<Gtk::FileChooserNative> dialog;
|
|
||||||
|
|
||||||
// Gesture control
|
|
||||||
Glib::RefPtr<Gtk::GestureDrag> gesture_drag;
|
|
||||||
Glib::RefPtr<Gtk::GestureMultiPress> gesture_click;
|
|
||||||
void drag_begin(double x, double y);
|
|
||||||
void drag_update(double x, double y);
|
|
||||||
void drag_end(double x, double y);
|
|
||||||
void move_to(double x, double y);
|
|
||||||
|
|
||||||
// Menu for image control
|
|
||||||
Gtk::PopoverMenu popover;
|
|
||||||
void press(int n_press, double x, double y);
|
|
||||||
|
|
||||||
// Signal Handlers
|
|
||||||
void btnopen_clicked();
|
|
||||||
void dialog_response(int response_id);
|
|
||||||
void scale_changed();
|
|
||||||
void image_zoom_in();
|
|
||||||
void image_zoom_out();
|
|
||||||
void image_zoom_reset();
|
|
||||||
};
|
|
|
@ -19,6 +19,14 @@ struct _ImageApp
|
||||||
|
|
||||||
G_DEFINE_TYPE(ImageApp, image_app, GTK_TYPE_APPLICATION_WINDOW)
|
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)
|
||||||
|
{
|
||||||
|
my_image_scale_draw(app->image_view, scale_value);
|
||||||
|
gtk_range_set_value(range, scale_value);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
static void image_app_dialog_response(GObject *dialog, GAsyncResult *result, gpointer data)
|
static void image_app_dialog_response(GObject *dialog, GAsyncResult *result, gpointer data)
|
||||||
{
|
{
|
||||||
GFile *file;
|
GFile *file;
|
||||||
|
@ -57,6 +65,7 @@ static void image_app_init(ImageApp *self)
|
||||||
self->image_scale = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0.1, 10.0, 0.1);
|
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");
|
self->btnopen = gtk_button_new_with_label("Open Image");
|
||||||
g_signal_connect(self->btnopen, "clicked", G_CALLBACK(btnopen_clicked), self);
|
g_signal_connect(self->btnopen, "clicked", G_CALLBACK(btnopen_clicked), self);
|
||||||
|
g_signal_connect(self->image_scale, "change-value", G_CALLBACK(image_app_change_scale), self);
|
||||||
|
|
||||||
// Initalize widgets
|
// Initalize widgets
|
||||||
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self->image_sw),
|
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(self->image_sw),
|
||||||
|
|
|
@ -1,79 +0,0 @@
|
||||||
#include "MyImage.hh"
|
|
||||||
|
|
||||||
MyImage::MyImage()
|
|
||||||
: scale_radio(1.0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
MyImage::~MyImage()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
bool MyImage::on_draw(const Cairo::RefPtr<Cairo::Context> &cr)
|
|
||||||
{
|
|
||||||
if (!image)
|
|
||||||
{
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set the default size for drawing area
|
|
||||||
set_size_request(surface->get_width() * scale_radio,
|
|
||||||
surface->get_height() * scale_radio);
|
|
||||||
|
|
||||||
cr->scale(scale_radio, scale_radio);
|
|
||||||
cr->set_source(surface, 0, 0);
|
|
||||||
|
|
||||||
cr->paint();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyImage::scale_draw(double scale)
|
|
||||||
{
|
|
||||||
// Set the scale radio and scale
|
|
||||||
if (scale <= 0)
|
|
||||||
{
|
|
||||||
scale_radio = 0.1;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (scale > 10.0)
|
|
||||||
{
|
|
||||||
scale_radio = 10.0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
scale_radio = scale;
|
|
||||||
queue_draw();
|
|
||||||
}
|
|
||||||
|
|
||||||
void MyImage::set_pixbuf(const Glib::RefPtr<Gdk::Pixbuf> &pixbuf)
|
|
||||||
{
|
|
||||||
if (image)
|
|
||||||
{
|
|
||||||
image.reset();
|
|
||||||
}
|
|
||||||
|
|
||||||
image = pixbuf;
|
|
||||||
|
|
||||||
if (!surface)
|
|
||||||
{
|
|
||||||
// Create a surface
|
|
||||||
surface = Cairo::ImageSurface::create(Cairo::FORMAT_ARGB32,
|
|
||||||
image->get_width(), image->get_height());
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get Image Size
|
|
||||||
int width = image->get_width();
|
|
||||||
int height = image->get_height();
|
|
||||||
// Draw the image in the middle of the surface, or (if the image is
|
|
||||||
// larger than the drawing area) draw the middle part of the image.
|
|
||||||
auto cr = Cairo::Context::create(surface);
|
|
||||||
Gdk::Cairo::set_source_pixbuf(cr, image,
|
|
||||||
(width - image->get_width()) / 2, (height - image->get_height()) / 2);
|
|
||||||
cr->paint();
|
|
||||||
|
|
||||||
// ReDraw the draw area
|
|
||||||
queue_draw();
|
|
||||||
}
|
|
|
@ -25,6 +25,7 @@ static void my_image_draw(GtkDrawingArea *area, cairo_t *cr,
|
||||||
|
|
||||||
// Scale the image and draw
|
// Scale the image and draw
|
||||||
cairo_set_source_surface(cr, image_view->surface, 0, 0);
|
cairo_set_source_surface(cr, image_view->surface, 0, 0);
|
||||||
|
|
||||||
cairo_surface_set_device_scale(image_view->surface,
|
cairo_surface_set_device_scale(image_view->surface,
|
||||||
image_view->scale_radio, image_view->scale_radio);
|
image_view->scale_radio, image_view->scale_radio);
|
||||||
cairo_paint(cr);
|
cairo_paint(cr);
|
||||||
|
@ -81,14 +82,14 @@ void my_image_scale_draw(MyImage *image, double scale)
|
||||||
// Set the scale radio and scale
|
// Set the scale radio and scale
|
||||||
if (scale <= 0)
|
if (scale <= 0)
|
||||||
{
|
{
|
||||||
image->scale_radio = 0.1;
|
image->scale_radio = 10.0;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (scale > 10.0)
|
if (scale > 10.0)
|
||||||
{
|
{
|
||||||
image->scale_radio = 10.0;
|
image->scale_radio = 0.1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
image->scale_radio = scale;
|
image->scale_radio = 1.0 / scale;
|
||||||
gtk_widget_queue_draw(GTK_WIDGET(image));
|
gtk_widget_queue_draw(GTK_WIDGET(image));
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,22 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <gtkmm.h>
|
|
||||||
|
|
||||||
class MyImage : public Gtk::DrawingArea
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
MyImage();
|
|
||||||
virtual ~MyImage();
|
|
||||||
// Set a Pixbuf to draw
|
|
||||||
void set_pixbuf(const Glib::RefPtr<Gdk::Pixbuf> &pixbuf);
|
|
||||||
// Scale the image
|
|
||||||
void scale_draw(double scale);
|
|
||||||
|
|
||||||
protected:
|
|
||||||
bool on_draw(const Cairo::RefPtr<Cairo::Context> &cr) override;
|
|
||||||
|
|
||||||
private:
|
|
||||||
double scale_radio;
|
|
||||||
Cairo::RefPtr<Cairo::ImageSurface> surface;
|
|
||||||
Glib::RefPtr<Gdk::Pixbuf> image;
|
|
||||||
};
|
|
Loading…
Reference in New Issue