#include "../include/xcv_license.h" //PCH namespace Widgets95 {//-. //<-' static int xcv_checkbox_orig_val; bool ui::boolean::_special_handler(int key, int modifiers) { boolean *c = nullptr; assert(_ui); if(key==GLUT_KEY_UP||key==GLUT_KEY_LEFT) { c = dynamic_cast(_ui->_find_prev_control(this)); } else if(key==GLUT_KEY_DOWN||key==GLUT_KEY_RIGHT) { c = dynamic_cast(_ui->_find_next_control(this)); } else return true; if(c) { int s = style()&style_item; if(s!=(c->style()&style_item) ||s==style_item &&((multiple::item*)c)->find_multiple() !=((multiple::item*)this)->find_multiple()) c = nullptr; } if(c) c->activate(); return false; } /****************************** WIDGETS_95_Checkbox::mouse_down_handler() **********/ bool ui::boolean::_mouse_down_handler(int local_x, int local_y) { xcv_checkbox_orig_val = _int_val; set_int_val(!_int_val); redraw(); return false; } /****************************** WIDGETS_95_Checkbox::mouse_up_handler() **********/ bool ui::boolean::_mouse_up_handler(int local_x, int local_y, bool inside) { if(inside) /*** Invoke the callback ***/ { //set_int_val(int_val); int nv = inside?!xcv_checkbox_orig_val:xcv_checkbox_orig_val; if(nv!=_int_val) set_int_val(nv); execute_callback(); } else set_int_val(xcv_checkbox_orig_val); /* undo effect on value */ redraw(); return false; } /****************************** WIDGETS_95_Checkbox::mouse_held_down_handler() ******/ bool ui::boolean::_mouse_held_down_handler(int local_x, int local_y, bool inside) { /********** Toggle checked and unchecked bitmap if we're entering or leaving the boolean area **********/ if(inside!=e.prev_inside) { //set_int_val(!int_val); set_int_val(inside?!xcv_checkbox_orig_val:xcv_checkbox_orig_val); redraw(); } return false; } /****************************** WIDGETS_95_Checkbox::draw() **********/ extern void xcv_bar_arrow(int arrowtype, int x, int y, int state, bool, int); void ui::boolean::_draw() { int s = style(); if(s&style_push) { int down = false; if(~s&style_fuzz) { down = 1==_int_val; } else if(_int_val) { bool desc = fuzzy(); int ay = desc?0:3; //17x17 int as = ui_bar_arrow_size; int at = desc?bottom:top; int st = desc?ui::bar::state_down:ui::bar::state_up; //NOTE: -3 depends on _update_area adding 2+2 margins. xcv_bar_arrow(at,_w-as-3,(_h-as)/2-ay,st,_enabled,false); } //2022: Inverted looks like a tab control. if(style_tab==(s&style_tab)) { down = !down; if(style_hide&s&&down) down = -1; } else if(style_hide&s&&!down) down = -1; return ((button*)this)->_draw(down); } int i; if(_int_val) { i = _enabled?bitmap::check_on:bitmap::check_on_dis; } else i = _enabled?bitmap::check_off:bitmap::check_off_dis; if(s&style_item) i+=2; //radio_off/on //DICEY: Negative margins can be useful but are //implemented selectively. int y = std::max(0,_y_off_top); if(_name.empty()) //EXPERIMENTAL { xcv_bitmaps[i]->draw(_x_lr,y); } else { //2022: This right placement layout //requires some _update_area tricks. int x = right==_placement?_w-_x_rl:_x_lr-18; xcv_bitmaps[i]->draw(x,y); if(right==_placement&&'\t'!=_name.back()) { x-=name_span(); } else x = _x_lr; //NOTE: x+=18 doesn't work for '\t'. draw_name(x,y,this==e::get_active()&&_tab_navigate); } } /************************************ WIDGETS_95_Checkbox::update_area() **********/ void ui::boolean::_update_area() { int s = style(); if(s&style_item) //multiple::item::_update_area() { if(multiple*m=((multiple::item*)this)->find_multiple()) { //HACK: Initialize multiple. This way the //constructor doesn't have to fill this out. if(_id==m->_int_val&&!_int_val) { if(!m->_text.empty()) //NEW: Enables -1. { m->set_int_val(_id); } } } } if(0==(_placement==right?_x_rl:_x_lr)) //2022 { //HACK: This is just a default auto-detect //scheme since setting placement is passive. //Without this user code would have to set //its margins manually. std::swap(_x_rl,_x_lr); } if(s&style_push) //Button? { //4: Make room for listbar's sorting arrows. int add = s&style_fuzz?4:0; int ww = _w; ((button*)this)->_update_area(add); //TODO: Don't assume standard height. //2022: Without max this chips away //every time updat_area is called. if(s&style_thin) _w = std::max(ww,_w-24); if(s&style_even) //Fudge focus-rect? { _w--; assert(_w%2==0); //For tab control. } } else //Checkbox/radio? { if(int name_w=name_span()) { _w = std::max(_w,_x_lr+name_w+6+_x_rl); //_h = ui_default_drop; //15 _h = _y_off_top+_font.height-3+_y_off_bot; //NEW } else //EXPERIMENTAL { _w = std::max(_w,_x_lr+13+_x_rl); _h = std::max(_h,_y_off_top+13+_y_off_bot); } } } //---. }//<-'