// returns true if created a new page bool HtmlFormatter::FlushCurrLine(bool isParagraphBreak) { if (IsCurrLineEmpty()) { currX = NewLineX(); currLineTopPadding = 0; // remove all spaces (only keep SetFont, LinkStart and Anchor instructions) for (size_t k = currLineInstr.size(); k > 0; k--) { DrawInstr& i = currLineInstr.at(k - 1); if (InstrFixedSpace == i.type || InstrElasticSpace == i.type) currLineInstr.RemoveAt(k - 1); } return false; } AlignAttr align = CurrStyle()->align; if (isParagraphBreak && (Align_Justify == align)) align = Align_Left; JustifyCurrLine(align); // create a new page if necessary float totalLineDy = CurrLineDy() + currLineTopPadding; bool createdPage = false; if (currY + totalLineDy > pageDy) { // current line too big to fit in current page, // so need to start another page UpdateLinkBboxes(currPage); pagesToSend.Append(currPage); // instructions for each page need to be self-contained // so we have to carry over some state (like current font) CrashIf(!CurrFont()); EmitNewPage(); CrashIf(currLineReparseIdx > INT_MAX); currPage->reparseIdx = (int)currLineReparseIdx; createdPage = true; } SetYPos(currLineInstr, currY + currLineTopPadding); currY += totalLineDy; DrawInstr link; if (currLinkIdx) { link = currLineInstr.at(currLinkIdx - 1); // TODO: this occasionally leads to empty links AppendInstr(DrawInstr(InstrLinkEnd)); } currPage->instructions.Append(currLineInstr.LendData(), currLineInstr.size()); currLineInstr.Reset(); currLineReparseIdx = -1; // mark as not set currLineTopPadding = 0; currX = NewLineX(); if (currLinkIdx) { AppendInstr(DrawInstr::LinkStart(link.str.s, link.str.len)); currLinkIdx = currLineInstr.size(); } nextPageStyle = styleStack.Last(); return createdPage; }
void HtmlFormatter::EmitElasticSpace() { if (!CanEmitElasticSpace(currX, NewLineX(), pageDx - spaceDx, currLineInstr)) return; EnsureDx(spaceDx); currX += spaceDx; AppendInstr(DrawInstr(InstrElasticSpace)); }
//==== Add Sub Group Layout At Current Position ====// void GroupLayout::AddCounter( Counter & count, const char* label ) { assert( m_Group && m_Screen ); //==== Counter Button ====// VspButton* button = NULL; if ( strcmp( label, "" ) != 0 ) { VspButton* button = AddParmButton( label ); button->align( Fl_Align( FL_ALIGN_CLIP ) ); } //==== Counter ====// int counter_w = FitWidth( m_ButtonWidth, m_SliderWidth ); Fl_Counter* fl_counter = new Fl_Counter( m_X, m_Y, counter_w, m_StdHeight ); fl_counter->type( FL_SIMPLE_COUNTER ); fl_counter->minimum( 0 ); fl_counter->maximum( 10000 ); fl_counter->step( 1 ); m_Group->add( fl_counter ); AddX( counter_w ); count.Init( m_Screen, fl_counter, button ); AddY( m_StdHeight ); NewLineX(); }
//==== Add Geom Picker ====// void GroupLayout::AddGeomPicker( GeomPicker & geom_picker ) { assert( m_Group && m_Screen ); //==== Geom Button ====// Fl_Button* button = new Fl_Button( m_X, m_Y, m_ChoiceButtonWidth, m_StdHeight, "Geom" ); button->box( FL_THIN_UP_BOX ); button->labelfont( 1 ); button->labelsize( 12 ); button->labelcolor( FL_BLACK ); m_Group->add( button ); AddX( m_ChoiceButtonWidth ); //==== Geom Picker ====// int choice_w = FitWidth( m_ChoiceButtonWidth, m_SliderWidth ); Fl_Choice* geom_choice = new Fl_Choice( m_X, m_Y, choice_w, m_StdHeight ); geom_choice->down_box( FL_BORDER_BOX ); geom_choice->textfont( 1 ); geom_choice->textsize( 12 ); geom_choice->textcolor( FL_DARK_BLUE ); m_Group->add( geom_choice ); AddX( choice_w ); AddY( m_StdHeight ); NewLineX(); geom_picker.Init( m_Screen, geom_choice ); }
//==== Create & Init Index Selector ====// void GroupLayout::AddIndexSelector( IndexSelector& selector ) { assert( m_Group && m_Screen ); int butw = 5 * m_ButtonWidth / 6; Fl_Button* but_ll = new Fl_Button( m_X, m_Y, butw, m_StdHeight, "<<" ); but_ll->box( FL_THIN_UP_BOX ); but_ll->labelfont( 1 ); but_ll->labelsize( 20 ); but_ll->labelcolor( ( Fl_Color )4 ); but_ll->align( Fl_Align( FL_ALIGN_CLIP ) ); AddX( butw ); Fl_Button* but_l = new Fl_Button( m_X, m_Y, butw, m_StdHeight, "<" ); but_l->box( FL_THIN_UP_BOX ); but_l->labelfont( 1 ); but_l->labelsize( 20 ); but_l->labelcolor( ( Fl_Color )4 ); but_l->align( Fl_Align( FL_ALIGN_CLIP ) ); AddX( butw ); int iw = FitWidth( 4 * butw, m_InputWidth ); Fl_Int_Input* int_inp = new Fl_Int_Input( m_X + 4, m_Y, iw - 8, m_StdHeight ); int_inp->type( 2 ); int_inp->box( FL_THIN_DOWN_BOX ); int_inp->labelfont( 1 ); int_inp->textsize( 14 ); int_inp->align( Fl_Align( FL_ALIGN_CENTER ) ); int_inp->when( FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE ); AddX( iw ); Fl_Button* but_r = new Fl_Button( m_X, m_Y, butw, m_StdHeight, ">" ); but_r->box( FL_THIN_UP_BOX ); but_r->labelfont( 1 ); but_r->labelsize( 20 ); but_r->labelcolor( ( Fl_Color )4 ); but_r->align( Fl_Align( FL_ALIGN_CLIP ) ); AddX( butw ); Fl_Button* but_rr = new Fl_Button( m_X, m_Y, butw, m_StdHeight, ">>" ); but_rr->box( FL_THIN_UP_BOX ); but_rr->labelfont( 1 ); but_rr->labelsize( 20 ); but_rr->labelcolor( ( Fl_Color )4 ); but_rr->align( Fl_Align( FL_ALIGN_CLIP ) ); AddX( butw ); selector.Init( m_Screen, but_ll, but_l, int_inp, but_r, but_rr ); AddY( m_StdHeight ); NewLineX(); }
void HtmlFormatter::HandleTagList(HtmlToken* t) { FlushCurrLine(true); if (t->IsStartTag()) listDepth++; else if (t->IsEndTag() && listDepth > 0) listDepth--; currX = NewLineX(); }
// add horizontal line (<hr> in html terms) void HtmlFormatter::EmitHr() { // hr creates an implicit paragraph break FlushCurrLine(true); CrashIf(NewLineX() != currX); RectF bbox(0.f, 0.f, pageDx, lineSpacing); AppendInstr(DrawInstr(InstrLine, bbox)); FlushCurrLine(true); }
void HtmlFormatter::EmitParagraph(float indent) { FlushCurrLine(true); CrashIf(NewLineX() != currX); bool needsIndent = Align_Left == CurrStyle()->align || Align_Justify == CurrStyle()->align; if (indent > 0 && needsIndent && EnsureDx(indent)) { AppendInstr(DrawInstr::FixedSpace(indent)); currX += indent; } }
// a text run is a string of consecutive text with uniform style void HtmlFormatter::EmitTextRun(const char* s, const char* end) { currReparseIdx = s - htmlParser->Start(); CrashIf(!ValidReparseIdx(currReparseIdx, htmlParser)); CrashIf(IsSpaceOnly(s, end) && !preFormatted); const char* tmp = ResolveHtmlEntities(s, end, textAllocator); bool resolved = tmp != s; if (resolved) { s = tmp; end = s + str::Len(s); } while (s < end) { // don't update the reparseIdx if s doesn't point into the original source if (!resolved) currReparseIdx = s - htmlParser->Start(); size_t strLen = str::Utf8ToWcharBuf(s, end - s, buf, dimof(buf)); // soft hyphens should not be displayed strLen -= str::RemoveChars(buf, L"\xad"); if (0 == strLen) break; textMeasure->SetFont(CurrFont()); RectF bbox = textMeasure->Measure(buf, strLen); EnsureDx(bbox.Width); if (bbox.Width <= pageDx - currX) { AppendInstr(DrawInstr::Str(s, end - s, bbox, dirRtl)); currX += bbox.Width; break; } size_t lenThatFits = StringLenForWidth(textMeasure, buf, strLen, pageDx - NewLineX()); // try to prevent a break in the middle of a word if (iswalnum(buf[lenThatFits])) { for (size_t len = lenThatFits; len > 0; len--) { if (!iswalnum(buf[len - 1])) { lenThatFits = len; break; } } } textMeasure->SetFont(CurrFont()); bbox = textMeasure->Measure(buf, lenThatFits); CrashIf(bbox.Width > pageDx); // s is UTF-8 and buf is UTF-16, so one // WCHAR doesn't always equal one char // TODO: this usually fails for non-BMP characters (i.e. hardly ever) for (size_t i = lenThatFits; i > 0; i--) { lenThatFits += buf[i - 1] < 0x80 ? 0 : buf[i - 1] < 0x800 ? 1 : 2; } AppendInstr(DrawInstr::Str(s, lenThatFits, bbox, dirRtl)); currX += bbox.Width; s += lenThatFits; } }
void HtmlFormatter::ForceNewPage() { bool createdNewPage = FlushCurrLine(true); if (createdNewPage) return; UpdateLinkBboxes(currPage); pagesToSend.Append(currPage); EmitNewPage(); currX = NewLineX(); currLineTopPadding = 0.f; }
//==== Add Parameter Tree Picker ====// void GroupLayout::AddParmTreePicker( ParmTreePicker & parm_tree_picker, int w, int h ) { assert( m_Group && m_Screen ); Fl_Tree* parm_tree = new Fl_Tree( m_X, m_Y, w, h ); m_Group->add( parm_tree ); AddY( h ); NewLineX(); parm_tree_picker.Init( m_Screen, parm_tree ); }
//==== Create & Init Gui Slider Adjustable Range ====// void GroupLayout::AddSlider( SliderAdjRangeInput& slid_adj_input, const char* label, double range, const char* format ) { assert( m_Group && m_Screen ); int init_used_w = m_X - m_Group->x(); //==== Parm Button ====// VspButton* button = AddParmButton( label ); //==== Range Button ====// Fl_Repeat_Button* lbutton = new Fl_Repeat_Button( m_X, m_Y, m_RangeButtonWidth, m_StdHeight, "<" ); lbutton->box( FL_THIN_UP_BOX ); lbutton->labelcolor( ( Fl_Color )4 ); m_Group->add( lbutton ); AddX( m_RangeButtonWidth ); //==== Slider ====// int sw = FitWidth( m_ButtonWidth + 2 * m_RangeButtonWidth + m_InputWidth + init_used_w, m_SliderWidth ); Fl_Slider* slider = new Fl_Slider( m_X, m_Y, sw, m_StdHeight ); slider->type( 5 ); slider->box( FL_THIN_DOWN_BOX ); slider->color( FL_BACKGROUND2_COLOR ); slider->selection_color( FL_SELECTION_COLOR ); m_Group->add( slider ); AddX( sw ); //==== Range Button ====// Fl_Repeat_Button* rbutton = new Fl_Repeat_Button( m_X, m_Y, m_RangeButtonWidth, m_StdHeight, "<" ); rbutton->box( FL_THIN_UP_BOX ); rbutton->labelcolor( ( Fl_Color )4 ); m_Group->add( rbutton ); AddX( m_RangeButtonWidth ); //==== Input ====// Fl_Float_Input* input = new Fl_Float_Input( m_X, m_Y, m_InputWidth, m_StdHeight ); input->type( 1 ); input->box( FL_THIN_DOWN_BOX ); input->textsize( 12 ); input->when( FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE ); m_Group->add( input ); AddX( m_InputWidth ); AddY( m_StdHeight ); NewLineX(); slid_adj_input.Init( m_Screen, slider, lbutton, rbutton, input, range, format, button ); if( strcmp( label, "AUTO_UPDATE" ) == 0 || strcmp( label, "" ) == 0 ) { slid_adj_input.SetButtonNameUpdate( true ); } }
//==== Add Fl Text Editor ====// Fl_Text_Editor* GroupLayout::AddFlTextEditor( int height ) { assert( m_Group && m_Screen ); Fl_Text_Editor* text_editor = new Fl_Text_Editor (m_X, m_Y, m_W, height, ""); m_Group->add( text_editor ); AddY( height ); NewLineX(); return text_editor; }
//==== Add Fl Text Display ====// Fl_Text_Display* GroupLayout::AddFlTextDisplay( int height ) { assert( m_Group && m_Screen ); Fl_Text_Display* text_display = new Fl_Text_Display (m_X, m_Y, m_W, height, ""); m_Group->add( text_display ); AddY( height ); NewLineX(); return text_display; }
//==== Add Fl Browser ====// Fl_Browser* GroupLayout::AddFlBrowser( int height ) { assert( m_Group && m_Screen ); Fl_Browser* browser = new Fl_Browser( m_X, m_Y, m_W, height); browser->type(2); browser->textsize(12); m_Group->add( browser ); AddY( height ); NewLineX(); return browser; }
// sum of widths of all elements with a fixed size and flexible // spaces (using minimum value for its width) REAL HtmlFormatter::CurrLineDx() { REAL dx = NewLineX(); for (DrawInstr& i : currLineInstr) { if (InstrString == i.type || InstrRtlString == i.type) { dx += i.bbox.Width; } else if (InstrImage == i.type) { dx += i.bbox.Width; } else if (InstrElasticSpace == i.type) { dx += spaceDx; } else if (InstrFixedSpace == i.type) { dx += i.bbox.Width; } } return dx; }
void HtmlFormatter::EmitEmptyLine(float lineDy) { CrashIf(!IsCurrLineEmpty()); currY += lineDy; if (currY <= pageDy) { currX = NewLineX(); // remove all spaces (only keep SetFont, LinkStart and Anchor instructions) for (size_t k = currLineInstr.size(); k > 0; k--) { DrawInstr& i = currLineInstr.at(k - 1); if (InstrFixedSpace == i.type || InstrElasticSpace == i.type) currLineInstr.RemoveAt(k - 1); } return; } ForceNewPage(); }
//==== Add Fl_CheckBrowser ====// Fl_Check_Browser* GroupLayout::AddCheckBrowser( int h ) { int w = FitWidth( 0, m_DividerHeight ); Fl_Check_Browser* check_browser = new Fl_Check_Browser( m_X, m_Y, w, h ); check_browser->labelfont( 1 ); check_browser->textsize( 12 ); check_browser->when( FL_WHEN_RELEASE ); m_Group->add( check_browser ); AddX( w ); AddY( m_StdHeight ); NewLineX(); return check_browser; }
//==== Create & Init Choice ====// void GroupLayout::AddChoice( Choice & choice, const char* label, int used_w ) { assert( m_Group && m_Screen ); //==== Choice Button ====// VspButton* button = new VspButton( m_X, m_Y, m_ChoiceButtonWidth, m_StdHeight, label ); button->box( FL_THIN_UP_BOX ); button->labelfont( 1 ); button->labelsize( 12 ); button->labelcolor( FL_BLACK ); button->copy_label( label ); m_Group->add( button ); AddX( m_ChoiceButtonWidth ); //==== Choice Picker ====// int choice_w = FitWidth( m_ChoiceButtonWidth + used_w, m_SliderWidth ); Fl_Choice* fl_choice = new Fl_Choice( m_X, m_Y, choice_w, m_StdHeight ); fl_choice->down_box( FL_BORDER_BOX ); fl_choice->textfont( 1 ); fl_choice->textsize( 12 ); fl_choice->textcolor( FL_DARK_BLUE ); m_Group->add( fl_choice ); AddX( choice_w ); //==== Add Choice Text ===// vector< string > choice_vec = choice.GetItems(); for ( int i = 0 ; i < ( int )choice_vec.size() ; i++ ) { fl_choice->add( choice_vec[i].c_str() ); } fl_choice->value( 0 ); choice.Init( m_Screen, fl_choice, button ); if( strcmp( label, "AUTO_UPDATE" ) == 0 || strcmp( label, "" ) == 0 ) { choice.SetButtonNameUpdate( true ); } AddY( m_StdHeight ); NewLineX(); }
//==== Create & Init Box Divider ====// void GroupLayout::AddDividerBox( const string& text, int used_w ) { assert( m_Group && m_Screen ); //==== Add Divider Box ====// int dw = FitWidth( used_w, m_ButtonWidth ); Fl_Box* flbox = new Fl_Box( m_X, m_Y, dw, m_DividerHeight ); flbox->box( FL_BORDER_BOX ); flbox->color( ( Fl_Color )12 ); flbox->labelfont( 1 ); flbox->labelcolor( FL_BACKGROUND2_COLOR ); flbox->copy_label( text.c_str() ); m_Group->add( flbox ); AddX( dw ); AddY( m_DividerHeight ); NewLineX(); }
//==== Create & Init Gui ParmButton ====// void GroupLayout::AddButton( ParmButton& pbutton, const char* label ) { assert( m_Group && m_Screen ); //==== Add Parm Button ====// int bw = FitWidth( 0, m_ButtonWidth ); VspButton* flbutton = new VspButton( m_X, m_Y, bw, m_StdHeight, label ); flbutton->copy_label( label ); flbutton->labelfont( 1 ); flbutton->labelsize( 12 ); flbutton->labelcolor( FL_DARK_BLUE ); m_Group->add( flbutton ); AddX( bw ); AddY( m_StdHeight ); NewLineX(); pbutton.Init( m_Screen, flbutton ); }
//==== Create & Init Gui ToggleButton ====// void GroupLayout::AddButton( CheckButtonBit& cbutton, const char* label, int value ) { assert( m_Group && m_Screen ); //==== Add Check Button ====// int bw = FitWidth( 0, m_ButtonWidth ); Fl_Light_Button* flbutton = new Fl_Light_Button( m_X, m_Y, bw, m_StdHeight, label ); flbutton->labelfont( 1 ); flbutton->labelsize( 12 ); flbutton->align( Fl_Align( 132 | FL_ALIGN_INSIDE ) ); flbutton->labelcolor( FL_DARK_BLUE ); flbutton->copy_label( label ); m_Group->add( flbutton ); AddX( bw ); AddY( m_StdHeight ); NewLineX(); cbutton.Init( m_Screen, flbutton, value ); }
//==== Create & Init Text Input ====// void GroupLayout::AddInput( StringInput& text_input, const char* label ) { assert( m_Group && m_Screen ); //==== Button ====// AddParmButton( label ); //==== Add Text Input ====// int iw = FitWidth( m_ButtonWidth, m_InputWidth ); Fl_Input* input = new Fl_Input( m_X, m_Y, iw, m_StdHeight ); input->box( FL_THIN_DOWN_BOX ); input->textsize( 12 ); input->when( FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE ); m_Group->add( input ); AddX( iw ); AddY( m_StdHeight ); NewLineX(); text_input.Init( m_Screen, input ); }
//==== Create & Init Gui CheckButton ====// void GroupLayout::AddButton( CheckButton& cbutton, const char* label ) { assert( m_Group && m_Screen ); //==== Add Check Button ====// int bw = FitWidth( 0, m_ButtonWidth ); Fl_Check_Button* flbutton = new Fl_Check_Button( m_X, m_Y, bw, m_StdHeight, label ); flbutton->box( FL_DOWN_BOX ); flbutton->down_box( FL_DOWN_BOX ); flbutton->labelfont( 1 ); flbutton->labelsize( 12 ); flbutton->labelcolor( FL_DARK_BLUE ); flbutton->copy_label( label ); m_Group->add( flbutton ); AddX( bw ); AddY( m_StdHeight ); NewLineX(); cbutton.Init( m_Screen, flbutton ); }
//==== Create & Init Float Input ====// void GroupLayout::AddInput( Input& input, const char* label, const char* format ) { assert( m_Group && m_Screen ); //==== Parm Button ====// VspButton* button = AddParmButton( label ); //==== Add Text Input ====// int iw = FitWidth( m_ButtonWidth, m_InputWidth ); Fl_Input* flinput = new Fl_Input( m_X, m_Y, iw, m_StdHeight ); flinput->type( 1 ); flinput->box( FL_THIN_DOWN_BOX ); flinput->textsize( 12 ); flinput->when( FL_WHEN_ENTER_KEY | FL_WHEN_RELEASE ); m_Group->add( flinput ); AddX( iw ); AddY( m_StdHeight ); NewLineX(); input.Init( m_Screen, flinput, format, button ); }
// When this is called, Width and Height of each element is already set // We set position x of each visible element void HtmlFormatter::LayoutLeftStartingAt(REAL offX) { DrawInstr* lastInstr = nullptr; int instrCount = 0; REAL x = offX + NewLineX(); for (DrawInstr& i : currLineInstr) { if (InstrString == i.type || InstrRtlString == i.type || InstrImage == i.type) { i.bbox.X = x; x += i.bbox.Width; lastInstr = &i; instrCount++; } else if (InstrElasticSpace == i.type) { x += spaceDx; } else if (InstrFixedSpace == i.type) { x += i.bbox.Width; } } // center a single image if (instrCount == 1 && InstrImage == lastInstr->type) lastInstr->bbox.X = (pageDx - lastInstr->bbox.Width) / 2.f; }
//==== Create & Init Text Output ====// void GroupLayout::AddOutput( StringOutput& string_output, const char* label ) { assert( m_Group && m_Screen ); //==== Button ====// AddParmButton( label ); //==== Add Text Input ====// int iw = FitWidth( m_ButtonWidth, m_InputWidth ); Fl_Output* output = new Fl_Output( m_X, m_Y, iw, m_StdHeight ); output->color( ( Fl_Color )23 ); output->labelfont( 1 ); output->labelsize( 12 ); output->textfont( 1 ); output->textsize( 12 ); m_Group->add( output ); AddX( iw ); AddY( m_StdHeight ); NewLineX(); string_output.Init( m_Screen, output ); }
//==== Add Parameter Picker ====// void GroupLayout::AddParmPicker( ParmPicker & parm_picker ) { assert( m_Group && m_Screen ); //==== Container Button ====// Fl_Button* button = new Fl_Button( m_X, m_Y, m_ChoiceButtonWidth, m_StdHeight, "Container" ); button->box( FL_THIN_UP_BOX ); button->labelfont( 1 ); button->labelsize( 12 ); button->labelcolor( FL_BLACK ); m_Group->add( button ); AddX( m_ChoiceButtonWidth ); //==== Container Picker ====// int choice_w = FitWidth( m_ChoiceButtonWidth, m_SliderWidth ); Fl_Choice* container_choice = new Fl_Choice( m_X, m_Y, choice_w, m_StdHeight ); container_choice->down_box( FL_BORDER_BOX ); container_choice->textfont( 1 ); container_choice->textsize( 12 ); container_choice->textcolor( FL_DARK_BLUE ); m_Group->add( container_choice ); AddX( choice_w ); AddY( m_StdHeight ); NewLineX(); //==== Group Button ====// button = new Fl_Button( m_X, m_Y, m_ChoiceButtonWidth, m_StdHeight, "Group" ); button->box( FL_THIN_UP_BOX ); button->labelfont( 1 ); button->labelsize( 12 ); button->labelcolor( FL_BLACK ); m_Group->add( button ); AddX( m_ChoiceButtonWidth ); //==== Group Picker ====// choice_w = FitWidth( m_ChoiceButtonWidth, m_SliderWidth ); Fl_Choice* group_choice = new Fl_Choice( m_X, m_Y, choice_w, m_StdHeight ); group_choice->down_box( FL_BORDER_BOX ); group_choice->textfont( 1 ); group_choice->textsize( 12 ); group_choice->textcolor( FL_DARK_BLUE ); m_Group->add( group_choice ); AddX( choice_w ); AddY( m_StdHeight ); NewLineX(); //==== Parm Button ====// button = new Fl_Button( m_X, m_Y, m_ChoiceButtonWidth, m_StdHeight, "Parm" ); button->box( FL_THIN_UP_BOX ); button->labelfont( 1 ); button->labelsize( 12 ); button->labelcolor( FL_BLACK ); m_Group->add( button ); AddX( m_ChoiceButtonWidth ); //==== Parm Picker ====// choice_w = FitWidth( m_ChoiceButtonWidth, m_SliderWidth ); Fl_Choice* parm_choice = new Fl_Choice( m_X, m_Y, choice_w, m_StdHeight ); parm_choice->down_box( FL_BORDER_BOX ); parm_choice->textfont( 1 ); parm_choice->textsize( 12 ); parm_choice->textcolor( FL_DARK_BLUE ); m_Group->add( parm_choice ); AddX( choice_w ); AddY( m_StdHeight ); NewLineX(); parm_picker.Init( m_Screen, container_choice, group_choice, parm_choice ); }
//==== Add Color Picker ====// void GroupLayout::AddColorPicker( ColorPicker& picker ) { assert( m_Group && m_Screen ); //==== Button ====// Fl_Button* colorButton = new Fl_Button( m_X, m_Y, m_ButtonWidth, m_StdHeight * 2, "Color:" ); colorButton->box( FL_THIN_UP_BOX ); colorButton->labelfont( 1 ); colorButton->labelsize( 12 ); colorButton->labelcolor( FL_BLACK ); m_Group->add( colorButton ); AddX( m_ButtonWidth ); //==== Current Color Button ====// Fl_Button* primColorButton = new Fl_Button( m_X, m_Y, m_ButtonWidth / 2, m_StdHeight * 2 ); primColorButton->box( FL_THIN_DOWN_BOX ); primColorButton->color( ( Fl_Color )2 ); m_Group->add( primColorButton ); AddX( m_ButtonWidth / 2 + 2 ); //==== Sliders ====// int ch = 2 * m_StdHeight / 3; int cw = m_StdHeight; int sw = FitWidth( m_ButtonWidth + m_ButtonWidth / 2 + 2 + 4 * cw, m_SliderWidth ); Fl_Slider* sliders[3]; for ( int i = 0 ; i < 3 ; i++ ) { sliders[i] = new Fl_Value_Slider( m_X, m_Y + i * ch, sw, ch ); sliders[i]->type( 5 ); sliders[i]->color( FL_BACKGROUND2_COLOR ); sliders[i]->selection_color( ( Fl_Color )1 ); sliders[i]->maximum( 255 ); sliders[i]->step( 1 ); m_Group->add( sliders[i] ); } sliders[0]->selection_color( ( Fl_Color )1 ); sliders[1]->selection_color( ( Fl_Color )2 ); sliders[2]->selection_color( ( Fl_Color )4 ); AddX( sw + 2 ); //==== Color Buttons ====// vector< Fl_Button* > cvec; int color_index = 0; for ( int i = 0 ; i < 4 ; i++ ) { for ( int j = 0 ; j < 3 ; j++ ) { Fl_Button* b = new Fl_Button( m_X + i * cw, m_Y + j * ch, cw, ch ); vec3d rgb = picker.GetIndexRGB( color_index ); Fl_Color c = fl_rgb_color( ( int )rgb[0], ( int )rgb[1], ( int )rgb[2] ); b->color( c ); m_Group->add( b ); cvec.push_back( b ); color_index++; } } AddX( 3 * cw ); picker.Init( m_Screen, colorButton, primColorButton, cvec, sliders ); AddY( m_StdHeight * 2 ); NewLineX(); }
void GroupLayout::AddSkinHeader( SkinHeader & skin_header ) { assert( m_Group && m_Screen ); int oldBW = GetButtonWidth(); bool saveFitWidth = m_FitWidthFlag; bool saveSameLine = m_SameLineFlag; vector< VspButton* > buttons; // Size of Set label buttons int setW = 25; // Size of Equal label button int eqW = 20; // Width of choice int cw = m_ChoiceButtonWidth + m_SliderWidth; m_FitWidthFlag = true; // Gap width int gw = FitWidth( 2 * setW + eqW + oldBW + 2 * cw, 2 * m_ButtonWidth )/2; m_FitWidthFlag = false; m_SameLineFlag = true; Choice* cont_choice = new Choice(); cont_choice->AddItem( "C0" ); cont_choice->AddItem( "C1" ); cont_choice->AddItem( "C2" ); AddChoice( *cont_choice, "Enforce" ); AddX( gw ); //==== Left Set Button ====// SetButtonWidth( setW ); buttons.push_back( AddParmButton( "Set" ) ); AddX( oldBW ); //==== Equal Button ====// SetButtonWidth( eqW ); buttons.push_back( AddParmButton( "=" ) ); //==== Right Set Button ====// SetButtonWidth( setW ); buttons.push_back( AddParmButton( "Set" ) ); NewLineX(); m_FitWidthFlag = saveFitWidth; m_SameLineFlag = saveSameLine; skin_header.Init( m_Screen, cont_choice, buttons ); ForceNewLine(); SetButtonWidth( oldBW ); }