void AsyncImageFileView::Draw(UIContext &dc) { if (!texture_ && !textureFailed_ && !filename_.empty()) { texture_ = dc.GetThin3DContext()->CreateTextureFromFile(filename_.c_str(), DETECT); if (!texture_) textureFailed_ = true; } if (HasFocus()) { dc.FillRect(dc.theme->itemFocusedStyle.background, bounds_.Expand(3)); } // TODO: involve sizemode if (texture_) { dc.Flush(); dc.GetThin3DContext()->SetTexture(0, texture_); dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_); dc.Flush(); dc.RebindTexture(); if (!text_.empty()) { dc.DrawText(text_.c_str(), bounds_.centerX()+1, bounds_.centerY()+1, 0x80000000, ALIGN_CENTER | FLAG_DYNAMIC_ASCII); dc.DrawText(text_.c_str(), bounds_.centerX(), bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER | FLAG_DYNAMIC_ASCII); } } else { if (!filename_.empty()) { // draw a black rectangle to represent the missing screenshot. dc.FillRect(UI::Drawable(0xFF000000), GetBounds()); } else { // draw a dark gray rectangle to represent no save state. dc.FillRect(UI::Drawable(0x50202020), GetBounds()); } if (!text_.empty()) { dc.DrawText(text_.c_str(), bounds_.centerX(), bounds_.centerY(), 0xFFFFFFFF, ALIGN_CENTER | FLAG_DYNAMIC_ASCII); } } }
void DrawGameBackground(UIContext &dc, const std::string &gamePath) { GameInfo *ginfo = g_gameInfoCache->GetInfo(dc.GetThin3DContext(), gamePath, GAMEINFO_WANTBG); dc.Flush(); if (ginfo) { bool hasPic = false; double loadTime; if (ginfo->pic1Texture) { dc.GetThin3DContext()->SetTexture(0, ginfo->pic1Texture); loadTime = ginfo->timePic1WasLoaded; hasPic = true; } else if (ginfo->pic0Texture) { dc.GetThin3DContext()->SetTexture(0, ginfo->pic0Texture); loadTime = ginfo->timePic0WasLoaded; hasPic = true; } if (hasPic) { uint32_t color = whiteAlpha(ease((time_now_d() - loadTime) * 3)) & 0xFFc0c0c0; dc.Draw()->DrawTexRect(dc.GetBounds(), 0,0,1,1, color); dc.Flush(); dc.RebindTexture(); } else { ::DrawBackground(dc, 1.0f); dc.RebindTexture(); dc.Flush(); } } }
void HttpImageFileView::Draw(UIContext &dc) { if (!texture_ && !textureFailed_ && !path_.empty() && !download_) { download_ = downloader_->StartDownloadWithCallback(path_, "", std::bind(&HttpImageFileView::DownloadCompletedCallback, this, placeholder::_1)); download_->SetHidden(true); } if (!textureData_.empty()) { texture_ = dc.GetThin3DContext()->CreateTextureFromFileData((const uint8_t *)(textureData_.data()), (int)textureData_.size(), DETECT); if (!texture_) textureFailed_ = true; textureData_.clear(); download_.reset(); } if (HasFocus()) { dc.FillRect(dc.theme->itemFocusedStyle.background, bounds_.Expand(3)); } // TODO: involve sizemode if (texture_) { dc.Flush(); dc.GetThin3DContext()->SetTexture(0, texture_); dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_); dc.Flush(); dc.RebindTexture(); } else { // draw a black rectangle to represent the missing image. dc.FillRect(UI::Drawable(0xFF000000), GetBounds()); } }
void DrawBackground(UIContext &dc, float alpha = 1.0f) { static float xbase[100] = {0}; static float ybase[100] = {0}; float xres = dc.GetBounds().w; float yres = dc.GetBounds().h; static int last_xres = 0; static int last_yres = 0; if (xbase[0] == 0.0f || last_xres != xres || last_yres != yres) { GMRng rng; for (int i = 0; i < 100; i++) { xbase[i] = rng.F() * xres; ybase[i] = rng.F() * yres; } last_xres = xres; last_yres = yres; } dc.GetThin3DContext()->Clear(T3DClear::COLOR | T3DClear::DEPTH | T3DClear::STENCIL, 0xff774422, 0.0, 0); int img = I_BG; #ifdef GOLD img = I_BG_GOLD; #endif ui_draw2d.DrawImageStretch(img, dc.GetBounds()); float t = time_now(); for (int i = 0; i < 100; i++) { float x = xbase[i] + dc.GetBounds().x; float y = ybase[i] + dc.GetBounds().y + 40 * cosf(i * 7.2f + t * 1.3f); float angle = sinf(i + t); int n = i & 3; ui_draw2d.DrawImageRotated(symbols[n], x, y, 1.0f, angle, colorAlpha(colors[n], alpha * 0.1f)); } }
void Thin3DTextureView::Draw(UIContext &dc) { // TODO: involve sizemode if (texture_) { dc.Flush(); dc.GetThin3DContext()->SetTexture(0, texture_); dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_); dc.Flush(); dc.RebindTexture(); } }
void AsyncImageFileView::Draw(UIContext &dc) { if (!texture_ && !textureFailed_) { texture_ = dc.GetThin3DContext()->CreateTextureFromFile(filename_.c_str(), DETECT); if (!texture_) textureFailed_ = true; } // TODO: involve sizemode if (texture_) { dc.Flush(); dc.GetThin3DContext()->SetTexture(0, texture_); dc.Draw()->Rect(bounds_.x, bounds_.y, bounds_.w, bounds_.h, color_); dc.Flush(); dc.RebindTexture(); } else { // draw a dark gray rectangle to represent the texture. dc.FillRect(UI::Drawable(0x50202020), GetBounds()); } }
void SavedataButton::Draw(UIContext &dc) { GameInfo *ginfo = g_gameInfoCache.GetInfo(dc.GetThin3DContext(), savePath_, GAMEINFO_WANTSIZE); Thin3DTexture *texture = 0; u32 color = 0, shadowColor = 0; using namespace UI; if (ginfo->iconTexture) { texture = ginfo->iconTexture; } int x = bounds_.x; int y = bounds_.y; int w = 144; int h = bounds_.h; UI::Style style = dc.theme->itemStyle; if (down_) style = dc.theme->itemDownStyle; h = bounds_.h; if (HasFocus()) style = down_ ? dc.theme->itemDownStyle : dc.theme->itemFocusedStyle; Drawable bg = style.background; dc.Draw()->Flush(); dc.RebindTexture(); dc.FillRect(bg, bounds_); dc.Draw()->Flush(); if (texture) { color = whiteAlpha(ease((time_now_d() - ginfo->timeIconWasLoaded) * 2)); shadowColor = blackAlpha(ease((time_now_d() - ginfo->timeIconWasLoaded) * 2)); float tw = texture->Width(); float th = texture->Height(); // Adjust position so we don't stretch the image vertically or horizontally. // TODO: Add a param to specify fit? The below assumes it's never too wide. float nw = h * tw / th; x += (w - nw) / 2.0f; w = nw; } int txOffset = down_ ? 4 : 0; txOffset = 0; Bounds overlayBounds = bounds_; // Render button int dropsize = 10; if (texture) { if (txOffset) { dropsize = 3; y += txOffset * 2; overlayBounds.y += txOffset * 2; } if (HasFocus()) { dc.Draw()->Flush(); dc.RebindTexture(); float pulse = sinf(time_now() * 7.0f) * 0.25 + 0.8; dc.Draw()->DrawImage4Grid(dc.theme->dropShadow4Grid, x - dropsize*1.5f, y - dropsize*1.5f, x + w + dropsize*1.5f, y + h + dropsize*1.5f, alphaMul(color, pulse), 1.0f); dc.Draw()->Flush(); } else { dc.Draw()->Flush(); dc.RebindTexture(); dc.Draw()->DrawImage4Grid(dc.theme->dropShadow4Grid, x - dropsize, y - dropsize*0.5f, x + w + dropsize, y + h + dropsize*1.5, alphaMul(shadowColor, 0.5f), 1.0f); dc.Draw()->Flush(); } } if (texture) { dc.Draw()->Flush(); dc.GetThin3DContext()->SetTexture(0, texture); dc.Draw()->DrawTexRect(x, y, x + w, y + h, 0, 0, 1, 1, color); dc.Draw()->Flush(); } dc.Draw()->Flush(); dc.RebindTexture(); dc.SetFontStyle(dc.theme->uiFont); float tw, th; dc.Draw()->Flush(); dc.PushScissor(bounds_); if (title_.empty() && !ginfo->title.empty()) { title_ = CleanSaveString(ginfo->title); } if (subtitle_.empty() && ginfo->gameSize > 0) { std::string savedata_title = ginfo->paramSFO.GetValueString("SAVEDATA_TITLE"); subtitle_ = CleanSaveString(savedata_title) + StringFromFormat(" (%d kB)", ginfo->gameSize / 1024); } dc.MeasureText(dc.GetFontStyle(), title_.c_str(), &tw, &th, 0); int availableWidth = bounds_.w - 150; float sineWidth = std::max(0.0f, (tw - availableWidth)) / 2.0f; float tx = 150; if (availableWidth < tw) { float overageRatio = 1.5f * availableWidth * 1.0f / tw; tx -= (1.0f + sin(time_now_d() * overageRatio)) * sineWidth; Bounds tb = bounds_; tb.x = bounds_.x + 150; tb.w = bounds_.w - 150; dc.PushScissor(tb); } dc.DrawText(title_.c_str(), bounds_.x + tx, bounds_.y + 4, style.fgColor, ALIGN_TOPLEFT); dc.SetFontScale(0.6f, 0.6f); dc.DrawText(subtitle_.c_str(), bounds_.x + tx, bounds_.y2() - 7, style.fgColor, ALIGN_BOTTOM); dc.SetFontScale(1.0f, 1.0f); if (availableWidth < tw) { dc.PopScissor(); } dc.Draw()->Flush(); dc.PopScissor(); dc.RebindTexture(); }