| @@ -33,21 +33,21 @@ struct SequentialLayout : virtual Widget { | |||
| struct Label : VirtualWidget { | |||
| std::string text; | |||
| float fontSize; | |||
| NVGcolor color; | |||
| enum Alignment { | |||
| LEFT_ALIGNMENT, | |||
| CENTER_ALIGNMENT, | |||
| RIGHT_ALIGNMENT, | |||
| }; | |||
| Alignment alignment = LEFT_ALIGNMENT; | |||
| Label() { | |||
| box.size.y = BND_WIDGET_HEIGHT; | |||
| } | |||
| Label(); | |||
| void draw(NVGcontext *vg) override; | |||
| }; | |||
| struct List : OpaqueWidget { | |||
| void step() override; | |||
| void draw(NVGcontext *vg) override; | |||
| }; | |||
| /** Deletes itself from parent when clicked */ | |||
| @@ -5,7 +5,7 @@ | |||
| #include <algorithm> | |||
| #define BND_LABEL_FONT_SIZE 13 | |||
| static const float itemMargin = 2.0; | |||
| namespace rack { | |||
| @@ -51,13 +51,15 @@ struct FavoriteRadioButton : RadioButton { | |||
| struct SeparatorItem : OpaqueWidget { | |||
| SeparatorItem() { | |||
| box.size.y = BND_WIDGET_HEIGHT; | |||
| box.size.y = 2*BND_WIDGET_HEIGHT + 2*itemMargin; | |||
| } | |||
| void setText(std::string text) { | |||
| clearChildren(); | |||
| Label *label = Widget::create<Label>(Vec(0, 0)); | |||
| Label *label = Widget::create<Label>(Vec(0, 12 + itemMargin)); | |||
| label->text = text; | |||
| label->fontSize = 20; | |||
| label->color.a *= 0.25; | |||
| addChild(label); | |||
| } | |||
| }; | |||
| @@ -67,7 +69,7 @@ struct BrowserListItem : OpaqueWidget { | |||
| bool selected = false; | |||
| BrowserListItem() { | |||
| box.size.y = 2 * BND_WIDGET_HEIGHT + 7; | |||
| box.size.y = BND_WIDGET_HEIGHT + 2*itemMargin; | |||
| } | |||
| void draw(NVGcontext *vg) override { | |||
| @@ -100,21 +102,26 @@ struct ModelItem : BrowserListItem { | |||
| Model *model; | |||
| Label *authorLabel; | |||
| ModelItem() { | |||
| box.size.y = 2*BND_WIDGET_HEIGHT + 3*itemMargin; | |||
| } | |||
| void setModel(Model *model) { | |||
| clearChildren(); | |||
| assert(model); | |||
| this->model = model; | |||
| Label *nameLabel = Widget::create<Label>(Vec(0, 0)); | |||
| Label *nameLabel = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||
| nameLabel->text = model->name; | |||
| addChild(nameLabel); | |||
| authorLabel = Widget::create<Label>(Vec(0, 0)); | |||
| authorLabel = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||
| authorLabel->alignment = Label::RIGHT_ALIGNMENT; | |||
| authorLabel->text = model->author; | |||
| authorLabel->color.a = 0.5; | |||
| addChild(authorLabel); | |||
| SequentialLayout *layout2 = Widget::create<SequentialLayout>(Vec(7, BND_WIDGET_HEIGHT)); | |||
| SequentialLayout *layout2 = Widget::create<SequentialLayout>(Vec(7, BND_WIDGET_HEIGHT + itemMargin)); | |||
| layout2->spacing = 0; | |||
| addChild(layout2); | |||
| @@ -136,6 +143,7 @@ struct ModelItem : BrowserListItem { | |||
| // } | |||
| Label *tagsLabel = new Label(); | |||
| tagsLabel->color.a = 0.5; | |||
| int i = 0; | |||
| for (ModelTag tag : model->tags) { | |||
| if (i++ > 0) | |||
| @@ -166,7 +174,7 @@ struct AuthorItem : BrowserListItem { | |||
| void setAuthor(std::string author) { | |||
| clearChildren(); | |||
| this->author = author; | |||
| Label *authorLabel = Widget::create<Label>(Vec(0, 0)); | |||
| Label *authorLabel = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||
| if (author.empty()) | |||
| authorLabel->text = "Show all modules"; | |||
| else | |||
| @@ -184,7 +192,7 @@ struct TagItem : BrowserListItem { | |||
| void setTag(ModelTag tag) { | |||
| clearChildren(); | |||
| this->tag = tag; | |||
| Label *tagLabel = Widget::create<Label>(Vec(0, 0)); | |||
| Label *tagLabel = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||
| if (tag == NO_TAG) | |||
| tagLabel->text = "Show all tags"; | |||
| else | |||
| @@ -198,7 +206,7 @@ struct TagItem : BrowserListItem { | |||
| struct ClearFilterItem : BrowserListItem { | |||
| ClearFilterItem() { | |||
| Label *label = Widget::create<Label>(Vec(0, 0)); | |||
| Label *label = Widget::create<Label>(Vec(0, 0 + itemMargin)); | |||
| label->text = "Clear filter"; | |||
| addChild(label); | |||
| } | |||
| @@ -332,6 +340,11 @@ struct ModuleBrowser : VirtualWidget { | |||
| clearSearch(); | |||
| } | |||
| void draw(NVGcontext *vg) override { | |||
| bndMenuBackground(vg, 0.0, 0.0, box.size.x, box.size.y, BND_CORNER_NONE); | |||
| Widget::draw(vg); | |||
| } | |||
| void clearSearch() { | |||
| searchField->setText(""); | |||
| } | |||
| @@ -353,7 +366,7 @@ struct ModuleBrowser : VirtualWidget { | |||
| moduleList->selected = 0; | |||
| // Favorites | |||
| { | |||
| if (!sFavoriteModels.empty()) { | |||
| SeparatorItem *item = new SeparatorItem(); | |||
| item->setText("Favorites"); | |||
| moduleList->addChild(item); | |||
| @@ -423,8 +436,9 @@ struct ModuleBrowser : VirtualWidget { | |||
| box.pos = parent->box.size.minus(box.size).div(2).round(); | |||
| box.pos.y = 60; | |||
| box.size.y = parent->box.size.y - 2 * box.pos.y; | |||
| moduleScroll->box.size.y = min(box.size.y - moduleScroll->box.pos.y, moduleList->box.size.y); | |||
| box.size.y = min(box.size.y, moduleScroll->box.getBottomRight().y); | |||
| gFocusedWidget = searchField; | |||
| Widget::step(); | |||
| } | |||
| @@ -28,7 +28,7 @@ static void drawPlug(NVGcontext *vg, Vec pos, NVGcolor color) { | |||
| } | |||
| static void drawWire(NVGcontext *vg, Vec pos1, Vec pos2, NVGcolor color, float tension, float opacity) { | |||
| NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.08); | |||
| NVGcolor colorShadow = nvgRGBAf(0, 0, 0, 0.10); | |||
| NVGcolor colorOutline = nvgLerpRGBA(color, nvgRGBf(0.0, 0.0, 0.0), 0.5); | |||
| // Wire | |||
| @@ -4,17 +4,30 @@ | |||
| namespace rack { | |||
| Label::Label() { | |||
| box.size.y = BND_WIDGET_HEIGHT; | |||
| fontSize = 13; | |||
| color = bndGetTheme()->regularTheme.textColor; | |||
| } | |||
| void Label::draw(NVGcontext *vg) { | |||
| float x = 0.0; | |||
| if (alignment == RIGHT_ALIGNMENT) { | |||
| x = box.size.x - bndLabelWidth(vg, -1, text.c_str()); | |||
| } | |||
| else if (alignment == CENTER_ALIGNMENT) { | |||
| x = (box.size.x - bndLabelWidth(vg, -1, text.c_str())) / 2.0; | |||
| // TODO | |||
| // Custom font sizes do not work with right or center alignment | |||
| float x; | |||
| switch (alignment) { | |||
| default: | |||
| case LEFT_ALIGNMENT: { | |||
| x = 0.0; | |||
| } break; | |||
| case RIGHT_ALIGNMENT: { | |||
| x = box.size.x - bndLabelWidth(vg, -1, text.c_str()); | |||
| } break; | |||
| case CENTER_ALIGNMENT: { | |||
| x = (box.size.x - bndLabelWidth(vg, -1, text.c_str())) / 2.0; | |||
| } break; | |||
| } | |||
| bndLabel(vg, x, 0.0, box.size.x, box.size.y, -1, text.c_str()); | |||
| bndIconLabelValue(vg, x, 0.0, box.size.x, box.size.y, -1, color, BND_LEFT, fontSize, text.c_str(), NULL); | |||
| } | |||
| @@ -20,11 +20,5 @@ void List::step() { | |||
| } | |||
| } | |||
| void List::draw(NVGcontext *vg) { | |||
| bndBackground(vg, 0.0, 0.0, box.size.x, box.size.y); | |||
| bndBevel(vg, 0.0, 0.0, box.size.x, box.size.y); | |||
| Widget::draw(vg); | |||
| } | |||
| } // namespace rack | |||
| @@ -387,7 +387,7 @@ void windowInit() { | |||
| bndSetFont(gGuiFont->handle); | |||
| // bndSetIconImage(loadImage(assetGlobal("res/icons.png"))); | |||
| windowSetTheme(nvgRGB(0x40, 0x40, 0x40), nvgRGB(0xf0, 0xf0, 0xf0)); | |||
| windowSetTheme(nvgRGB(0x33, 0x33, 0x33), nvgRGB(0xf0, 0xf0, 0xf0)); | |||
| } | |||
| void windowDestroy() { | |||
| @@ -556,34 +556,34 @@ void windowSetTheme(NVGcolor bg, NVGcolor fg) { | |||
| w.shadeTop = 0; | |||
| w.shadeDown = 0; | |||
| BNDwidgetTheme sliderW = w; | |||
| sliderW.itemColor = bg; | |||
| sliderW.innerColor = colorPlus(bg, nvgRGB(0x50, 0x50, 0x50)); | |||
| sliderW.innerSelectedColor = colorPlus(bg, nvgRGB(0x60, 0x60, 0x60)); | |||
| BNDwidgetTheme textW = sliderW; | |||
| textW.textColor = colorMinus(bg, nvgRGB(0x20, 0x20, 0x20)); | |||
| textW.textSelectedColor = colorMinus(bg, nvgRGB(0x20, 0x20, 0x20)); | |||
| BNDwidgetTheme scrollW = w; | |||
| scrollW.itemColor = colorPlus(bg, nvgRGB(0x50, 0x50, 0x50)); | |||
| scrollW.innerColor = bg; | |||
| BNDtheme t; | |||
| t.backgroundColor = colorPlus(bg, nvgRGB(0x30, 0x30, 0x30)); | |||
| t.regularTheme = w; | |||
| t.toolTheme = w; | |||
| t.radioTheme = w; | |||
| t.textFieldTheme = textW; | |||
| t.textFieldTheme = w; | |||
| t.optionTheme = w; | |||
| t.choiceTheme = w; | |||
| t.numberFieldTheme = w; | |||
| t.sliderTheme = sliderW; | |||
| t.scrollBarTheme = scrollW; | |||
| t.sliderTheme = w; | |||
| t.scrollBarTheme = w; | |||
| t.tooltipTheme = w; | |||
| t.menuTheme = w; | |||
| t.menuItemTheme = w; | |||
| t.sliderTheme.itemColor = bg; | |||
| t.sliderTheme.innerColor = colorPlus(bg, nvgRGB(0x50, 0x50, 0x50)); | |||
| t.sliderTheme.innerSelectedColor = colorPlus(bg, nvgRGB(0x60, 0x60, 0x60)); | |||
| t.textFieldTheme.textColor = colorMinus(bg, nvgRGB(0x20, 0x20, 0x20)); | |||
| t.textFieldTheme.textSelectedColor = t.textFieldTheme.textColor; | |||
| t.scrollBarTheme.itemColor = colorPlus(bg, nvgRGB(0x50, 0x50, 0x50)); | |||
| t.scrollBarTheme.innerColor = bg; | |||
| t.menuTheme.textColor = colorMinus(fg, nvgRGB(0x50, 0x50, 0x50)); | |||
| t.menuTheme.textSelectedColor = t.menuTheme.textColor; | |||
| bndSetTheme(t); | |||
| } | |||