00001 #include "bcpixmap.h"
00002 #include "bcresources.h"
00003 #include "bcsignals.h"
00004 #include "bctoggle.h"
00005 #include "clip.h"
00006 #include "colors.h"
00007 #include "cursors.h"
00008 #include "fonts.h"
00009 #include "vframe.h"
00010
00011 #include <string.h>
00012
00013 BC_Toggle::BC_Toggle(int x, int y,
00014 VFrame **data,
00015 int value,
00016 char *caption,
00017 int bottom_justify,
00018 int font,
00019 int color)
00020 : BC_SubWindow(x, y, 0, 0, -1)
00021 {
00022 this->data = data;
00023 for(int i = 0; i < 5; i++)
00024 images[i] = 0;
00025 bg_image = 0;
00026 status = value ? BC_Toggle::TOGGLE_CHECKED : BC_Toggle::TOGGLE_UP;
00027 this->value = value;
00028 strcpy(this->caption, caption);
00029 this->bottom_justify = bottom_justify;
00030 this->font = font;
00031 if(color >= 0)
00032 this->color = color;
00033 else
00034 this->color = get_resources()->default_text_color;
00035 select_drag = 0;
00036 enabled = 1;
00037 underline = -1;
00038 is_radial = 0;
00039 }
00040
00041
00042 BC_Toggle::~BC_Toggle()
00043 {
00044 for(int i = 0; i < 5; i++) if(images[i]) delete images[i];
00045 delete bg_image;
00046 }
00047
00048
00049 int BC_Toggle::initialize()
00050 {
00051
00052 set_images(data);
00053 calculate_extents(this,
00054 data,
00055 bottom_justify,
00056 &text_line,
00057 &w,
00058 &h,
00059 &toggle_x,
00060 &toggle_y,
00061 &text_x,
00062 &text_y,
00063 &text_w,
00064 &text_h,
00065 has_caption() ? caption : 0);
00066
00067
00068 BC_SubWindow::initialize();
00069 set_cursor(UPRIGHT_ARROW_CURSOR);
00070
00071 draw_face();
00072 return 0;
00073 }
00074
00075
00076 void BC_Toggle::calculate_extents(BC_WindowBase *gui,
00077 VFrame **images,
00078 int bottom_justify,
00079 int *text_line,
00080 int *w,
00081 int *h,
00082 int *toggle_x,
00083 int *toggle_y,
00084 int *text_x,
00085 int *text_y,
00086 int *text_w,
00087 int *text_h,
00088 char *caption)
00089 {
00090 BC_Resources *resources = get_resources();
00091 VFrame *frame = images[0];
00092 *w = frame->get_w();
00093 *h = frame->get_h();
00094 *toggle_x = 0;
00095 *toggle_y = 0;
00096 *text_x = *w + 5;
00097 *text_y = 0;
00098 *text_w = 0;
00099 *text_h = 0;
00100
00101 if(caption)
00102 {
00103 *text_w = gui->get_text_width(MEDIUMFONT, caption);
00104 *text_h = gui->get_text_height(MEDIUMFONT);
00105
00106 if(resources->toggle_highlight_bg)
00107 {
00108 *text_w += resources->toggle_text_margin * 2;
00109 *text_h = MAX(*text_h, resources->toggle_highlight_bg->get_h());
00110 }
00111
00112 if(*text_h > *h)
00113 {
00114 *toggle_y = (*text_h - *h) >> 1;
00115 *h = *text_h;
00116 }
00117 else
00118 *text_y = (*h - *text_h) >> 1;
00119
00120 if(bottom_justify)
00121 {
00122 *text_y = *h - *text_h;
00123 *text_line = *h - gui->get_text_descent(MEDIUMFONT);
00124 }
00125 else
00126 *text_line = *text_y + gui->get_text_ascent(MEDIUMFONT);
00127
00128 *w = *text_x + *text_w;
00129 }
00130
00131
00132 }
00133
00134
00135 int BC_Toggle::set_images(VFrame **data)
00136 {
00137 delete bg_image;
00138 bg_image = 0;
00139 for(int i = 0; i < 5; i++)
00140 {
00141 if(images[i]) delete images[i];
00142 images[i] = new BC_Pixmap(top_level, data[i], PIXMAP_ALPHA);
00143 }
00144 BC_Resources *resources = get_resources();
00145 if(resources->toggle_highlight_bg)
00146 {
00147 bg_image = new BC_Pixmap(top_level,
00148 resources->toggle_highlight_bg,
00149 PIXMAP_ALPHA);
00150 }
00151 return 0;
00152 }
00153
00154 void BC_Toggle::set_underline(int number)
00155 {
00156 this->underline = number;
00157 }
00158
00159
00160 void BC_Toggle::set_select_drag(int value)
00161 {
00162 this->select_drag = value;
00163 }
00164
00165 int BC_Toggle::draw_face()
00166 {
00167 BC_Resources *resources = get_resources();
00168 draw_top_background(parent_window, 0, 0, get_w(), get_h());
00169 if(has_caption())
00170 {
00171 if(enabled &&
00172 (status == BC_Toggle::TOGGLE_UPHI ||
00173 status == BC_Toggle::TOGGLE_DOWN ||
00174 status == BC_Toggle::TOGGLE_CHECKEDHI))
00175 {
00176
00177 if(bg_image)
00178 {
00179 int x = text_x;
00180 int y = text_line - get_text_ascent(MEDIUMFONT) / 2 -
00181 bg_image->get_h() / 2;
00182 int w = text_w;
00183 draw_3segmenth(x,
00184 y,
00185 w,
00186 bg_image);
00187 }
00188 else
00189
00190 {
00191 set_color(LTGREY);
00192 draw_box(text_x,
00193 text_line - get_text_ascent(MEDIUMFONT),
00194 get_w() - text_x,
00195 get_text_height(MEDIUMFONT));
00196 }
00197 }
00198
00199 set_opaque();
00200 if(enabled)
00201 set_color(color);
00202 else
00203 set_color(MEGREY);
00204 set_font(font);
00205 draw_text(text_x + resources->toggle_text_margin,
00206 text_line,
00207 caption);
00208
00209
00210 if(underline >= 0)
00211 {
00212 int x = text_x + resources->toggle_text_margin;
00213 int y = text_line + 1;
00214 int x1 = get_text_width(current_font, caption, underline) + x;
00215 int x2 = get_text_width(current_font, caption, underline + 1) + x;
00216 draw_line(x1, y, x2, y);
00217 draw_line(x1, y + 1, (x2 + x1) / 2, y + 1);
00218 }
00219 }
00220
00221 draw_pixmap(images[status]);
00222 flash();
00223 return 0;
00224 }
00225
00226 void BC_Toggle::enable()
00227 {
00228 enabled = 1;
00229 if(parent_window) draw_face();
00230 }
00231
00232 void BC_Toggle::disable()
00233 {
00234 enabled = 0;
00235 if(parent_window) draw_face();
00236 }
00237
00238 void BC_Toggle::set_status(int value)
00239 {
00240 this->status = value;
00241 }
00242
00243
00244 int BC_Toggle::repeat_event(int64_t duration)
00245 {
00246 if(duration == top_level->get_resources()->tooltip_delay &&
00247 tooltip_text[0] != 0 &&
00248 (status == BC_Toggle::TOGGLE_UPHI || status == BC_Toggle::TOGGLE_CHECKEDHI) &&
00249 !tooltip_done)
00250 {
00251 show_tooltip();
00252 tooltip_done = 1;
00253 return 1;
00254 }
00255 return 0;
00256 }
00257
00258 int BC_Toggle::cursor_enter_event()
00259 {
00260 if(top_level->event_win == win && enabled)
00261 {
00262 tooltip_done = 0;
00263 if(top_level->button_down)
00264 status = BC_Toggle::TOGGLE_DOWN;
00265 else
00266 status = value ? BC_Toggle::TOGGLE_CHECKEDHI : BC_Toggle::TOGGLE_UPHI;
00267 draw_face();
00268 }
00269 return 0;
00270 }
00271
00272 int BC_Toggle::cursor_leave_event()
00273 {
00274 hide_tooltip();
00275 if(!value && status == BC_Toggle::TOGGLE_UPHI)
00276 {
00277 status = BC_Toggle::TOGGLE_UP;
00278 draw_face();
00279 }
00280 else
00281 if(status == BC_Toggle::TOGGLE_CHECKEDHI)
00282 {
00283 status = BC_Toggle::TOGGLE_CHECKED;
00284 draw_face();
00285 }
00286 return 0;
00287 }
00288
00289 int BC_Toggle::button_press_event()
00290 {
00291 hide_tooltip();
00292 if(top_level->event_win == win && get_buttonpress() == 1 && enabled)
00293 {
00294 status = BC_Toggle::TOGGLE_DOWN;
00295
00296
00297
00298 if(select_drag)
00299 {
00300 if(!is_radial)
00301 value = !value;
00302 else
00303 value = 1;
00304 top_level->toggle_drag = 1;
00305 top_level->toggle_value = value;
00306 handle_event();
00307 }
00308
00309 draw_face();
00310 return 1;
00311 }
00312 return 0;
00313 }
00314
00315 int BC_Toggle::button_release_event()
00316 {
00317 int result = 0;
00318 hide_tooltip();
00319
00320 if(top_level->event_win == win)
00321 {
00322
00323 if(select_drag)
00324 {
00325 if(value)
00326 status = BC_Toggle::TOGGLE_CHECKEDHI;
00327 else
00328 status = BC_Toggle::TOGGLE_UPHI;
00329 top_level->toggle_drag = 0;
00330 }
00331 else
00332
00333 if(status == BC_Toggle::TOGGLE_DOWN)
00334 {
00335
00336 if(!value || is_radial)
00337 {
00338 status = BC_Toggle::TOGGLE_CHECKEDHI;
00339 value = 1;
00340 }
00341 else
00342 {
00343 status = BC_Toggle::TOGGLE_UPHI;
00344 value = 0;
00345 }
00346 result = handle_event();
00347 }
00348 draw_face();
00349 return result;
00350 }
00351 return 0;
00352 }
00353
00354 int BC_Toggle::cursor_motion_event()
00355 {
00356 if(top_level->button_down &&
00357 top_level->event_win == win &&
00358 !cursor_inside())
00359 {
00360 if(status == BC_Toggle::TOGGLE_DOWN)
00361 {
00362 if(value)
00363 status = BC_Toggle::TOGGLE_CHECKED;
00364 else
00365 status = BC_Toggle::TOGGLE_UP;
00366 draw_face();
00367 }
00368 else
00369 if(status == BC_Toggle::TOGGLE_UPHI)
00370 {
00371 status = BC_Toggle::TOGGLE_CHECKEDHI;
00372 draw_face();
00373 }
00374 }
00375 return 0;
00376 }
00377
00378 int BC_Toggle::get_value()
00379 {
00380 return value;
00381 }
00382
00383 int BC_Toggle::set_value(int value, int draw)
00384 {
00385 if(value != this->value)
00386 {
00387 this->value = value;
00388 if(value)
00389 {
00390 switch(status)
00391 {
00392 case BC_Toggle::TOGGLE_UP:
00393 status = BC_Toggle::TOGGLE_CHECKED;
00394 break;
00395 case BC_Toggle::TOGGLE_UPHI:
00396 status = BC_Toggle::TOGGLE_CHECKEDHI;
00397 break;
00398 }
00399 }
00400 else
00401 switch(status)
00402 {
00403 case BC_Toggle::TOGGLE_CHECKED:
00404 status = BC_Toggle::TOGGLE_UP;
00405 break;
00406 case BC_Toggle::TOGGLE_CHECKEDHI:
00407 status = BC_Toggle::TOGGLE_UPHI;
00408 break;
00409 }
00410 if(draw) draw_face();
00411 }
00412 return 0;
00413 }
00414
00415 int BC_Toggle::update(int value, int draw)
00416 {
00417 return set_value(value, draw);
00418 }
00419
00420 void BC_Toggle::reposition_window(int x, int y)
00421 {
00422 BC_WindowBase::reposition_window(x, y);
00423 draw_face();
00424 }
00425
00426
00427 int BC_Toggle::has_caption()
00428 {
00429 return (caption != 0 && caption[0] != 0);
00430 }
00431
00432 BC_Radial::BC_Radial(int x,
00433 int y,
00434 int value,
00435 char *caption,
00436 int font,
00437 int color)
00438 : BC_Toggle(x,
00439 y,
00440 BC_WindowBase::get_resources()->radial_images,
00441 value,
00442 caption,
00443 0,
00444 font,
00445 color)
00446 {
00447 is_radial = 1;
00448 }
00449
00450 BC_CheckBox::BC_CheckBox(int x,
00451 int y,
00452 int value,
00453 char *caption,
00454 int font,
00455 int color)
00456 : BC_Toggle(x,
00457 y,
00458 BC_WindowBase::get_resources()->checkbox_images,
00459 value,
00460 caption,
00461 0,
00462 font,
00463 color)
00464 {
00465 this->value = 0;
00466 }
00467
00468 BC_CheckBox::BC_CheckBox(int x,
00469 int y,
00470 int *value,
00471 char *caption,
00472 int font,
00473 int color)
00474 : BC_Toggle(x,
00475 y,
00476 BC_WindowBase::get_resources()->checkbox_images,
00477 *value,
00478 caption,
00479 1,
00480 font,
00481 color)
00482 {
00483 this->value = value;
00484 }
00485
00486 int BC_CheckBox::handle_event()
00487 {
00488 *value = get_value();
00489 return 1;
00490 }
00491
00492
00493
00494 BC_Label::BC_Label(int x,
00495 int y,
00496 int value,
00497 int font,
00498 int color)
00499 : BC_Toggle(x,
00500 y,
00501 BC_WindowBase::get_resources()->label_images,
00502 value,
00503 "",
00504 0,
00505 font,
00506 color)
00507 {
00508 }