1 //---------------------------------------------------------------------------- 2 // Anti-Grain Geometry (AGG) - Version 2.5 3 // A high quality rendering engine for C++ 4 // Copyright (C) 2002-2006 Maxim Shemanarev 5 // Contact: mcseem@antigrain.com 6 // mcseemagg@yahoo.com 7 // http://antigrain.com 8 // 9 // AGG is free software; you can redistribute it and/or 10 // modify it under the terms of the GNU General Public License 11 // as published by the Free Software Foundation; either version 2 12 // of the License, or (at your option) any later version. 13 // 14 // AGG is distributed in the hope that it will be useful, 15 // but WITHOUT ANY WARRANTY; without even the implied warranty of 16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 // GNU General Public License for more details. 18 // 19 // You should have received a copy of the GNU General Public License 20 // along with AGG; if not, write to the Free Software 21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, 22 // MA 02110-1301, USA. 23 //---------------------------------------------------------------------------- 24 25 #include <string.h> 26 #include "ctrl/agg_rbox_ctrl.h" 27 28 namespace agg 29 { 30 31 //------------------------------------------------------------------------ rbox_ctrl_impl(double x1,double y1,double x2,double y2,bool flip_y)32 rbox_ctrl_impl::rbox_ctrl_impl(double x1, double y1, 33 double x2, double y2, bool flip_y) : 34 ctrl(x1, y1, x2, y2, flip_y), 35 m_border_width(1.0), 36 m_border_extra(0.0), 37 m_text_thickness(1.5), 38 m_text_height(9.0), 39 m_text_width(0.0), 40 m_num_items(0), 41 m_cur_item(-1), 42 m_ellipse_poly(m_ellipse), 43 m_text_poly(m_text), 44 m_idx(0), 45 m_vertex(0) 46 { 47 calc_rbox(); 48 } 49 50 51 //------------------------------------------------------------------------ calc_rbox()52 void rbox_ctrl_impl::calc_rbox() 53 { 54 m_xs1 = m_x1 + m_border_width; 55 m_ys1 = m_y1 + m_border_width; 56 m_xs2 = m_x2 - m_border_width; 57 m_ys2 = m_y2 - m_border_width; 58 } 59 60 61 //------------------------------------------------------------------------ add_item(const char * text)62 void rbox_ctrl_impl::add_item(const char* text) 63 { 64 if(m_num_items < 32) 65 { 66 m_items[m_num_items].resize(strlen(text) + 1); 67 strcpy(&m_items[m_num_items][0], text); 68 m_num_items++; 69 } 70 } 71 72 73 //------------------------------------------------------------------------ border_width(double t,double extra)74 void rbox_ctrl_impl::border_width(double t, double extra) 75 { 76 m_border_width = t; 77 m_border_extra = extra; 78 calc_rbox(); 79 } 80 81 82 //------------------------------------------------------------------------ text_size(double h,double w)83 void rbox_ctrl_impl::text_size(double h, double w) 84 { 85 m_text_width = w; 86 m_text_height = h; 87 } 88 89 90 91 //------------------------------------------------------------------------ rewind(unsigned idx)92 void rbox_ctrl_impl::rewind(unsigned idx) 93 { 94 m_idx = idx; 95 m_dy = m_text_height * 2.0; 96 m_draw_item = 0; 97 98 switch(idx) 99 { 100 default: 101 102 case 0: // Background 103 m_vertex = 0; 104 m_vx[0] = m_x1 - m_border_extra; 105 m_vy[0] = m_y1 - m_border_extra; 106 m_vx[1] = m_x2 + m_border_extra; 107 m_vy[1] = m_y1 - m_border_extra; 108 m_vx[2] = m_x2 + m_border_extra; 109 m_vy[2] = m_y2 + m_border_extra; 110 m_vx[3] = m_x1 - m_border_extra; 111 m_vy[3] = m_y2 + m_border_extra; 112 break; 113 114 case 1: // Border 115 m_vertex = 0; 116 m_vx[0] = m_x1; 117 m_vy[0] = m_y1; 118 m_vx[1] = m_x2; 119 m_vy[1] = m_y1; 120 m_vx[2] = m_x2; 121 m_vy[2] = m_y2; 122 m_vx[3] = m_x1; 123 m_vy[3] = m_y2; 124 m_vx[4] = m_x1 + m_border_width; 125 m_vy[4] = m_y1 + m_border_width; 126 m_vx[5] = m_x1 + m_border_width; 127 m_vy[5] = m_y2 - m_border_width; 128 m_vx[6] = m_x2 - m_border_width; 129 m_vy[6] = m_y2 - m_border_width; 130 m_vx[7] = m_x2 - m_border_width; 131 m_vy[7] = m_y1 + m_border_width; 132 break; 133 134 case 2: // Text 135 m_text.text(&m_items[0][0]); 136 m_text.start_point(m_xs1 + m_dy * 1.5, m_ys1 + m_dy / 2.0); 137 m_text.size(m_text_height, m_text_width); 138 m_text_poly.width(m_text_thickness); 139 m_text_poly.line_join(round_join); 140 m_text_poly.line_cap(round_cap); 141 m_text_poly.rewind(0); 142 break; 143 144 case 3: // Inactive items 145 m_ellipse.init(m_xs1 + m_dy / 1.3, 146 m_ys1 + m_dy / 1.3, 147 m_text_height / 1.5, 148 m_text_height / 1.5, 32); 149 m_ellipse_poly.width(m_text_thickness); 150 m_ellipse_poly.rewind(0); 151 break; 152 153 154 case 4: // Active Item 155 if(m_cur_item >= 0) 156 { 157 m_ellipse.init(m_xs1 + m_dy / 1.3, 158 m_ys1 + m_dy * m_cur_item + m_dy / 1.3, 159 m_text_height / 2.0, 160 m_text_height / 2.0, 32); 161 m_ellipse.rewind(0); 162 } 163 break; 164 165 } 166 } 167 168 169 //------------------------------------------------------------------------ vertex(double * x,double * y)170 unsigned rbox_ctrl_impl::vertex(double* x, double* y) 171 { 172 unsigned cmd = path_cmd_line_to; 173 switch(m_idx) 174 { 175 case 0: 176 if(m_vertex == 0) cmd = path_cmd_move_to; 177 if(m_vertex >= 4) cmd = path_cmd_stop; 178 *x = m_vx[m_vertex]; 179 *y = m_vy[m_vertex]; 180 m_vertex++; 181 break; 182 183 case 1: 184 if(m_vertex == 0 || m_vertex == 4) cmd = path_cmd_move_to; 185 if(m_vertex >= 8) cmd = path_cmd_stop; 186 *x = m_vx[m_vertex]; 187 *y = m_vy[m_vertex]; 188 m_vertex++; 189 break; 190 191 case 2: 192 cmd = m_text_poly.vertex(x, y); 193 if(is_stop(cmd)) 194 { 195 m_draw_item++; 196 if(m_draw_item >= m_num_items) 197 { 198 break; 199 } 200 else 201 { 202 m_text.text(&m_items[m_draw_item][0]); 203 m_text.start_point(m_xs1 + m_dy * 1.5, 204 m_ys1 + m_dy * (m_draw_item + 1) - m_dy / 2.0); 205 206 m_text_poly.rewind(0); 207 cmd = m_text_poly.vertex(x, y); 208 } 209 } 210 break; 211 212 case 3: 213 cmd = m_ellipse_poly.vertex(x, y); 214 if(is_stop(cmd)) 215 { 216 m_draw_item++; 217 if(m_draw_item >= m_num_items) 218 { 219 break; 220 } 221 else 222 { 223 m_ellipse.init(m_xs1 + m_dy / 1.3, 224 m_ys1 + m_dy * m_draw_item + m_dy / 1.3, 225 m_text_height / 1.5, 226 m_text_height / 1.5, 32); 227 m_ellipse_poly.rewind(0); 228 cmd = m_ellipse_poly.vertex(x, y); 229 } 230 } 231 break; 232 233 234 case 4: 235 if(m_cur_item >= 0) 236 { 237 cmd = m_ellipse.vertex(x, y); 238 } 239 else 240 { 241 cmd = path_cmd_stop; 242 } 243 break; 244 245 default: 246 cmd = path_cmd_stop; 247 break; 248 } 249 250 if(!is_stop(cmd)) 251 { 252 transform_xy(x, y); 253 } 254 255 return cmd; 256 } 257 258 259 //------------------------------------------------------------------------ in_rect(double x,double y) const260 bool rbox_ctrl_impl::in_rect(double x, double y) const 261 { 262 inverse_transform_xy(&x, &y); 263 return x >= m_x1 && x <= m_x2 && y >= m_y1 && y <= m_y2; 264 } 265 266 267 268 //------------------------------------------------------------------------ on_mouse_button_down(double x,double y)269 bool rbox_ctrl_impl::on_mouse_button_down(double x, double y) 270 { 271 inverse_transform_xy(&x, &y); 272 unsigned i; 273 for(i = 0; i < m_num_items; i++) 274 { 275 double xp = m_xs1 + m_dy / 1.3; 276 double yp = m_ys1 + m_dy * i + m_dy / 1.3; 277 if(calc_distance(x, y, xp, yp) <= m_text_height / 1.5) 278 { 279 m_cur_item = int(i); 280 return true; 281 } 282 } 283 return false; 284 } 285 286 287 //------------------------------------------------------------------------ on_mouse_move(double,double,bool)288 bool rbox_ctrl_impl::on_mouse_move(double, double, bool) 289 { 290 return false; 291 } 292 293 //------------------------------------------------------------------------ on_mouse_button_up(double,double)294 bool rbox_ctrl_impl::on_mouse_button_up(double, double) 295 { 296 return false; 297 } 298 299 //------------------------------------------------------------------------ on_arrow_keys(bool left,bool right,bool down,bool up)300 bool rbox_ctrl_impl::on_arrow_keys(bool left, bool right, bool down, bool up) 301 { 302 if(m_cur_item >= 0) 303 { 304 if(up || right) 305 { 306 m_cur_item++; 307 if(m_cur_item >= int(m_num_items)) 308 { 309 m_cur_item = 0; 310 } 311 return true; 312 } 313 314 if(down || left) 315 { 316 m_cur_item--; 317 if(m_cur_item < 0) 318 { 319 m_cur_item = m_num_items - 1; 320 } 321 return true; 322 } 323 } 324 return false; 325 } 326 327 328 } 329 330 331