#include "../include/xcv_license.h" //PCH namespace Widgets95 {//-. //<-' static bool xcv_panel_main(ui::control *p) { return !p->_parent_node&&p->_ui&&p==p->_ui->main_panel(); } /****************************** WIDGETS_95_Panel::draw() **********/ static void xcv_panel_draw_name(ui::control &c, int x, int y, int name_w=0) //extern { if(!name_w) name_w = c.name_span(); if(!name_w) return; assert(!c._name.empty()); if('\t'!=c._name.back()) //right placement? { //right/bottom is implemented. //if(c._x_lr>ui_namespacing+2) //FIX ME? if(c.right==c._placement) { x = c._x_lr-name_w-ui_namespacing; if(x<0) { //NOTE: This may draw out-of-bounds. int cx,cw; c.column_dims(&cx,&cw); cx-=c._x_abs; x = std::max(cx,x); } } else assert(c.bottom&c._placement); } //HACK: Trying to not gray textboxes. //draw_name(x,y); //int gray = !_enabled&&_space_clicks?-1:0; int gray = 0; //TODO: Pass as argument. c.draw_active_name(x,y,c._name,gray); } void box_interface::_draw() { bool main = xcv_panel_main(this); int drop = 0; //ui_box_name_drop+1; //9 int name_w = 0; if(!main&&_placement&(left|right|top|bottom)) name_w = name_span(); int bt = _box_type; int top,bot,left = 0; if(bt==raised||bt==sunken) { top = 0; left = ui_edgespacing; //??? drop+=ui_edgespacing-1; //??? int w = 255, g = 128; if(bt==sunken) std::swap(w,g); //NEW window::draw_color(w); window::draw_border_rect(0,0,_w,_h-1,1|2); window::draw_color(g); window::draw_border_rect(-1,0,_w,_h,4|8); } else if(bt==etched) { if(name_w) { drop-=3; top = ui_panel_emboss_top; } else top = 0; bot = _h; int right = _w; if(main) { //Retain old style that chops off white edge. right++; bot++; } window::draw_etched_rect(0,top,right,bot); if(name_w) /* Only draw non-null strings */ { left = _placement&right?_w-10-name_w:8; window::draw_filled_rect(left-1,0,left+name_w+2,ui_box_name_drop,BOX_CLEAR); } } else if(bt&&(unsigned)bt<=BOX_WHITE_ON_WHITE) //box { if(_placement&bottom) drop+=1; //NEW top = _y_off_top; bot = _h-_y_off_bot; //NAIVE IMPLMENTATION //Subtract children from fill area? int dx = 0, dxx = 0; int dy = 0, dyy = 0; control *ch = first_child(); for(;ch;ch=ch->next()) if(!ch->_hidden) { int hzw = ch->_w, hzh = ch->_h; //hotzone if(!ch->_alignment) { int cmp = ch->_y_abs-_y_abs; //HACK if(top==cmp) //NEW { dy+=ch->_h; //listbar? } else if(bot==cmp+hzh) //HACK { dyy-=ch->_h; //scrollbar2? } continue; //ALIGN_EXPAND? } ch->offset_dims(&hzw,&hzh); left!=ch->_alignment?dxx-=hzw:dx+=hzw; } //-1 is because _x_rl should be 3 but is 2. int x = _x_lr, xx = _w-_x_rl-1, y = top, yy = bot; int cmp = dx+dy-dxx-dyy; int color = bt*(_enabled?1:-1); int clear = cmp>0?BOX_CLEAR:color; if(bt==BOX_WHITE_ON_WHITE) //return_on_enter? { window::draw_color(0); window::draw_border_rect(x-1,y-1,xx+1,yy+1); window::draw_color(255); window::draw_border_rect(x-2,y-2,xx+2,yy+2); window::draw_filled_rect(x,y,xx,yy,clear); } else window::draw_framed_rect(x,y,xx,yy,clear); if(cmp>0) { if(dy) y+=dy+1; //listbar? if(dyy) yy+=dyy; //scrollbar2? //The right margin omits a pixel //when adding scrollbars. if(dx) x+=dx+1; if(dxx) xx+=dxx; window::draw_filled_rect(x,y,xx,yy,color); } } else if(bt) { //NOTE: These are mostly negative, except //if a white-left edge is present. //It's just more useful for containers to //trace the area versus the "active-area". int m[4] = {0,0,_w,_h}; if(!_box_behavior) margin_rect(m); window::draw_shadow_rect(m[0],m[1],m[2],m[3],~bt); } else left = _placement&right?_w-name_w:0; if(name_w) { if(!bt) drop+=1; if(right==_placement) //??? { //HACKS //Should be 3 unless pushed down artificially. //drop = ui_boxinnermarginx; //font.height; //13 //ARBITRARY drop = _y_off_top+1; } xcv_panel_draw_name(*this,left,drop,name_w); } } /************************************** WIDGETS_95_Panel::update_area() **********/ void box_interface::_update_area() { bool main = xcv_panel_main(this); int name_w = 0; if(!main&&_placement&(left|right|top|bottom)) name_w = name_span(); _w = std::max(_w,name_w+16); int m = 2; //NEW: Etched bar width. switch(int bt=_box_type) { case sunken: case raised: m = -1; //break; case etched: { _y_off_top = m+ui_edgespacing; _y_off_bot = m+ui_edgespacing; if(name_w) switch(bt) { case etched: _y_off_top+=8; break; default: case sunken: case raised: _y_off_top+=14; break; } _x_lr = _x_rl = m+ui_edgespacing; if(main&&m==2) //etched? { _y_off_bot--; _x_rl--; } break; } default: //BOX (textbox, wordproc, etc.) if((unsigned)bt>BOX_WHITE_ON_WHITE) goto shadow; //NOTE: 2 is ui_boxoutermarginx, but currently //the bottom margin is 3. if(name_w) //HACK { if(_placement&bottom) //UNFINISHED _y_off_top = std::max(ui_default_drop+ui_itemspacing+2,_y_off_top); } _x_lr = std::max(2,_x_lr); //It's really 3 pixels but want to shift scrollbar/spinner. _x_rl = std::max(2,_x_rl); _y_off_top = std::max(2,_y_off_top); _y_off_bot = std::max(3,_y_off_bot); //2 break; case none: shadow: if(name_w) if(right==_placement) //2022 { //I'm trying to put a multiple on single //row. Normally the margin would be set //in the constructor. This may be fitted //too tight. _x_lr = std::max(_x_rl,name_w+ui_namespacing-ui_boxoutermarginx); } else //bottom? { assert(_placement&bottom); //_draw will drop the name down ui_boxoutermarginx instead. _y_off_top = std::max (_y_off_top,ui_default_drop+ui_itemspacing/*-ui_boxoutermarginx*/); } break; } } //---. }//<-'