void HudItemDesc::onDraw(Renderer2D &out) const { HudLayer::onDraw(out); FRect rect = this->rect(); if(!m_item.isDummy()) { float ypos = topOffset() + rect.y(); FRect uv_rect; auto texture = m_item.guiImage(false, uv_rect); float2 size(texture->width() * uv_rect.width(), texture->height() * uv_rect.height()); float2 pos = (float2)(int2)(float2(rect.center().x - size.x * 0.5f, ypos)); out.addFilledRect(FRect(pos, pos + size), uv_rect, {texture, mulAlpha(ColorId::white, alpha())}); ypos += size.y + 10.0f; FRect desc_rect(rect.x() + 5.0f, ypos, rect.ex() - 5.0f, rect.ey() - 5.0f); // TODO: fix drawing of text that does not fit string params_desc; if(m_item.type() == ItemType::weapon) params_desc = Weapon(m_item).paramDesc(); else if(m_item.type() == ItemType::ammo) params_desc = Ammo(m_item).paramDesc(); else if(m_item.type() == ItemType::armour) params_desc = Armour(m_item).paramDesc(); m_font->draw(out, float2(rect.x() + 5.0f, ypos), {titleColor(), titleShadowColor()}, params_desc); } }
void ImageButton::drawContents(Renderer2D &out) const { bool is_pressed = m_mode == mode_toggle? m_is_pressed ^ m_mouse_press : m_mode == mode_toggle_on? m_is_pressed || m_mouse_press : m_mouse_press; if(is_pressed) out.addFilledRect(IRect(m_proto.down->size()), m_proto.down); else out.addFilledRect(IRect(m_proto.up->size()), m_proto.up); if(m_proto.font) { int2 rect_center = size() / 2; int2 pos(m_proto.text_rect.min.x - 1, m_proto.text_rect.center().y - m_text_extents.height() / 2 - 1); if(m_mouse_press) pos += int2(2, 2); m_proto.font->draw(out, pos, {m_is_enabled? Color(255, 200, 0) : Color::gray, Color::black}, m_text); } }
void Window::drawWindow(Renderer2D &out, IRect rect, FColor color, int outline) { FColor lighter(color.rgb() * 1.2f, color.a); FColor darker(color.rgb() * 0.8f, color.a); int aoutline = fwk::abs(outline); if(outline) { int2 hsize(rect.width(), aoutline); int2 vsize(aoutline, rect.height()); FColor col1 = outline < 0? darker : lighter; out.addFilledRect(IRect(rect.min, rect.min + hsize), col1); out.addFilledRect(IRect(rect.min, rect.min + vsize), col1); int2 p1(rect.min.x, rect.max.y - aoutline); int2 p2(rect.max.x - aoutline, rect.min.y); FColor col2 = outline < 0? lighter : darker; out.addFilledRect(IRect(p1, p1 + hsize), col2); out.addFilledRect(IRect(p2, p2 + vsize), col2); } int2 off(aoutline, aoutline); out.addFilledRect(inset(rect, off, off), color); }
void MultiPlayerMenu::onDraw(Renderer2D &out) const { FRect back_quad((float2)m_window_size); out.addFilledRect(back_quad, mulAlpha(ColorId::black, m_visible_time * 0.8f)); HudLayer::onDraw(out); if(!m_message.empty()) { double msg_time = getTime() - m_message_time; double alpha = min(1.0, 5.0 - msg_time); if(msg_time < 5.0) m_font->draw(out, rect() + float2(spacing, 0.0f), {mulAlpha(m_message_color, alpha), mulAlpha(ColorId::black, alpha), HAlign::left, VAlign::bottom}, m_message); } }
void HudItemButton::onDraw(Renderer2D &out) const { HudButton::onDraw(out); FRect rect = this->rect(); if(!m_entry.item.isDummy()) { FRect uv_rect; auto texture = m_entry.item.guiImage(true, uv_rect); float2 size(texture->width() * uv_rect.width(), texture->height() * uv_rect.height()); float2 pos = (float2)(int2)(rect.center() - size / 2); out.addFilledRect(FRect(pos, pos + size), texture); if(m_entry.count > 1) m_font->draw(out, rect, {textColor(), textShadowColor(), HAlign::right}, format("%", m_entry.count)); if(isDropping()) m_font->draw(out, rect, {textColor(true), textShadowColor(), HAlign::left, VAlign::bottom}, format("-%", dropCount())); } }
void HudWeapon::onDraw(Renderer2D &out) const { HudButton::onDraw(out); FRect rect = this->rect(); if(!m_weapon.isDummy()) { FRect uv_rect; auto texture = m_weapon.guiImage(false, uv_rect); float2 size(texture->width() * uv_rect.width(), texture->height() * uv_rect.height()); float2 pos = (int2)(rect.center() - size / 2); out.addFilledRect(FRect(pos, pos + size), uv_rect, {texture, Color::white}); //TODO: print current attack mode if(m_weapon.proto().max_ammo) { TextFormatter fmt; fmt("%d/%d", m_ammo_count, m_weapon.proto().max_ammo); //TODO: alpha for shadow color m_font->draw(out, rect, {m_style.enabled_color, Color::black, HAlign::right, VAlign::top}, fmt); } } }
void Window::draw(Renderer2D &out) const { out.setViewPos(-m_clipped_rect.min); out.setScissorRect(m_clipped_rect); if(m_background_color.a > 0.0f && !(m_background && m_background->size() == m_rect.size())) out.addFilledRect(IRect(m_clipped_rect.size()), m_background_color); if(m_background) out.addFilledRect(IRect(m_background->size()), m_background); drawContents(out); out.setViewPos(-m_clipped_rect.min); if(m_has_inner_rect) { int2 rsize = m_rect.size(); int2 isize = m_inner_rect.size(); auto col1 = WindowStyle::gui_dark; auto col2 = WindowStyle::gui_light; col1 = FColor(col1.rgb() * 0.8f, 0.5f); col2 = FColor(col2.rgb() * 1.333f, 0.5f); // TODO: minimum size of progress bar, coz sometimes its almost invisible if(isize.x > rsize.x) { float divisor = 1.0f / float(isize.x); float spos = float(0 - m_inner_rect.min.x) * divisor; float epos = float(rsize.x - m_inner_rect.min.x) * divisor; out.addFilledRect(IRect(0, rsize.y - 5, rsize.x, rsize.y), col1); out.addFilledRect(IRect(spos * rsize.x, rsize.y - 5, (spos + epos) * rsize.x, rsize.y), col2); } if(isize.y > rsize.y) { float divisor = 1.0f / float(isize.y); float spos = float(0 - m_inner_rect.min.y) * divisor; float epos = float(rsize.y - m_inner_rect.min.y) * divisor; out.addFilledRect(IRect(rsize.x - 5, 0, rsize.x, rsize.y), col1); out.addFilledRect(IRect(rsize.x - 5, spos * rsize.y, rsize.x, epos * rsize.y), col2); } } for(int n = 0; n < (int)m_children.size(); n++) if(m_children[n]->isVisible()) m_children[n]->draw(out); if(!m_parent) out.setScissorRect(none); }
void GroupEditor::drawContents(Renderer2D &out) const { int2 offset = innerOffset(); for(int n = 0; n < m_tile_group->entryCount(); n++) m_tile_group->entryTile(n)->m_temp = n; IRect clip_rect(int2(0, 0), clippedRect().size()); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; entry.is_selected = m_mode == mAddRemove? m_tile_group->isValidEntryId(entry.tile->m_temp, entry.tile) : entry.group_id == m_selected_group_id; IRect tile_rect = entry.tile->rect(); int2 pos = entry.pos - tile_rect.min - offset; if(areOverlapping(clip_rect, tile_rect + pos)) entry.tile->draw(out, pos); } DTexture::unbind(); for(int n = 0; n < (int)m_tile_list.size(); n++) { const ui::TileList::Entry &entry = m_tile_list[n]; if(!entry.is_selected) continue; Color col = m_tile_group->isEntryDirty(entry.tile->m_temp)? ColorId::red : ColorId::white; int2 pos = entry.pos - offset; out.addRect(IRect(pos, pos + entry.size), col); } if(m_mode == mModify && m_selected_group_id != -1) { IRect edit_rect(clippedRect().max - int2(280, 250), clippedRect().max - int2(5, 0)); int2 center = edit_rect.center(); out.setViewPos(-center); int2 half_size = edit_rect.size() / 2; out.addFilledRect(IRect(-half_size, half_size), FColor(0.3f, 0.3f, 0.3f)); drawBBox(out, IBox({-9, 0, -9}, {9, 1, 9}), ColorId::white); auto font = res::getFont(WindowStyle::fonts[0]); for(int n = 0; n < TileGroup::Group::side_count; n++) { out.setViewPos(-center - worldToScreen(TileGroup::Group::s_side_offsets[n] * 9)); font->draw(out, float2(0, 0), {ColorId::white}, format("%d", m_tile_group->groupSurface(m_selected_group_id, n))); } out.setViewPos(-center +edit_rect.size() / 2); font->draw(out, float2(0, 0), {ColorId::white}, format("setting surface: %d", m_selected_surface_id)); /* const char *names[] = { "", "snow", "gravel", "dirt", "grass", "mud", "mud_cracked", "sand", "green goo", }; out.setViewPos(-int2(bottom_rect.max.x - 200, bottom_rect.min.y)); for(int n = 0; n < arraySize(names); n++) font->draw(int2(0, 10), ColorId::white, m_selected_surface_id == n? "%d: [%s]\n" : "%d: %s\n", n, names[n]); */ out.setViewPos(-clippedRect().min); } if(m_current_entry) m_font->draw(out, float2(5, height() - 20), {ColorId::white, ColorId::black}, format("%s", m_current_entry->tile->resourceName().c_str())); }