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
This commit is contained in:
parent
c602170faa
commit
d17d129044
|
@ -47,7 +47,9 @@ public:
|
||||||
int get_x_start() ;
|
int get_x_start() ;
|
||||||
int get_x_end() ;
|
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)
|
//public signals (emitted upon resize/move)
|
||||||
sigc::signal<void,int,int, ArrowType> signal_resize;
|
sigc::signal<void,int,int, ArrowType> signal_resize;
|
||||||
|
@ -67,12 +69,9 @@ protected:
|
||||||
bool drawingarea_on_button_release_event( GdkEventButton * ev ) ;
|
bool drawingarea_on_button_release_event( GdkEventButton * ev ) ;
|
||||||
bool drawingarea_on_leave_notify( GdkEventCrossing * 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 ;
|
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;
|
Gdk::Color color_used, color_unused, color_arrow, color_background, color_partition, color_arrow_rectangle;
|
||||||
|
|
||||||
|
|
|
@ -33,7 +33,7 @@ private:
|
||||||
//overridden signal handler
|
//overridden signal handler
|
||||||
virtual bool drawingarea_on_mouse_motion( GdkEventMotion * ev ) ;
|
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 */
|
#endif /* GPARTED_FRAME_RESIZER_EXTENDED_H */
|
||||||
|
|
|
@ -373,7 +373,7 @@ void Dialog_Base_Partition::on_spinbutton_value_changed( SPINBUTTON spinbutton )
|
||||||
|
|
||||||
frame_resizer_base ->set_x_end( 500 - Utils::round( spinbutton_after .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() ;
|
Check_Change() ;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
// 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 ) );
|
filesystem_label_entry.set_max_length( Utils::get_filesystem_label_maxlength( fs.filesystem ) );
|
||||||
|
|
||||||
frame_resizer_base ->Draw_Partition() ;
|
frame_resizer_base->redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
#include "Frame_Resizer_Base.h"
|
#include "Frame_Resizer_Base.h"
|
||||||
|
|
||||||
|
#include <gdkmm/general.h>
|
||||||
|
|
||||||
|
|
||||||
Frame_Resizer_Base::Frame_Resizer_Base()
|
Frame_Resizer_Base::Frame_Resizer_Base()
|
||||||
{
|
{
|
||||||
BORDER = 8 ;
|
BORDER = 8 ;
|
||||||
|
@ -46,11 +49,11 @@ void Frame_Resizer_Base::init()
|
||||||
|
|
||||||
this ->add( drawingarea ) ;
|
this ->add( drawingarea ) ;
|
||||||
|
|
||||||
color_used .set( "#F8F8BA" ); this ->get_colormap() ->alloc_color( color_used ) ;
|
color_used.set("#F8F8BA");
|
||||||
color_unused .set( "white" ); this ->get_colormap() ->alloc_color( color_unused ) ;
|
color_unused.set("white");
|
||||||
color_arrow .set( "black" ); this ->get_colormap() ->alloc_color( color_arrow ) ;
|
color_arrow.set("black");
|
||||||
color_background .set( "darkgrey" ); this ->get_colormap() ->alloc_color( color_background ) ;
|
color_background.set("darkgrey");
|
||||||
color_arrow_rectangle .set( "lightgrey" ); this ->get_colormap() ->alloc_color( color_arrow_rectangle ) ;
|
color_arrow_rectangle.set("lightgrey");
|
||||||
|
|
||||||
cursor_resize = new Gdk::Cursor( Gdk::SB_H_DOUBLE_ARROW ) ;
|
cursor_resize = new Gdk::Cursor( Gdk::SB_H_DOUBLE_ARROW ) ;
|
||||||
cursor_move = new Gdk::Cursor( Gdk::FLEUR ) ;
|
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 )
|
void Frame_Resizer_Base::set_rgb_partition_color( const Gdk::Color & color )
|
||||||
{
|
{
|
||||||
this ->get_colormap() ->free_color( color_partition ) ;
|
|
||||||
this ->color_partition = color ;
|
this ->color_partition = color ;
|
||||||
this ->get_colormap() ->alloc_color( color_partition ) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame_Resizer_Base::override_default_rgb_unused_color( const Gdk::Color & color )
|
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 ->color_unused = color ;
|
||||||
this ->get_colormap() ->alloc_color( color_unused ) ;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Frame_Resizer_Base::set_x_start( int x_start )
|
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()
|
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::POINTER_MOTION_MASK );
|
||||||
drawingarea .add_events( Gdk::BUTTON_PRESS_MASK );
|
drawingarea .add_events( Gdk::BUTTON_PRESS_MASK );
|
||||||
drawingarea .add_events( Gdk::BUTTON_RELEASE_MASK );
|
drawingarea .add_events( Gdk::BUTTON_RELEASE_MASK );
|
||||||
|
@ -143,7 +136,23 @@ void Frame_Resizer_Base::drawingarea_on_realize()
|
||||||
|
|
||||||
bool Frame_Resizer_Base::drawingarea_on_expose( GdkEventExpose * ev )
|
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;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -282,7 +291,7 @@ bool Frame_Resizer_Base::drawingarea_on_mouse_motion( GdkEventMotion * ev )
|
||||||
signal_move .emit( X_START - GRIPPER, X_END - GRIPPER - BORDER * 2 ) ;
|
signal_move .emit( X_START - GRIPPER, X_END - GRIPPER - BORDER * 2 ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw_Partition() ;
|
redraw();
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -357,47 +366,49 @@ bool Frame_Resizer_Base::drawingarea_on_leave_notify( GdkEventCrossing *ev )
|
||||||
return true;
|
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 ;
|
UNUSED = X_END - X_START - BORDER * 2 - USED ;
|
||||||
if ( UNUSED < 0 )
|
if ( UNUSED < 0 )
|
||||||
UNUSED = 0 ;
|
UNUSED = 0 ;
|
||||||
|
|
||||||
if ( drawingarea .get_window() )
|
// Background color
|
||||||
{
|
Gdk::Cairo::set_source_color(cr, color_background);
|
||||||
//i couldn't find a clear() for a pixmap, that's why ;)
|
cr->rectangle(0, 0, 536, 50);
|
||||||
gc_pixmap ->set_foreground( color_background );
|
cr->fill();
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, 0, 0, 536, 50 );
|
|
||||||
|
|
||||||
//the two rectangles on each side of the partition
|
// The two rectangles on each side of the partition
|
||||||
gc_pixmap ->set_foreground( color_arrow_rectangle );
|
Gdk::Cairo::set_source_color(cr, color_arrow_rectangle);
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, 0, 0, 10, 50 );
|
cr->rectangle(0, 0, 10, 50);
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, 526, 0, 10, 50 );
|
cr->fill();
|
||||||
|
cr->rectangle(526, 0, 10, 50);
|
||||||
|
cr->fill();
|
||||||
|
|
||||||
//partition
|
// Partition
|
||||||
gc_pixmap ->set_foreground( color_partition );
|
Gdk::Cairo::set_source_color(cr, color_partition);
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, X_START, 0, X_END - X_START, 50 );
|
cr->rectangle(X_START, 0, X_END - X_START, 50);
|
||||||
|
cr->fill();
|
||||||
|
|
||||||
//used
|
// Used
|
||||||
gc_pixmap ->set_foreground( color_used );
|
Gdk::Cairo::set_source_color(cr, color_used);
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, X_START +BORDER, BORDER, USED, 34 );
|
cr->rectangle(X_START + BORDER, BORDER, USED, 34);
|
||||||
|
cr->fill();
|
||||||
|
|
||||||
//unused
|
// Unused
|
||||||
gc_pixmap ->set_foreground( color_unused );
|
Gdk::Cairo::set_source_color(cr, color_unused);
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, X_START +BORDER +USED, BORDER, UNUSED, 34 );
|
cr->rectangle(X_START + BORDER + USED, BORDER, UNUSED, 34);
|
||||||
|
cr->fill();
|
||||||
|
|
||||||
//resize grips
|
// Resize grips
|
||||||
if ( ! fixed_start )
|
if (!fixed_start)
|
||||||
Draw_Resize_Grip( ARROW_LEFT ) ;
|
draw_resize_grip(cr, ARROW_LEFT);
|
||||||
|
|
||||||
Draw_Resize_Grip( ARROW_RIGHT ) ;
|
draw_resize_grip(cr, ARROW_RIGHT);
|
||||||
|
|
||||||
//and draw everything to "real" screen..
|
|
||||||
drawingarea .get_window() ->draw_drawable( gc_drawingarea, pixmap, 0, 0, 0, 0 ) ;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
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 )
|
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 ) ;
|
arrow_points[ 2 ] .set_x( X_END ) ;
|
||||||
}
|
}
|
||||||
|
|
||||||
//attach resize arrows to the partition
|
// Attach resize arrows to the partition
|
||||||
gc_pixmap ->set_foreground( color_arrow_rectangle );
|
Gdk::Cairo::set_source_color(cr, color_arrow_rectangle);
|
||||||
pixmap ->draw_rectangle( gc_pixmap,
|
cr->rectangle((arrow_type == ARROW_LEFT ? X_START - GRIPPER : X_END + 1) + 0.5,
|
||||||
false,
|
5 + 0.5,
|
||||||
arrow_type == ARROW_LEFT ? X_START - GRIPPER : X_END +1,
|
9,
|
||||||
5,
|
40);
|
||||||
9,
|
cr->stroke();
|
||||||
40 ) ;
|
|
||||||
|
|
||||||
gc_pixmap ->set_foreground( color_arrow );
|
Gdk::Cairo::set_source_color(cr, color_arrow);
|
||||||
pixmap ->draw_polygon( gc_pixmap, true, arrow_points );
|
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()
|
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_resize;
|
||||||
delete cursor_move;
|
delete cursor_move;
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,9 @@
|
||||||
|
|
||||||
#include "Frame_Resizer_Extended.h"
|
#include "Frame_Resizer_Extended.h"
|
||||||
|
|
||||||
|
#include <gdkmm/general.h>
|
||||||
|
|
||||||
|
|
||||||
Frame_Resizer_Extended::Frame_Resizer_Extended()
|
Frame_Resizer_Extended::Frame_Resizer_Extended()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -124,7 +127,7 @@ bool Frame_Resizer_Extended::drawingarea_on_mouse_motion( GdkEventMotion * ev )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Draw_Partition() ;
|
redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
//check if pointer is over a gripper
|
//check if pointer is over a gripper
|
||||||
|
@ -151,30 +154,35 @@ bool Frame_Resizer_Extended::drawingarea_on_mouse_motion( GdkEventMotion * ev )
|
||||||
return true ;
|
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 ;)
|
// Background color
|
||||||
gc_pixmap ->set_foreground( color_background );
|
Gdk::Cairo::set_source_color(cr, color_background);
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, 0, 0, 536, 50 );
|
cr->rectangle(0, 0, 536, 50);
|
||||||
|
cr->fill();
|
||||||
|
|
||||||
//the two rectangles on each side of the partition
|
// The two rectangles on each side of the partition
|
||||||
gc_pixmap ->set_foreground( color_arrow_rectangle );
|
Gdk::Cairo::set_source_color(cr, color_arrow_rectangle);
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, 0, 0, 10, 50 );
|
cr->rectangle(0, 0, 10, 50);
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, 526, 0, 10, 50 );
|
cr->fill();
|
||||||
|
cr->rectangle(526, 0, 10, 50);
|
||||||
|
cr->fill();
|
||||||
|
|
||||||
//used
|
// Used
|
||||||
gc_pixmap ->set_foreground( color_used );
|
Gdk::Cairo::set_source_color(cr, color_used);
|
||||||
pixmap ->draw_rectangle( gc_pixmap, true, USED_START + BORDER, BORDER, USED, 34 );
|
cr->rectangle(USED_START + BORDER, BORDER, USED, 34);
|
||||||
|
cr->fill();
|
||||||
|
|
||||||
//partition
|
// Partition
|
||||||
gc_pixmap ->set_foreground( color_partition );
|
Gdk::Cairo::set_source_color(cr, color_partition);
|
||||||
for( short t = 0; t < 9 ; t++ )
|
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 );
|
{
|
||||||
|
cr->rectangle(X_START + t + 0.5, t + 0.5, X_END - X_START - t*2, 50 - t*2);
|
||||||
|
cr->stroke();
|
||||||
|
}
|
||||||
|
|
||||||
//resize grips
|
// Resize grips
|
||||||
Draw_Resize_Grip( ARROW_LEFT ) ;
|
draw_resize_grip(cr, ARROW_LEFT);
|
||||||
Draw_Resize_Grip( ARROW_RIGHT ) ;
|
draw_resize_grip(cr, ARROW_RIGHT);
|
||||||
|
|
||||||
//and draw everything to "real" screen..
|
|
||||||
drawingarea .get_window() ->draw_drawable( gc_drawingarea, pixmap, 0, 0, 0, 0 ) ;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue