bool GroupEditor::onMouseDrag(const InputState&, int2 start, int2 current, int key, int is_final) { if(key == 0) { const ui::TileList::Entry *entry = m_tile_list.find(current + innerOffset()); m_current_entry = entry; if(m_mode == mAddRemove && entry) { int selection_mode = m_tile_group->findEntry(entry->tile) == -1? 1 : -1; if(!m_selection_mode) m_selection_mode = selection_mode; if(m_selection_mode == selection_mode) { if(selection_mode == -1) m_tile_group->removeEntry(m_tile_group->findEntry(entry->tile)); else m_tile_group->addEntry(entry->tile); entry = nullptr; m_tile_list.update(); } } if(m_mode == mModify) { m_selected_group_id = entry? entry->group_id : -1; } if(is_final) m_selection_mode = 0; return true; } return false; }
bool TileSelector::onMouseDrag(const InputState&, int2 start, int2 current, int key, int is_final) { if(key == 0) { m_selection = m_tile_list.find(current + innerOffset()); sendEvent(this, Event::element_selected); return true; } return false; }
void TileSelector::drawContents(Renderer2D &out) const { int2 offset = innerOffset(); IRect clip_rect(int2(0, 0), clippedRect().size()); for(int n = 0; n < (int)m_tile_list.size(); n++) { const Tile *tile = m_tile_list[n].tile; IRect tile_rect = tile->rect(); int2 pos = m_tile_list[n].pos - tile_rect.min - offset; if(areOverlapping(clip_rect, tile_rect + pos)) tile->draw(out, pos); } if(m_selection) { int2 pos = m_selection->pos - offset; out.setViewPos(-clippedRect().min - pos + m_selection->tile->rect().min); IBox box(int3(0, 0, 0), m_selection->tile->bboxSize()); drawBBox(out, box); // out.addFilledRect(IRect(pos, pos + m_selection->size)); } }
void GroupEditor::onInput(const InputState &state) { ASSERT(m_tile_group); if(state.isKeyDown(InputKey::space)) { m_offset[m_mode] = innerOffset(); m_mode = (m_mode == mAddRemove ? mModify : mAddRemove); updateSelector(); return; } const ui::TileList::Entry *entry = m_tile_list.find(state.mousePos() + innerOffset()); m_current_entry = entry; if(m_mode == mModify) { if(state.isKeyDown('D') && entry) { int entry_id = m_tile_group->findEntry(entry->tile); m_tile_group->setEntryDirty(entry_id, !m_tile_group->isEntryDirty(entry_id)); } if(state.isKeyDown('G') && entry && m_selected_group_id != -1) { m_tile_group->setEntryGroup(m_tile_group->findEntry(entry->tile), entry->group_id == m_selected_group_id? m_tile_group->groupCount() : m_selected_group_id); m_tile_list.update(); } if(state.isKeyDown('A') && entry && m_selected_group_id == entry->group_id) { enum { subgroup_count = 3 }; const char *infixes[subgroup_count] = { "CONCAVE_", "CONVEX_", "SIDE_", }; int subgroup_id[subgroup_count] = {-1, -1, -1}; for(int n = 0; n < m_tile_group->entryCount(); n++) { if(m_tile_group->entryGroup(n) == m_selected_group_id) { const char *name = m_tile_group->entryTile(n)->resourceName().c_str(); for(int s = 0; s < subgroup_count; s++) if(!caseEqual(name, infixes[s])) { if(subgroup_id[s] == -1) subgroup_id[s] = m_tile_group->groupCount(); m_tile_group->setEntryGroup(n, subgroup_id[s]); break; } } } m_tile_list.update(); } struct { int key; int side; } actions[] = { { InputKey::kp_1, 0 }, { InputKey::kp_2, 1 }, { InputKey::kp_3, 2 }, { InputKey::kp_6, 3 }, { InputKey::kp_9, 4 }, { InputKey::kp_8, 5 }, { InputKey::kp_7, 6 }, { InputKey::kp_4, 7 } }; if(m_selected_group_id != -1) { for(int a = 0; a < arraySize(actions); a++) if(state.isKeyDown(actions[a].key) || state.isKeyDown(InputKey::kp_5)) m_tile_group->setGroupSurface(m_selected_group_id, actions[a].side, m_selected_surface_id); } for(int n = 0; n <= 9; n++) if(state.isKeyDown('0' + n)) m_selected_surface_id = n; if(state.isKeyDown('-')) m_selected_surface_id = -1; } }
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())); }