1 #include "ColorCellEditable.h"
2 
3 #include <gtkmm.h>
4 
5 #include <sstream>
6 
7 #include <iostream>
8 
ColorCellEditable(const Glib::ustring & path)9 ColorCellEditable::ColorCellEditable(const Glib::ustring& path) :
10 	Glib::ObjectBase( typeid(ColorCellEditable) ),
11 	Gtk::EventBox(),
12 	Gtk::CellEditable(),
13 	path_( path ),
14 	color_area_ptr_( 0 ),
15 	entry_ptr_( 0 ),
16 	button_ptr_( 0 ),
17 	editing_cancelled_( false )
18 {
19 	Gtk::HBox *const hbox = new Gtk::HBox(false, 0);
20 	add (*Gtk::manage( hbox ));
21 
22 	color_area_ptr_ = new ColorArea();
23 	// TODO: expose color_area size for get_size_vfunc
24 	color_area_ptr_->set_size_request (16, 16);
25 	hbox->pack_start (*Gtk::manage( color_area_ptr_ ), Gtk::PACK_SHRINK, 2);
26 
27 	entry_ptr_ = new Gtk::Entry();
28 	hbox->pack_start (*Gtk::manage(entry_ptr_), Gtk::PACK_EXPAND_WIDGET);
29 	entry_ptr_->set_has_frame (false);
30 	entry_ptr_->gobj()->is_cell_renderer = true; // XXX
31 
32 	button_ptr_ = new Gtk::Button();
33 	hbox->pack_start (*Gtk::manage( button_ptr_ ), Gtk::PACK_SHRINK);
34 	button_ptr_->add (*Gtk::manage(new Gtk::Arrow(Gtk::ARROW_DOWN, Gtk::SHADOW_OUT)));
35 
36 	set_flags(Gtk::CAN_FOCUS);
37 
38 	show_all_children();
39 }
40 
~ColorCellEditable()41 ColorCellEditable::~ColorCellEditable()
42 {
43 }
44 
get_path() const45 Glib::ustring ColorCellEditable::get_path() const
46 {
47 	return path_;
48 }
49 
set_text(const Glib::ustring & text)50 void ColorCellEditable::set_text(const Glib::ustring& text)
51 {
52 	int r = 0;
53 	int g = 0;
54 	int b = 0;
55 
56 	entry_ptr_->set_text (text);
57 
58 	std::stringstream ss;
59 	ss << text;
60 	ss >> r;
61 	ss >> g;
62 	ss >> b;
63 
64 	color_.set_rgb_p (r/255.0, g/255.0, b/255.0);
65 
66 	color_area_ptr_->set_color (color_);
67 }
68 
get_text() const69 Glib::ustring ColorCellEditable::get_text() const
70 {
71 	std::stringstream ss;
72 	ss << int(color_.get_red_p() * 255) << " ";
73 	ss << int(color_.get_green_p() * 255) << " ";
74 	ss << int(color_.get_blue_p() * 255);
75 
76 	return ss.str();
77 }
78 
get_button_width()79 int ColorCellEditable::get_button_width()
80 {
81 	Gtk::Window window (Gtk::WINDOW_POPUP);
82 
83 	Gtk::Button *const button = new Gtk::Button();
84 	window.add(*Gtk::manage(button));
85 
86 	button->add(*Gtk::manage(new Gtk::Arrow(Gtk::ARROW_DOWN, Gtk::SHADOW_OUT)));
87 
88 	// Urgh.  Hackish :/
89 	window.move(-500, -500);
90 	window.show_all();
91 
92 	Gtk::Requisition requisition = window.size_request();
93 
94 	return requisition.width;
95 }
96 
get_color_area_width()97 /* static */ int ColorCellEditable::get_color_area_width()
98 {
99 	return 16;
100 }
101 
start_editing_vfunc(GdkEvent *)102 void ColorCellEditable::start_editing_vfunc(GdkEvent*)
103 {
104 	entry_ptr_->select_region(0, -1);
105 	entry_ptr_->signal_activate().connect(sigc::mem_fun(*this, &ColorCellEditable::on_entry_activate));
106 	entry_ptr_->signal_key_press_event().connect(sigc::mem_fun(*this, &ColorCellEditable::on_entry_key_press_event));
107 
108 	button_ptr_->signal_clicked().connect (sigc::mem_fun( *this, &ColorCellEditable::on_button_clicked ));
109 }
110 
on_editing_done()111 void ColorCellEditable::on_editing_done()
112 {
113 	std::cout << "on_editing_done " << editing_cancelled_ << std::endl;
114 
115 	if (!editing_cancelled_)
116 	{
117 		int r = 0;
118 		int g = 0;
119 		int b = 0;
120 
121 		std::stringstream ss;
122 		ss << entry_ptr_->get_text();
123 		ss >> r;
124 		ss >> g;
125 		ss >> b;
126 
127 		color_.set_rgb_p (r/255.0, g/255.0, b/255.0);
128 	}
129 
130 	signal_editing_done_.emit();
131 }
132 
on_button_clicked()133 void ColorCellEditable::on_button_clicked()
134 {
135 	Gtk::ColorSelectionDialog dialog( "Changing color" );
136 
137 	dialog.set_transient_for ((Gtk::Window&)(*this->get_toplevel()));
138 
139 	Gtk::ColorSelection* colorsel = dialog.get_colorsel();
140 	colorsel->set_previous_color (color_);
141 	colorsel->set_current_color (color_);
142 	colorsel->set_has_palette (true);
143 
144 	if (dialog.run() == Gtk::RESPONSE_OK)
145 	{
146 		color_ = colorsel->get_current_color();
147 
148 		signal_editing_done_.emit();
149 	}
150 
151 }
152 
on_entry_key_press_event(GdkEventKey * event)153 bool ColorCellEditable::on_entry_key_press_event(GdkEventKey* event)
154 {
155 	if (event->keyval == GDK_Escape)
156 	{
157 		std::cout << "Press ESCAPE" << std::endl;
158 
159 		editing_cancelled_ = true;
160 
161 	    editing_done();
162 	    remove_widget();
163 		return true;
164 	}
165 
166 	return false;
167 }
168 
on_entry_activate()169 void ColorCellEditable::on_entry_activate()
170 {
171 	editing_done();
172 }
173