[gparted] modern-gtk2: Use Cairo for drawing the partition resizer (!17)



commit d17d1290445646fac57284d96501912e7898ec52
Author: Luca Bacci <luca bacci982 gmail com>
Date:   Thu Aug 2 18:10:11 2018 +0200

    modern-gtk2: Use Cairo for drawing the partition resizer (!17)
    
    GdkGC has been deprecated in the underlying C / GTK+ 2.22 library.  It
    is less clearly stated but Gdk::GC is also deprecated in C++ / gtkmm.
    Cairo based rendering should be used instead.
    https://developer.gnome.org/gtk3/stable/gtk-migrating-2-to-3.html
    https://gitlab.gnome.org/GNOME/gtk/blob/2.22.0/NEWS#L124
    https://developer.gnome.org/gtkmm/2.24/classGdk_1_1GC.html
    
    First commit in a series to convert Gdk::GC based drawing to Cairo based
    drawing.  This specific commit makes the transition for the graphical
    partition resizing widget that is used in the "Create New Partition",
    "Paste" creating new partition and "Resize/Move" dialogs.
    
    Cairo is not pixel based but instead uses a continuous coordinate space.
    To draw in a pixel aligned way follow the guidance in the Cairo FAQ.
    https://www.cairographics.org/FAQ/#sharp_lines
    
    Additional references:
    https://developer.gnome.org/gdk2/stable/gdk2-Drawing-Primitives.html#gdk-draw-line
    https://developer.gnome.org/gdk2/stable/gdk2-Drawing-Primitives.html#gdk-draw-rectangle
    
    Closes !17 - Gtk2 modernisation

 include/Frame_Resizer_Base.h     |  11 ++-
 include/Frame_Resizer_Extended.h |   2 +-
 src/Dialog_Base_Partition.cc     |   6 +-
 src/Dialog_Partition_New.cc      |   2 +-
 src/Frame_Resizer_Base.cc        | 163 +++++++++++++++++++++------------------
 src/Frame_Resizer_Extended.cc    |  60 +++++++-------
 6 files changed, 132 insertions(+), 112 deletions(-)
---
diff --git a/include/Frame_Resizer_Base.h b/include/Frame_Resizer_Base.h
index 0e61d67a..50c65890 100644
--- a/include/Frame_Resizer_Base.h
+++ b/include/Frame_Resizer_Base.h
@@ -47,7 +47,9 @@ public:
        int get_x_start() ;
        int get_x_end() ;
 
-       virtual void Draw_Partition() ;
+       virtual void draw_partition(const Cairo::RefPtr<Cairo::Context>& cr);
+
+       void redraw();
 
        //public signals  (emitted upon resize/move)
        sigc::signal<void,int,int, ArrowType> signal_resize;
@@ -66,13 +68,10 @@ protected:
        bool drawingarea_on_button_press_event( GdkEventButton * ev ) ;
        bool drawingarea_on_button_release_event( GdkEventButton * ev ) ;
        bool drawingarea_on_leave_notify( GdkEventCrossing * ev ) ;
-               
-       void Draw_Resize_Grip( ArrowType ) ;
+
+       void draw_resize_grip(const Cairo::RefPtr<Cairo::Context>& cr, ArrowType);
 
        Gtk::DrawingArea drawingarea ;
-       Glib::RefPtr<Gdk::GC> gc_drawingarea ;
-       Glib::RefPtr<Gdk::Pixmap> pixmap ;
-       Glib::RefPtr<Gdk::GC> gc_pixmap ;
 
        Gdk::Color color_used, color_unused, color_arrow, color_background, color_partition, 
color_arrow_rectangle;
 
diff --git a/include/Frame_Resizer_Extended.h b/include/Frame_Resizer_Extended.h
index 96f67ec8..8d148c05 100644
--- a/include/Frame_Resizer_Extended.h
+++ b/include/Frame_Resizer_Extended.h
@@ -33,7 +33,7 @@ private:
        //overridden signal handler
        virtual bool drawingarea_on_mouse_motion( GdkEventMotion * ev ) ;
 
-       virtual void Draw_Partition() ;
+       virtual void draw_partition(const Cairo::RefPtr<Cairo::Context>& cr);
 };
 
 #endif /* GPARTED_FRAME_RESIZER_EXTENDED_H */
diff --git a/src/Dialog_Base_Partition.cc b/src/Dialog_Base_Partition.cc
index eeea927f..65a70699 100644
--- a/src/Dialog_Base_Partition.cc
+++ b/src/Dialog_Base_Partition.cc
@@ -372,9 +372,9 @@ void Dialog_Base_Partition::on_spinbutton_value_changed( SPINBUTTON spinbutton )
                        frame_resizer_base ->set_x_start( Utils::round( spinbutton_before .get_value() / 
MB_PER_PIXEL ) ) ;
                
                frame_resizer_base ->set_x_end( 500 - Utils::round( spinbutton_after .get_value() / 
MB_PER_PIXEL ) ) ;
-               
-               frame_resizer_base ->Draw_Partition() ;
-               
+
+               frame_resizer_base->redraw();
+
                Check_Change() ;
        }
 }
diff --git a/src/Dialog_Partition_New.cc b/src/Dialog_Partition_New.cc
index 84ffa582..a97ad244 100644
--- a/src/Dialog_Partition_New.cc
+++ b/src/Dialog_Partition_New.cc
@@ -382,7 +382,7 @@ void Dialog_Partition_New::combobox_changed(bool type)
        // Maximum length of the file system label varies according to the selected file system type.
        filesystem_label_entry.set_max_length( Utils::get_filesystem_label_maxlength( fs.filesystem ) );
 
-       frame_resizer_base ->Draw_Partition() ;
+       frame_resizer_base->redraw();
 }
 
 
diff --git a/src/Frame_Resizer_Base.cc b/src/Frame_Resizer_Base.cc
index 0af2b03f..99b9fb9c 100644
--- a/src/Frame_Resizer_Base.cc
+++ b/src/Frame_Resizer_Base.cc
@@ -17,6 +17,9 @@
 
 #include "Frame_Resizer_Base.h"
 
+#include <gdkmm/general.h>
+
+
 Frame_Resizer_Base::Frame_Resizer_Base()
 {
        BORDER = 8 ;
@@ -45,13 +48,13 @@ void Frame_Resizer_Base::init()
                        sigc::mem_fun(*this, &Frame_Resizer_Base::drawingarea_on_leave_notify) ) ;
                
        this ->add( drawingarea ) ;
-       
-       color_used .set( "#F8F8BA" );                   this ->get_colormap() ->alloc_color( color_used ) ;
-       color_unused .set( "white" );                   this ->get_colormap() ->alloc_color( color_unused ) ;
-       color_arrow .set( "black" );                    this ->get_colormap() ->alloc_color( color_arrow ) ;
-       color_background .set( "darkgrey" );            this ->get_colormap() ->alloc_color( color_background 
) ;
-       color_arrow_rectangle .set( "lightgrey" );      this ->get_colormap() ->alloc_color( 
color_arrow_rectangle ) ;
-       
+
+       color_used.set("#F8F8BA");
+       color_unused.set("white");
+       color_arrow.set("black");
+       color_background.set("darkgrey");
+       color_arrow_rectangle.set("lightgrey");
+
        cursor_resize = new Gdk::Cursor( Gdk::SB_H_DOUBLE_ARROW ) ; 
        cursor_move   = new Gdk::Cursor( Gdk::FLEUR ) ; 
          
@@ -69,16 +72,12 @@ void Frame_Resizer_Base::init()
 
 void Frame_Resizer_Base::set_rgb_partition_color( const Gdk::Color & color )
 {
-       this ->get_colormap() ->free_color( color_partition ) ;
        this ->color_partition = color ;
-       this ->get_colormap() ->alloc_color( color_partition ) ;
 }
 
 void Frame_Resizer_Base::override_default_rgb_unused_color( const Gdk::Color & color ) 
 {
-       this ->get_colormap() ->free_color( color_unused ) ;
        this ->color_unused = color ;
-       this ->get_colormap() ->alloc_color( color_unused ) ;
 }
 
 void Frame_Resizer_Base::set_x_start( int x_start ) 
@@ -129,12 +128,6 @@ int Frame_Resizer_Base::get_x_end()
 
 void Frame_Resizer_Base::drawingarea_on_realize()
 {
-       gc_drawingarea = Gdk::GC::create( drawingarea .get_window() );
-       pixmap = Gdk::Pixmap::create( drawingarea .get_window(),
-                                     drawingarea .get_allocation() .get_width(),
-                                     drawingarea .get_allocation() .get_height() );
-       gc_pixmap = Gdk::GC::create( pixmap );
-       
        drawingarea .add_events( Gdk::POINTER_MOTION_MASK );
        drawingarea .add_events( Gdk::BUTTON_PRESS_MASK );
        drawingarea .add_events( Gdk::BUTTON_RELEASE_MASK );
@@ -142,8 +135,24 @@ void Frame_Resizer_Base::drawingarea_on_realize()
 }
 
 bool Frame_Resizer_Base::drawingarea_on_expose( GdkEventExpose * ev )
-{ 
-       Draw_Partition() ;
+{
+       Glib::RefPtr<Gdk::Window> window = drawingarea.get_window();
+       if (!window)
+               return true;
+
+       Cairo::RefPtr<Cairo::Context> cr = window->create_cairo_context();
+
+       // Clip to the area indicated by the expose event so that we only redraw
+       // the portion of the window that needs to be redrawn.
+       cr->rectangle(ev->area.x, ev->area.y,
+                     ev->area.width, ev->area.height);
+       cr->clip();
+
+       cr->set_line_cap(Cairo::LINE_CAP_SQUARE);
+       cr->set_line_width(1.0);
+
+       draw_partition(cr);
+
        return true;
 }
 
@@ -281,8 +290,8 @@ bool Frame_Resizer_Base::drawingarea_on_mouse_motion( GdkEventMotion * ev )
                        X_START_MOVE = static_cast<int>( ev ->x ) ;
                        signal_move .emit( X_START - GRIPPER, X_END - GRIPPER - BORDER * 2 ) ;
                }
-               
-               Draw_Partition() ;
+
+               redraw();
        }
        else
        { 
@@ -357,47 +366,49 @@ bool Frame_Resizer_Base::drawingarea_on_leave_notify( GdkEventCrossing *ev )
        return true;
 }
 
-void Frame_Resizer_Base::Draw_Partition()   
+
+void Frame_Resizer_Base::draw_partition(const Cairo::RefPtr<Cairo::Context>& cr)
 {
        UNUSED = X_END - X_START - BORDER * 2 - USED ;
        if ( UNUSED < 0 )
                UNUSED = 0 ;
-       
-       if ( drawingarea .get_window() )
-       {
-               //i couldn't find a clear() for a pixmap, that's why ;)
-               gc_pixmap ->set_foreground( color_background );
-               pixmap ->draw_rectangle( gc_pixmap, true, 0, 0, 536, 50 );
-               
-               //the two rectangles on each side of the partition
-               gc_pixmap ->set_foreground( color_arrow_rectangle );
-               pixmap ->draw_rectangle( gc_pixmap, true, 0, 0, 10, 50 );
-               pixmap ->draw_rectangle( gc_pixmap, true, 526, 0, 10, 50 );
-               
-               //partition
-               gc_pixmap ->set_foreground( color_partition );
-               pixmap ->draw_rectangle( gc_pixmap, true, X_START, 0, X_END - X_START, 50 );
-               
-               //used
-               gc_pixmap ->set_foreground( color_used );
-               pixmap ->draw_rectangle( gc_pixmap, true, X_START +BORDER, BORDER, USED, 34 );
-               
-               //unused
-               gc_pixmap ->set_foreground( color_unused );
-               pixmap ->draw_rectangle( gc_pixmap, true, X_START +BORDER +USED, BORDER, UNUSED, 34 );
-               
-               //resize grips
-               if ( ! fixed_start )
-                       Draw_Resize_Grip( ARROW_LEFT ) ;
-               
-               Draw_Resize_Grip( ARROW_RIGHT ) ;
-               
-               //and draw everything to "real" screen..
-               drawingarea .get_window() ->draw_drawable( gc_drawingarea, pixmap, 0, 0, 0, 0 ) ;
-       }
+
+       // Background color
+       Gdk::Cairo::set_source_color(cr, color_background);
+       cr->rectangle(0, 0, 536, 50);
+       cr->fill();
+
+       // The two rectangles on each side of the partition
+       Gdk::Cairo::set_source_color(cr, color_arrow_rectangle);
+       cr->rectangle(0, 0, 10, 50);
+       cr->fill();
+       cr->rectangle(526, 0, 10, 50);
+       cr->fill();
+
+       // Partition
+       Gdk::Cairo::set_source_color(cr, color_partition);
+       cr->rectangle(X_START, 0, X_END - X_START, 50);
+       cr->fill();
+
+       // Used
+       Gdk::Cairo::set_source_color(cr, color_used);
+       cr->rectangle(X_START + BORDER, BORDER, USED, 34);
+       cr->fill();
+
+       // Unused
+       Gdk::Cairo::set_source_color(cr, color_unused);
+       cr->rectangle(X_START + BORDER + USED, BORDER, UNUSED, 34);
+       cr->fill();
+
+       // Resize grips
+       if (!fixed_start)
+               draw_resize_grip(cr, ARROW_LEFT);
+
+       draw_resize_grip(cr, ARROW_RIGHT);
 }
 
-void Frame_Resizer_Base::Draw_Resize_Grip( ArrowType arrow_type ) 
+
+void Frame_Resizer_Base::draw_resize_grip(const Cairo::RefPtr<Cairo::Context>& cr, ArrowType arrow_type)
 {
        if ( arrow_type == ARROW_LEFT )
        {
@@ -412,28 +423,30 @@ void Frame_Resizer_Base::Draw_Resize_Grip( ArrowType arrow_type )
                arrow_points[ 2 ] .set_x( X_END )  ;
        }
        
-       //attach resize arrows to the partition
-       gc_pixmap ->set_foreground( color_arrow_rectangle );
-       pixmap ->draw_rectangle( gc_pixmap,
-                                false,
-                                arrow_type == ARROW_LEFT ? X_START - GRIPPER : X_END +1,
-                                5,
-                                9,
-                                40 ) ;
-       
-       gc_pixmap ->set_foreground( color_arrow );
-       pixmap ->draw_polygon( gc_pixmap, true, arrow_points );
+       // Attach resize arrows to the partition
+       Gdk::Cairo::set_source_color(cr, color_arrow_rectangle);
+       cr->rectangle((arrow_type == ARROW_LEFT ? X_START - GRIPPER : X_END + 1) + 0.5,
+                     5 + 0.5,
+                     9,
+                     40);
+       cr->stroke();
+
+       Gdk::Cairo::set_source_color(cr, color_arrow);
+       cr->move_to(arrow_points[0].get_x(), arrow_points[0].get_y());
+       cr->line_to(arrow_points[1].get_x(), arrow_points[1].get_y());
+       cr->line_to(arrow_points[2].get_x(), arrow_points[2].get_y());
+       cr->close_path();
+       cr->fill();
+}
+
+
+void Frame_Resizer_Base::redraw()
+{
+       drawingarea.queue_draw();
 }
 
 Frame_Resizer_Base::~Frame_Resizer_Base()
-{ 
-       this ->get_colormap() ->free_color( color_used ) ;
-       this ->get_colormap() ->free_color( color_unused ) ;
-       this ->get_colormap() ->free_color( color_arrow ) ;
-       this ->get_colormap() ->free_color( color_background ) ;
-       this ->get_colormap() ->free_color( color_partition ) ;
-       this ->get_colormap() ->free_color( color_arrow_rectangle ) ;
-       
+{
        delete cursor_resize;
        delete cursor_move;
 }
diff --git a/src/Frame_Resizer_Extended.cc b/src/Frame_Resizer_Extended.cc
index 321dc004..9b4b771f 100644
--- a/src/Frame_Resizer_Extended.cc
+++ b/src/Frame_Resizer_Extended.cc
@@ -17,6 +17,9 @@
 
 #include "Frame_Resizer_Extended.h"
 
+#include <gdkmm/general.h>
+
+
 Frame_Resizer_Extended::Frame_Resizer_Extended()
 {
 }
@@ -123,8 +126,8 @@ bool Frame_Resizer_Extended::drawingarea_on_mouse_motion( GdkEventMotion * ev )
                                }
                        }
                }
-               
-               Draw_Partition() ;
+
+               redraw();
        }
        
        //check if pointer is over a gripper
@@ -151,30 +154,35 @@ bool Frame_Resizer_Extended::drawingarea_on_mouse_motion( GdkEventMotion * ev )
        return true ;
 }
 
-void Frame_Resizer_Extended::Draw_Partition() 
+
+void Frame_Resizer_Extended::draw_partition(const Cairo::RefPtr<Cairo::Context>& cr)
 {
-       //i couldn't find a clear() for a pixmap, that's why ;)
-       gc_pixmap ->set_foreground( color_background );
-       pixmap ->draw_rectangle( gc_pixmap, true, 0, 0, 536, 50 );
-       
-       //the two rectangles on each side of the partition
-       gc_pixmap ->set_foreground( color_arrow_rectangle );
-       pixmap ->draw_rectangle( gc_pixmap, true, 0, 0, 10, 50 );
-       pixmap ->draw_rectangle( gc_pixmap, true, 526, 0, 10, 50 );
-       
-       //used
-       gc_pixmap ->set_foreground( color_used );
-       pixmap ->draw_rectangle( gc_pixmap, true, USED_START + BORDER, BORDER, USED, 34 );
-       
-       //partition
-       gc_pixmap ->set_foreground( color_partition );
+       // Background color
+       Gdk::Cairo::set_source_color(cr, color_background);
+       cr->rectangle(0, 0, 536, 50);
+       cr->fill();
+
+       // The two rectangles on each side of the partition
+       Gdk::Cairo::set_source_color(cr, color_arrow_rectangle);
+       cr->rectangle(0, 0, 10, 50);
+       cr->fill();
+       cr->rectangle(526, 0, 10, 50);
+       cr->fill();
+
+       // Used
+       Gdk::Cairo::set_source_color(cr, color_used);
+       cr->rectangle(USED_START + BORDER, BORDER, USED, 34);
+       cr->fill();
+
+       // Partition
+       Gdk::Cairo::set_source_color(cr, color_partition);
        for( short t = 0; t < 9 ; t++ )
-               pixmap ->draw_rectangle( gc_pixmap, false, X_START +t, t, X_END - X_START -t*2, 50 - t*2 );
-                       
-       //resize grips
-       Draw_Resize_Grip( ARROW_LEFT ) ;
-       Draw_Resize_Grip( ARROW_RIGHT ) ;
-       
-       //and draw everything to "real" screen..
-       drawingarea .get_window() ->draw_drawable( gc_drawingarea, pixmap, 0, 0, 0, 0 ) ;
+       {
+               cr->rectangle(X_START + t + 0.5, t + 0.5, X_END - X_START - t*2, 50 - t*2);
+               cr->stroke();
+       }
+
+       // Resize grips
+       draw_resize_grip(cr, ARROW_LEFT);
+       draw_resize_grip(cr, ARROW_RIGHT);
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]