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 EntitiesEditor::drawContents(Renderer2D &out) const { m_view.updateVisibility(); SceneRenderer renderer(clippedRect(), m_view.pos()); { vector<int> visible_ids; visible_ids.reserve(1024); m_tile_map.findAll(visible_ids, renderer.targetRect(), Flags::all | Flags::visible); for(int i = 0; i < (int)visible_ids.size(); i++) { auto &object = m_tile_map[visible_ids[i]]; int3 pos(object.bbox.min); object.ptr->addToRender(renderer, pos, Color::white); } visible_ids.clear(); m_entity_map.findAll(visible_ids, renderer.targetRect(), Flags::all | Flags::visible); vector<char> selection_map(m_entity_map.size(), 0); vector<float3> old_positions(m_selected_ids.size()); for(int n = 0; n < (int)m_selected_ids.size(); n++) { selection_map[m_selected_ids[n]] = 1; visible_ids.push_back(m_selected_ids[n]); if(m_is_moving) { auto &object = m_entity_map[m_selected_ids[n]]; old_positions[n] = object.ptr->pos(); object.ptr->setPos(old_positions[n] + float3(m_move_offset)); m_entity_map.update(m_selected_ids[n]); } } sort(visible_ids.begin(), visible_ids.end()); visible_ids.resize(std::unique(visible_ids.begin(), visible_ids.end()) - visible_ids.begin()); for(int n = 0; n < (int)visible_ids.size(); n++) { auto &object = m_entity_map[visible_ids[n]]; float3 old_pos = object.ptr->pos(); bool is_selected = selection_map[visible_ids[n]]; FBox bbox = object.ptr->boundingBox(); if(object.ptr->typeId() == EntityId::trigger) { renderer.addBox(bbox, Color(Color::green, 64), true); renderer.addBox(FBox(bbox.min + float3(0.1, 0.1, 0.1), bbox.max - float3(0.1, 0.1, 0.1)), Color::green); } else { object.ptr->addToRender(renderer); } bool is_colliding = m_tile_map.findAny(bbox) != -1 || m_entity_map.findAny(bbox, visible_ids[n]) != -1; if(is_colliding) renderer.addBox(bbox, Color::red); if(is_selected) { if(!is_colliding) renderer.addBox(bbox, Color::white); FBox overground_box = computeOvergroundBox(bbox); if(!overground_box.isEmpty()) renderer.addBox(overground_box, Color::yellow); } } if(m_is_moving) for(int n = 0; n < (int)m_selected_ids.size(); n++) { auto &object = m_entity_map[m_selected_ids[n]]; object.ptr->setPos(old_positions[n]); m_entity_map.update(m_selected_ids[n]); } } if(m_proto && m_mode == Mode::placing) { m_proto->setPos(m_cursor_pos); m_proto->addToRender(renderer); FBox bbox = m_proto->boundingBox(); bool is_colliding = m_tile_map.findAny(bbox) != -1 || m_entity_map.findAny(bbox) != -1; renderer.addBox(bbox, is_colliding? Color::red : Color::white); if(bbox.max.y == bbox.min.y) bbox.max.y += 1.0f; FBox overground_box = computeOvergroundBox(bbox); if(!overground_box.isEmpty()) renderer.addBox(overground_box, Color::yellow); } renderer.render(); if(m_mode == Mode::selecting && m_is_selecting) out.addRect(m_selection - m_view.pos(), Color::white); out.setScissorRect(clippedRect()); out.setViewPos(-clippedRect().min + m_view.pos()); m_view.drawGrid(out); out.setViewPos(-clippedRect().min); auto font = res::getFont(WindowStyle::fonts[1]); font->draw(out, int2(0, clippedRect().height() - 25), {Color::white, Color::black}, format("Cursor: (%.0f, %.0f, %.0f) Grid: %d Mode: %s\n", m_cursor_pos.x, m_cursor_pos.y, m_cursor_pos.z, m_view.gridHeight(), EntitiesEditorMode::toString(m_mode))); }