void ScrollView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { View::resized(root, sub); _scroll({}); if (m_contentView.m_view) { boo::SWindowRect cRect = sub; cRect.location[0] += m_scroll[0]; cRect.location[1] += sub.size[1] - m_contentView.m_view->nominalHeight() + m_scroll[1]; cRect.size[0] = m_contentView.m_view->nominalWidth(); cRect.size[1] = m_contentView.m_view->nominalHeight(); m_contentView.m_scissorRect = sub; if (m_style == Style::SideButtons && m_drawSideButtons) { int width0 = m_sideButtons[0].m_view->nominalWidth() + 2; int width1 = m_sideButtons[1].m_view->nominalWidth(); cRect.location[0] += width0; cRect.size[0] -= (width0 + width1); m_contentView.m_scissorRect.location[0] += width0; m_contentView.m_scissorRect.size[0] -= (width0 + width1); } m_contentView.m_view->resized(root, cRect, m_contentView.m_scissorRect); if (m_style == Style::ThinIndicator) { float ratio = sub.size[1] / float(cRect.size[1]); m_drawInd = ratio < 1.f; if (m_drawInd) { float pf = rootView().viewRes().pixelFactor(); int barHeight = sub.size[1] * ratio; int scrollHeight = sub.size[1] - barHeight; float prog = m_scroll[1] / float(cRect.size[1] - sub.size[1]); int x = sub.size[0]; int y = sub.size[1] - scrollHeight * prog; m_verts[0].m_pos.assign(x, y, 0); m_verts[1].m_pos.assign(x, y - barHeight, 0); m_verts[2].m_pos.assign(x + 2 * pf, y, 0); m_verts[3].m_pos.assign(x + 2 * pf, y - barHeight, 0); const zeus::CColor& color = rootView().themeData().scrollIndicator(); for (int i = 0; i < 4; ++i) m_verts[i].m_color = color; m_vertsBinding.load<decltype(m_verts)>(m_verts); } } else if (m_style == Style::SideButtons && m_drawSideButtons) { boo::SWindowRect bRect = sub; bRect.size[0] = m_sideButtons[0].m_view->nominalWidth(); bRect.size[1] = m_sideButtons[0].m_view->nominalHeight(); m_sideButtons[0].m_view->resized(root, bRect); bRect.size[0] = m_sideButtons[1].m_view->nominalWidth(); bRect.size[1] = m_sideButtons[1].m_view->nominalHeight(); bRect.location[0] += sub.size[0] - bRect.size[0]; m_sideButtons[1].m_view->resized(root, bRect); } } }
void SplashScreen::updateContentOpacity(float opacity) { specter::ViewResources& res = rootView().viewRes(); if (!m_title && res.fontCacheReady()) { m_title.reset(new specter::TextView(res, *this, res.m_titleFont)); zeus::CColor clearColor = res.themeData().uiText(); clearColor[3] = 0.0; m_title->typesetGlyphs("URDE", clearColor); m_buildInfo.reset(new specter::MultiLineTextView(res, *this, res.m_mainFont, specter::TextView::Alignment::Right)); m_buildInfo->typesetGlyphs(m_buildInfoStr, clearColor); m_newButt.m_view.reset(new specter::Button(res, *this, &m_newProjBind, m_newString, nullptr, specter::Button::Style::Text)); m_openButt.m_view.reset(new specter::Button(res, *this, &m_openProjBind, m_openString, nullptr, specter::Button::Style::Text)); m_extractButt.m_view.reset(new specter::Button(res, *this, &m_extractProjBind, m_extractString, nullptr, specter::Button::Style::Text)); updateSize(); } zeus::CColor clearColor = res.themeData().uiText(); clearColor[3] = 0.0; zeus::CColor color = zeus::CColor::lerp(clearColor, res.themeData().uiText(), opacity); m_title->colorGlyphs(color); m_buildInfo->colorGlyphs(color); m_newButt.m_view->colorGlyphs(color); m_openButt.m_view->colorGlyphs(color); m_extractButt.m_view->colorGlyphs(color); }
void PathButtons::ContentView::draw(boo::IGraphicsCommandQueue* gfxQ) { gfxQ->setScissor(m_scissorRect); for (PathButton& b : m_pb.m_pathButtons) b.m_button.m_view->draw(gfxQ); gfxQ->setScissor(rootView().subRect()); }
void IconView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { m_viewVertBlock.setViewRect(root, sub); float pf = rootView().viewRes().pixelFactor(); m_viewVertBlock.m_mv[0][0] *= sub.size[0]; m_viewVertBlock.m_mv[1][1] *= sub.size[1]; View::resized(m_viewVertBlock, sub); }
void Menu::ItemView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { View::resized(root, sub); float pf = rootView().viewRes().pixelFactor(); boo::SWindowRect textRect = sub; textRect.location[0] += 5 * pf; textRect.location[1] += 5 * pf; m_textView->resized(root, textRect); }
void PathButtons::containerResized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { if (m_fillContainer) { boo::SWindowRect fillRect = sub; fillRect.size[1] = 20 * rootView().viewRes().pixelFactor(); View::resized(root, fillRect); } }
void PathButtons::setButtons(const std::vector<hecl::SystemString>& comps) { m_pathButtons.clear(); m_pathButtons.reserve(comps.size()); size_t idx = 0; ViewResources& res = rootView().viewRes(); for (const hecl::SystemString& c : comps) m_pathButtons.emplace_back(*this, res, idx++, c); }
bool ScrollView::_scroll(const boo::SScrollDelta& scroll) { if (m_contentView.m_view) { float ratioX = subRect().size[0] / float(m_contentView.m_view->nominalWidth()); float ratioY = subRect().size[1] / float(m_contentView.m_view->nominalHeight()); float pf = rootView().viewRes().pixelFactor(); double mult = 20.0 * pf; if (scroll.isFine) mult = 1.0 * pf; bool ret = false; if (ratioX >= 1.f) { m_scroll[0] = 0; m_targetScroll[0] = 0; m_drawSideButtons = false; ret = true; } else { m_drawSideButtons = true; m_targetScroll[0] += scroll.delta[0] * mult; m_targetScroll[0] = std::min(m_targetScroll[0], 0); int scrollWidth = m_contentView.m_view->nominalWidth() - scrollAreaWidth(); m_targetScroll[0] = std::max(m_targetScroll[0], -scrollWidth); } if (ratioY >= 1.f) { m_scroll[1] = 0; m_targetScroll[1] = 0; ret = true; } else { m_targetScroll[1] -= scroll.delta[1] * mult; m_targetScroll[1] = std::max(m_targetScroll[1], 0); int scrollHeight = m_contentView.m_view->nominalHeight() - subRect().size[1]; m_targetScroll[1] = std::min(m_targetScroll[1], scrollHeight); } if (scroll.isFine) { m_scroll[0] = m_targetScroll[0]; m_scroll[1] = m_targetScroll[1]; ret = true; } return ret; } else { m_scroll[0] = 0; m_scroll[1] = 0; m_targetScroll[0] = 0; m_targetScroll[1] = 0; m_drawSideButtons = false; return true; } return false; }
void Menu::ContentView::draw(boo::IGraphicsCommandQueue* gfxQ) { View::draw(gfxQ); gfxQ->setScissor(m_scissorRect); if (m_highlightedItem != -1) { gfxQ->setShaderDataBinding(m_hlVertsBinding); gfxQ->draw(0, 4); } for (ViewChild<std::unique_ptr<ItemView>>& c : m_menu.m_items) if (c.m_view) c.m_view->draw(gfxQ); gfxQ->setScissor(rootView().subRect()); }
void Menu::reset(IMenuNode* rootNode) { m_rootNode = rootNode; m_thisNode = rootNode; ViewResources& res = rootView().viewRes(); for (int i = 0; i < 8; ++i) m_verts[i].m_color = res.themeData().tooltipBackground(); m_vertsBinding.load<decltype(m_verts)>(m_verts); m_subMenu.reset(); const std::string* headText = rootNode->text(); m_headText->typesetGlyphs(headText ? *headText : "", rootView().themeData().uiAltText()); float pf = rootView().viewRes().pixelFactor(); int itemAdv = (ROW_HEIGHT + ITEM_MARGIN * 2) * pf; m_cWidth = m_headText->nominalWidth() + 10 * pf; m_cHeight = headText ? itemAdv : 0; m_cTop = m_cHeight; size_t subCount = rootNode->subNodeCount(); m_items.clear(); if (subCount) { m_items.reserve(subCount); for (size_t i = 0; i < subCount; ++i) { IMenuNode* node = rootNode->subNode(i); const std::string* nodeText = node->text(); m_items.emplace_back(); ViewChild<std::unique_ptr<ItemView>>& item = m_items.back(); if (nodeText) { item.m_view.reset(new ItemView(res, *this, *nodeText, i, node)); m_cWidth = std::max(m_cWidth, int(item.m_view->m_textView->nominalWidth() + 10 * pf)); } m_cHeight += itemAdv; } } }
ScrollView::ScrollView(ViewResources& res, View& parentView, Style style) : View(res, parentView), m_style(style), m_sideButtonBind(*this, rootView().viewManager()) { commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool { buildResources(ctx, res); m_vertsBinding.init(ctx, res, 4, m_viewVertBlockBuf); return true; }); if (style == Style::SideButtons) { m_sideButtons[0].m_view.reset(new Button(res, *this, &m_sideButtonBind, "<")); m_sideButtons[1].m_view.reset(new Button(res, *this, &m_sideButtonBind, ">")); } }
void Menu::ContentView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub, const boo::SWindowRect& scissor) { View::resized(root, sub); float pf = rootView().viewRes().pixelFactor(); m_scissorRect = scissor; boo::SWindowRect itemRect = sub; itemRect.size[0] = m_menu.m_cWidth; itemRect.size[1] = ROW_HEIGHT * pf; itemRect.location[1] += sub.size[1] - m_menu.m_cTop + ITEM_MARGIN * pf; int itemAdv = (ROW_HEIGHT + ITEM_MARGIN * 2) * pf; for (ViewChild<std::unique_ptr<ItemView>>& c : m_menu.m_items) { itemRect.location[1] -= itemAdv; if (c.m_view) c.m_view->resized(root, itemRect); } }
void SplashScreen::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { ModalWindow::resized(root, sub); float pf = rootView().viewRes().pixelFactor(); boo::SWindowRect centerRect = subRect(); centerRect.location[0] = root.size[0] / 2 - (SPLASH_WIDTH * pf / 2.0); centerRect.location[1] = root.size[1] / 2 - (SPLASH_HEIGHT * pf / 2.0); boo::SWindowRect textRect = centerRect; textRect.location[0] += TEXT_MARGIN * pf; textRect.location[1] += (SPLASH_HEIGHT - 36) * pf; if (m_title) { m_title->resized(root, textRect); textRect.location[0] = centerRect.location[0] + (SPLASH_WIDTH - TEXT_MARGIN) * pf; textRect.location[1] -= 5 * pf; m_buildInfo->resized(root, textRect); textRect.size[0] = m_newButt.m_view->nominalWidth(); textRect.size[1] = m_newButt.m_view->nominalHeight(); textRect.location[1] = centerRect.location[1] + 20 * pf; textRect.location[0] = centerRect.location[0] + SPLASH_WIDTH / 4 * pf - m_newButt.m_view->nominalWidth() / 2; m_newButt.m_view->resized(root, textRect); textRect.size[0] = m_openButt.m_view->nominalWidth(); textRect.size[1] = m_openButt.m_view->nominalHeight(); textRect.location[1] = centerRect.location[1] + 20 * pf; textRect.location[0] = centerRect.location[0] + SPLASH_WIDTH * 2 / 4 * pf - m_openButt.m_view->nominalWidth() / 2; m_openButt.m_view->resized(root, textRect); textRect.size[0] = m_extractButt.m_view->nominalWidth(); textRect.size[1] = m_extractButt.m_view->nominalHeight(); textRect.location[1] = centerRect.location[1] + 20 * pf; textRect.location[0] = centerRect.location[0] + SPLASH_WIDTH * 3 / 4 * pf - m_extractButt.m_view->nominalWidth() / 2; m_extractButt.m_view->resized(root, textRect); } if (m_fileBrowser.m_view) m_fileBrowser.m_view->resized(root, root); }
void ScrollView::think() { m_consecutiveIdx = (m_consecutiveIdx + 1) % 16; m_consecutiveScroll[m_consecutiveIdx][0] = 0.0; m_consecutiveScroll[m_consecutiveIdx][1] = 0.0; if (m_sideButtonState != SideButtonState::None) { if (m_sideButtonState == SideButtonState::ScrollLeft) m_targetScroll[0] -= 3; else if (m_sideButtonState == SideButtonState::ScrollRight) m_targetScroll[0] += 3; m_targetScroll[0] = std::min(m_targetScroll[0], 0); int scrollWidth = m_contentView.m_view->nominalWidth() - scrollAreaWidth(); m_targetScroll[0] = std::max(m_targetScroll[0], -scrollWidth); } bool update = false; float pf = rootView().viewRes().pixelFactor(); int xSpeed = std::max(1, std::min(abs(m_targetScroll[0] - m_scroll[0]) / int(5 * pf), int(pf * MAX_SCROLL_SPEED))); if (m_scroll[0] < m_targetScroll[0]) { m_scroll[0] += xSpeed; update = true; } else if (m_scroll[0] > m_targetScroll[0]) { m_scroll[0] -= xSpeed; update = true; } int ySpeed = std::max(1, std::min(abs(m_targetScroll[1] - m_scroll[1]) / int(5 * pf), int(pf * MAX_SCROLL_SPEED))); if (m_scroll[1] < m_targetScroll[1]) { m_scroll[1] += ySpeed; update = true; } else if (m_scroll[1] > m_targetScroll[1]) { m_scroll[1] -= ySpeed; update = true; } if (update) updateSize(); }
void Menu::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) { float pf = rootView().viewRes().pixelFactor(); boo::SWindowRect rect = sub; rect.size[0] = m_cWidth; if (rect.location[1] - m_cHeight < 0) { rect.location[1] += ROW_HEIGHT * pf; rect.size[1] = std::min(root.size[1] - rect.location[1], m_cHeight); } else { rect.location[1] -= m_cHeight; rect.size[1] = m_cHeight; } View::resized(root, rect); m_scroll.m_view->resized(root, rect); setVerts(rect.size[0], rect.size[1], pf); rect.location[0] += 5 * pf; rect.location[1] += rect.size[1] - (ROW_HEIGHT + ITEM_MARGIN - 5) * pf; rect.size[0] = m_headText->nominalWidth(); rect.size[1] = m_headText->nominalHeight(); m_headText->resized(root, rect); }