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