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