From 810acc167302662e508d50963b08986fdfb98eeb Mon Sep 17 00:00:00 2001 From: Ivan Mahonin Date: Aug 25 2018 05:40:37 +0000 Subject: Checkered background for thumbs --- diff --git a/synfig-studio/src/gui/widgets/widget_canvastimeslider.cpp b/synfig-studio/src/gui/widgets/widget_canvastimeslider.cpp index a95cfda..8cc8a2d 100644 --- a/synfig-studio/src/gui/widgets/widget_canvastimeslider.cpp +++ b/synfig-studio/src/gui/widgets/widget_canvastimeslider.cpp @@ -63,6 +63,7 @@ using namespace studio; Widget_CanvasTimeslider::Widget_CanvasTimeslider(): tooltip(Gtk::WINDOW_POPUP) { + thumb.signal_draw().connect(sigc::mem_fun(*this, &Widget_CanvasTimeslider::draw_thumb)); thumb.show(); tooltip.set_type_hint(Gdk::WINDOW_TYPE_HINT_TOOLTIP); @@ -93,6 +94,10 @@ Widget_CanvasTimeslider::set_canvas_view(const CanvasView::LooseHandle &x) void Widget_CanvasTimeslider::show_tooltip(const synfig::Point &p, const synfig::Point &root) { + thumb_background.clear(); + thumb_surface.clear(); + + Cairo::RefPtr pattern; Cairo::RefPtr surface; if ( get_width() && adj_timescale @@ -110,11 +115,11 @@ Widget_CanvasTimeslider::show_tooltip(const synfig::Point &p, const synfig::Poin synfig::Time time(x/w*(end - start) + start); time = time.round(fps); surface = canvas_view->get_work_area()->get_renderer_canvas()->get_thumb(time); + pattern = canvas_view->get_work_area()->get_background_pattern(); } } - thumb.set(surface); - if (surface && get_screen() && get_width() > 0) { + if (pattern && surface && get_screen() && get_width() > 0) { const int space = 20; int tooltip_w = surface->get_width(); int tooltip_h = surface->get_height(); @@ -142,6 +147,10 @@ Widget_CanvasTimeslider::show_tooltip(const synfig::Point &p, const synfig::Poin } if (visible) { + thumb_background = pattern; + thumb_surface = surface; + thumb.set_size_request(thumb_surface->get_width(), thumb_surface->get_height()); + thumb.queue_draw(); tooltip.set_screen(get_screen()); tooltip.move(x, y); tooltip.show(); @@ -188,6 +197,25 @@ Widget_CanvasTimeslider::on_leave_notify_event(GdkEventCrossing*) return true; } +bool +Widget_CanvasTimeslider::draw_thumb(const Cairo::RefPtr &cr) +{ + if (!thumb_background || !thumb_surface) + return false; + + cr->save(); + cr->translate(tooltip.get_width()/2, tooltip.get_height()/2); + cr->set_source(thumb_background); + cr->paint(); + cr->restore(); + + cr->save(); + cr->set_source(thumb_surface, 0, 0); + cr->paint(); + cr->restore(); + + return true; +} void Widget_CanvasTimeslider::draw_background(const Cairo::RefPtr &cr) diff --git a/synfig-studio/src/gui/widgets/widget_canvastimeslider.h b/synfig-studio/src/gui/widgets/widget_canvastimeslider.h index e7c4776..9873955 100644 --- a/synfig-studio/src/gui/widgets/widget_canvastimeslider.h +++ b/synfig-studio/src/gui/widgets/widget_canvastimeslider.h @@ -27,7 +27,7 @@ /* === H E A D E R S ======================================================= */ -#include +#include #include "widget_timeslider.h" @@ -49,10 +49,13 @@ protected: etl::loose_handle canvas_view; etl::handle lock_ducks; Gtk::Window tooltip; - Gtk::Image thumb; + Gtk::DrawingArea thumb; + Cairo::RefPtr thumb_background; + Cairo::RefPtr thumb_surface; virtual void draw_background(const Cairo::RefPtr &cr); + bool draw_thumb(const Cairo::RefPtr &cr); void show_tooltip(const synfig::Point &p, const synfig::Point &root); virtual bool on_motion_notify_event(GdkEventMotion* event); diff --git a/synfig-studio/src/gui/workarea.cpp b/synfig-studio/src/gui/workarea.cpp index 9fa1471..a502a91 100644 --- a/synfig-studio/src/gui/workarea.cpp +++ b/synfig-studio/src/gui/workarea.cpp @@ -854,36 +854,56 @@ WorkArea::set_grid_color(const synfig::Color &c) void WorkArea::set_background_size(const synfig::Vector &s) { - if (background_size != s) - { - background_size = s; - save_meta_data(); - } + if (background_size == s) return; + background_size = s; + background_pattern.clear(); + save_meta_data(); queue_draw(); } void WorkArea::set_background_first_color(const synfig::Color &c) { - if(background_first_color != c) - { - background_first_color = c; - save_meta_data(); - } + if (background_first_color == c) return; + background_first_color = c; + background_pattern.clear(); + save_meta_data(); queue_draw(); } void WorkArea::set_background_second_color(const synfig::Color &c) { - if(background_second_color != c) - { - background_second_color = c; - save_meta_data(); - } + if (background_second_color == c) return; + background_second_color = c; + background_pattern.clear(); + save_meta_data(); queue_draw(); } +const Cairo::RefPtr& +WorkArea::get_background_pattern() const +{ + if (!background_pattern) { + int w = std::max(1, std::min(1000, (int)round(background_size[0]))); + int h = std::max(1, std::min(1000, (int)round(background_size[1]))); + Cairo::RefPtr surface = Cairo::ImageSurface::create(Cairo::FORMAT_RGB24, w*2, h*2); + Cairo::RefPtr context = Cairo::Context::create(surface); + context->set_source_rgb(background_first_color.get_r(), background_first_color.get_g(), background_first_color.get_b()); + context->paint(); + context->set_source_rgb(background_second_color.get_r(), background_second_color.get_g(), background_second_color.get_b()); + context->rectangle(w, 0, w, h); + context->rectangle(0, h, w, h); + context->fill(); + surface->flush(); + + background_pattern = Cairo::SurfacePattern::create(surface); + background_pattern->set_filter(Cairo::FILTER_NEAREST); + background_pattern->set_extend(Cairo::EXTEND_REPEAT); + } + return background_pattern; +} + void WorkArea::set_focus_point(const synfig::Point &point) { diff --git a/synfig-studio/src/gui/workarea.h b/synfig-studio/src/gui/workarea.h index 5553244..9898558 100644 --- a/synfig-studio/src/gui/workarea.h +++ b/synfig-studio/src/gui/workarea.h @@ -195,6 +195,8 @@ private: synfig::Color background_first_color; //! Checker background second color synfig::Color background_second_color; + //! Checker background pattern (will generated by first request) + mutable Cairo::RefPtr background_pattern; synfig::Time jack_offset; @@ -374,11 +376,13 @@ public: //! Sets the second color of the checker background void set_background_second_color(const synfig::Color &c); //! Sets the size of the checker background - const synfig::Vector &get_background_size()const { return background_size;} + const synfig::Vector& get_background_size() const { return background_size;} //! Returns the first color of the checker background - const synfig::Color &get_background_first_color()const { return background_first_color;} + const synfig::Color& get_background_first_color() const { return background_first_color;} //! Returns the second color of the checker background - const synfig::Color &get_background_second_color()const { return background_second_color;} + const synfig::Color& get_background_second_color() const { return background_second_color;} + //! Returns the Cairo Pattern for background + const Cairo::RefPtr& get_background_pattern() const; bool get_low_resolution_flag()const { return low_resolution; } void set_low_resolution_flag(bool x); diff --git a/synfig-studio/src/gui/workarearenderer/renderer_background.cpp b/synfig-studio/src/gui/workarearenderer/renderer_background.cpp index 3d36f75..b1096a2 100644 --- a/synfig-studio/src/gui/workarearenderer/renderer_background.cpp +++ b/synfig-studio/src/gui/workarearenderer/renderer_background.cpp @@ -56,20 +56,16 @@ using namespace studio; /* === M E T H O D S ======================================================= */ Renderer_Background::~Renderer_Background() -{ -} + { } bool Renderer_Background::get_enabled_vfunc()const -{ - return true; -} + { return true; } void Renderer_Background::render_vfunc( - const Glib::RefPtr& drawable, - const Gdk::Rectangle& /*expose_area*/ - ) + const Glib::RefPtr& drawable, + const Gdk::Rectangle& /*expose_area*/ ) { assert(get_work_area()); if(!get_work_area()) @@ -80,42 +76,10 @@ Renderer_Background::render_vfunc( int h=get_h(); Cairo::RefPtr cr = drawable->create_cairo_context(); - - synfig::Vector grid_size(get_work_area()->get_background_size()); - Cairo::RefPtr surface_background = draw_check_pattern(grid_size[0], grid_size[1]); - cr->save(); - - cr->set_source(surface_background, offset[0] + w/2, offset[1] - h/2); - - Cairo::RefPtr sp_ptr = Cairo::SurfacePattern::create(surface_background); - sp_ptr->set_filter(Cairo::FILTER_NEAREST); - sp_ptr->set_extend(Cairo::EXTEND_REPEAT); - - cr->set_source(sp_ptr); - + cr->set_source(get_work_area()->get_background_pattern()); cr->rectangle(offset[0], offset[1], w, h); cr->clip(); cr->paint(); - cr->restore(); } - -Cairo::RefPtr -Renderer_Background::draw_check_pattern(int width, int height) -{ - Cairo::RefPtr surface_ptr = Cairo::ImageSurface::create (Cairo::FORMAT_RGB24, width*2, height*2); - Cairo::RefPtr cr_ptr = Cairo::Context::create (surface_ptr); - - synfig::Color first_color(get_work_area()->get_background_first_color()); - cr_ptr->set_source_rgb(first_color.get_r(), first_color.get_g(), first_color.get_b()); - cr_ptr->paint(); - - synfig::Color second_color(get_work_area()->get_background_second_color()); - cr_ptr->set_source_rgb(second_color.get_r(), second_color.get_g(), second_color.get_b()); - cr_ptr->rectangle(int(width), 0 , width, height); - cr_ptr->rectangle(0, int(height), width , height); - cr_ptr->fill(); - - return surface_ptr; -} diff --git a/synfig-studio/src/gui/workarearenderer/renderer_background.h b/synfig-studio/src/gui/workarearenderer/renderer_background.h index c027ccf..5801570 100644 --- a/synfig-studio/src/gui/workarearenderer/renderer_background.h +++ b/synfig-studio/src/gui/workarearenderer/renderer_background.h @@ -40,16 +40,12 @@ namespace studio { class Renderer_Background : public studio::WorkAreaRenderer { -private: - Cairo::RefPtr draw_check_pattern(int width, int height); +protected: + bool get_enabled_vfunc()const; public: ~Renderer_Background(); - void render_vfunc(const Glib::RefPtr& drawable,const Gdk::Rectangle& expose_area ); - -protected: - bool get_enabled_vfunc()const; }; }; // END of namespace studio