Add image Scale for gtk119

This commit is contained in:
daleclack 2021-12-27 23:06:00 +08:00
parent e3bb0b1c45
commit e1d59d5b71
5 changed files with 125 additions and 24 deletions

View File

@ -1,42 +1,69 @@
#include "MyImage.hh"
MyImage::MyImage(){
MyImage::MyImage()
:scale_radio(1.0)
{
}
MyImage::~MyImage(){
MyImage::~MyImage()
{
}
bool MyImage::on_draw(const Cairo::RefPtr<Cairo::Context> &cr){
if(!image){
bool MyImage::on_draw(const Cairo::RefPtr<Cairo::Context> &cr)
{
if (!image)
{
return false;
}
int width = image->get_width();
int height = image->get_height();
// Set the default size for drawing area
set_size_request(width,height);
set_size_request(surface->get_width()*scale_radio,
surface->get_height()*scale_radio);
// Draw the image in the middle of the drawing area, or (if the image is
// larger than the drawing area) draw the middle part of the image.
Gdk::Cairo::set_source_pixbuf(cr, image,
(width - image->get_width())/2, (height - image->get_height())/2);
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
scale_radio = scale;
queue_draw();
}
void MyImage::set_pixbuf(const Glib::RefPtr<Gdk::Pixbuf> &pixbuf)
{
if(image){
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();
}

View File

@ -6,8 +6,14 @@ 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;
};

View File

@ -18,6 +18,7 @@ btnopen("Open Image")
m_adjustment = Gtk::Adjustment::create(1.0,0.1,10.0,0.1,0.1);
scale.set_default_direction(Gtk::TEXT_DIR_LTR);
scale.set_adjustment(m_adjustment);
scale.signal_value_changed().connect(sigc::mem_fun(*this,&MyWin::scale_changed));
//Add control widgets
btnbox.pack_start(scale);
@ -50,3 +51,9 @@ void MyWin::dialog_response(int response_id){
dialog.reset();
}
void MyWin::scale_changed(){
double value = scale.get_value();
g_print("%f\n",value);
image_area.scale_draw(value);
}

View File

@ -21,4 +21,5 @@ class MyWin : public Gtk::Window{
//Signal Handlers
void btnopen_clicked();
void dialog_response(int response_id);
void scale_changed();
};

60
cairo_scale.py Normal file
View File

@ -0,0 +1,60 @@
#!/usr/bin/python3
import cairo
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
def draw(da, ctx):
global surface
ctx.scale(scale, scale)
ctx.set_source_surface(surface)
ctx.get_source().set_filter(cairo.FILTER_NEAREST)
ctx.paint()
da.set_size_request(surface.get_width() * scale, surface.get_height() * scale)
def clicked(btn):
global scale
scale *= 1.5
da = btn.get_parent().get_children()[1].get_child().get_child()
da.queue_draw()
def main():
global scale
scale = 1
global surface
surface = cairo.ImageSurface.create_from_png("../Xe-Project/Gift.png")
win = Gtk.Window()
win.connect('destroy', lambda w: Gtk.main_quit())
win.set_default_size(500, 500)
box = Gtk.Box()
win.add(box)
btn = Gtk.Button()
btn.set_label("Scale")
box.add(btn)
btn.connect('clicked', clicked)
scrolled_win = Gtk.ScrolledWindow()
box.add(scrolled_win)
drawingarea = Gtk.DrawingArea()
drawingarea.set_vexpand(True)
drawingarea.set_hexpand(True)
scrolled_win.add(drawingarea)
drawingarea.connect('draw', draw)
win.show_all()
Gtk.main()
if __name__ == '__main__':
main()