Merge branch 'devel'
[aoi.git] / src / gui_kanjiview.cxx
blobd8fdbc386fe3fd4b9ebeef28ddcfca4ceaf016ef
1 /*
2 Copyright 2013 Karel Matas
4 This program is free software: you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation, either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program. If not, see <http://www.gnu.org/licenses/>.
17 #include <cstdio>
18 #include <cmath>
19 #include <FL/Fl_Menu_Item.H>
20 #include "gui_kanjiview.hxx"
21 #include "utils.hxx"
22 #include "logger.hxx"
23 #ifdef DEBUG
24 // std::runtime_error is used only with DEBUG
25 #include <stdexcept>
26 #endif
28 using utils::split_string;
30 namespace aoi_ui {
32 KanjiView::KanjiView ( int x, int y, int w, int h, const char *l ): Fl_Table(x,y,w,h,l)
34 when( FL_WHEN_RELEASE|FL_WHEN_CHANGED );
35 table_box( FL_NO_BOX );
36 cb_leftclick( scb_general, nullptr );
37 cb_rightclick( scb_general, nullptr );
38 cb_select( scb_general, nullptr );
39 cols(1);
40 end();
44 int KanjiView::handle ( int event )
46 switch ( event ) {
47 case FL_PUSH:
49 take_focus();
50 if ( Fl::event_button() == FL_LEFT_MOUSE && Fl::belowmouse() == this ){
51 Cell *c = cell_at_xy(Fl::event_x()-x(), Fl::event_y()-y());
52 if ( c ){
53 if ( c->selected )
54 c->selected = false;
55 else {
56 select_cell(c);
57 cb_leftclick(this);
59 redraw();
60 return 1;
63 else if ( Fl::event_button() == FL_RIGHT_MOUSE ) {
64 Cell *c = cell_at_xy(Fl::event_x()-x(), Fl::event_y()-y());
65 Fl_Menu_Item menu[] = {
66 { "Copy", 0, scb_copy, (void*)c->str.c_str() },
67 // TODO: copy all kanjidata
68 { 0 }
70 const Fl_Menu_Item *m = menu->popup(Fl::event_x(), Fl::event_y(), 0, 0, 0);
71 if ( m )
72 m->do_callback(0, m->user_data());
73 return 1;
76 case FL_RELEASE:
77 if ( Fl::event_button() == FL_RIGHT_MOUSE )
78 return 1;
79 case FL_KEYUP:
81 int cell = selected_id();
82 switch ( Fl::event_key() ){
83 case FL_Left:
85 if ( cell > 0 )
86 select_cell(cell-1);
87 return 1;
89 case FL_Right:
91 size_t id = cell+1;
92 if ( id < data_.size() )
93 select_cell(id);
94 return 1;
96 case FL_Down:
98 size_t id = cell+cols();
99 if ( id < data_.size() )
100 select_cell(id);
101 return 1;
103 case FL_Up:
105 int id = cell-cols();
106 if ( id >= 0 )
107 select_cell(id);
108 return 1;
110 case FL_Enter:
111 case ' ':
113 cb_select(this);
114 return 1;
118 default:
119 return Fl_Table::handle(event);
123 void KanjiView::font_size ( int s )
125 font_size_ = s;
126 fl_font( font_, font_size_ );
127 int x = fl_height() + 2*cell_padding_;
128 cell_size(x);
131 void KanjiView::set_data ( const vector<Cell> &d )
133 // prevents division by zero
134 if ( cols() == 0 )
135 cols(1);
136 // clear view
137 data_.clear();
138 // set new data
139 data_ = d;
140 int ncols = d.size()/cols();
141 rows( (ncols>1) ? ncols:1 );
142 row_height_all( cell_size_ );
143 col_width_all( cell_size_ );
144 draw_cell( CONTEXT_RC_RESIZE, 0, 0, 0, 0 );
145 redraw();
149 void KanjiView::draw_single_cell ( int R, int C, int X, int Y, int W, int H )
151 int cell = R*cols()+C;
153 // empty cells at the end of the last row
154 if ( cell >= int(data_.size()) ){
155 fl_push_clip(X, Y, W, H);
157 // background
158 fl_color( Fl::get_color( FL_BACKGROUND2_COLOR ) );
159 fl_rectf(X, Y, W, H);
160 // border
161 fl_color(FL_LIGHT2);
162 fl_rect(X, Y, W, H);
164 fl_pop_clip();
165 return;
168 Cell c = data_.at(cell);
169 fl_push_clip(X, Y, W, H);
171 // BG COLOR
172 fl_color(c.selected ? selection_color_:c.bgcolor );
173 fl_rectf(X, Y, W, H);
175 // TEXT
176 fl_font( font_, font_size_ );
177 fl_color( c.fgcolor );
178 fl_draw( c.str.c_str(), X+cell_padding_, Y+font_size_ );
180 // BORDER
181 fl_color(FL_LIGHT2);
182 fl_rect(X, Y, W, H);
184 fl_pop_clip();
188 void KanjiView::draw_cell ( TableContext context, int R, int C, int X, int Y, int W, int H )
190 switch ( context )
192 case CONTEXT_STARTPAGE:
193 fl_font( FL_HELVETICA, font_size());
194 return;
196 case CONTEXT_COL_HEADER:
197 fl_push_clip(X, Y, W, H);
199 fl_draw_box(FL_THIN_UP_BOX, X, Y, W, H, col_header_color());
201 fl_pop_clip();
202 return;
205 case CONTEXT_CELL:
207 draw_single_cell(R,C,X,Y,W,H);
208 return;
212 case CONTEXT_RC_RESIZE:
214 // append column
215 int n_cols = (w()-vscrollbar->w())/cell_size_;
216 int n_rows = ceil((float)data_.size()/n_cols);
217 if ( n_cols != cols() )
218 cols( n_cols );
219 if ( n_rows != rows() ){
220 rows(n_rows);
221 row_height_all(cell_size_);
223 return;
226 default:
227 return;
231 } // namespace