|
@@ -404,23 +404,39 @@ void CSplitWindow::sliderMoved(int to)
|
|
|
|
|
|
CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill pskill, std::vector<SecondarySkill> & skills, std::function<void(ui32)> callback)
|
|
|
: CWindowObject(PLAYER_COLORED, ImagePath::builtin("LVLUPBKG")),
|
|
|
- cb(callback)
|
|
|
+ cb(callback),
|
|
|
+ skills(skills),
|
|
|
+ hero(hero),
|
|
|
+ skillViewOffset(0)
|
|
|
{
|
|
|
OBJECT_CONSTRUCTION;
|
|
|
|
|
|
GAME->interface()->showingDialog->setBusy();
|
|
|
|
|
|
- if(!skills.empty())
|
|
|
- {
|
|
|
- std::vector<std::shared_ptr<CSelectableComponent>> comps;
|
|
|
- for(auto & skill : skills)
|
|
|
- {
|
|
|
- auto comp = std::make_shared<CSelectableComponent>(ComponentType::SEC_SKILL, skill, hero->getSecSkillLevel(SecondarySkill(skill))+1, CComponent::medium);
|
|
|
- comp->onChoose = std::bind(&CLevelWindow::close, this);
|
|
|
- comps.push_back(comp);
|
|
|
- }
|
|
|
+ sortedSkills = skills;
|
|
|
+ std::sort(sortedSkills.begin(), sortedSkills.end(), [hero](auto a, auto b) {
|
|
|
+ if(hero->getSecSkillLevel(a) == hero->getSecSkillLevel(b))
|
|
|
+ return LIBRARY->skillh->getById(a)->getNameTranslated() < LIBRARY->skillh->getById(b)->getNameTranslated();
|
|
|
+ return hero->getSecSkillLevel(a) > hero->getSecSkillLevel(b);
|
|
|
+ });
|
|
|
|
|
|
- box = std::make_shared<CComponentBox>(comps, Rect(75, 300, pos.w - 150, 100));
|
|
|
+ createSkillBox();
|
|
|
+ if(skills.size() > 3)
|
|
|
+ {
|
|
|
+ buttonLeft = std::make_shared<CButton>(Point(23, 309), AnimationPath::builtin("HSBTNS3"), CButton::tooltip(), [this, skills](){
|
|
|
+ if(skillViewOffset > 0)
|
|
|
+ skillViewOffset--;
|
|
|
+ else
|
|
|
+ skillViewOffset = skills.size() - 1;
|
|
|
+ createSkillBox();
|
|
|
+ }, EShortcut::MOVE_LEFT);
|
|
|
+ buttonRight = std::make_shared<CButton>(Point(pos.w - 45, 309), AnimationPath::builtin("HSBTNS5"), CButton::tooltip(), [this, skills](){
|
|
|
+ if(skillViewOffset < skills.size() - 1)
|
|
|
+ skillViewOffset++;
|
|
|
+ else
|
|
|
+ skillViewOffset = 0;
|
|
|
+ createSkillBox();
|
|
|
+ }, EShortcut::MOVE_RIGHT);
|
|
|
}
|
|
|
|
|
|
portrait = std::make_shared<CHeroArea>(170, 66, hero);
|
|
@@ -444,11 +460,53 @@ CLevelWindow::CLevelWindow(const CGHeroInstance * hero, PrimarySkill pskill, std
|
|
|
skillValue = std::make_shared<CLabel>(192, 253, FONT_MEDIUM, ETextAlignment::CENTER, Colors::WHITE, LIBRARY->generaltexth->primarySkillNames[pskill.getNum()] + " +1");
|
|
|
}
|
|
|
|
|
|
+std::vector<SecondarySkill> getSkillsToShow(const std::vector<SecondarySkill>& skills, int offset, int count)
|
|
|
+{
|
|
|
+ std::vector<SecondarySkill> result;
|
|
|
+
|
|
|
+ int size = skills.size();
|
|
|
+ if (size == 0 || count <= 0) return result;
|
|
|
+
|
|
|
+ offset = offset % size; // ensure offset is within bounds
|
|
|
+ for (int i = 0; i < std::min(count, size); ++i)
|
|
|
+ {
|
|
|
+ int index = (offset + i) % size; // ring buffer like
|
|
|
+ result.push_back(skills[index]);
|
|
|
+ }
|
|
|
+
|
|
|
+ return result;
|
|
|
+}
|
|
|
+
|
|
|
+void CLevelWindow::createSkillBox()
|
|
|
+{
|
|
|
+ OBJECT_CONSTRUCTION;
|
|
|
+
|
|
|
+ std::vector<SecondarySkill> skillsToShow = skills.size() > 3 ? getSkillsToShow(sortedSkills, skillViewOffset, 3) : sortedSkills;
|
|
|
+ if(!skillsToShow.empty())
|
|
|
+ {
|
|
|
+ std::vector<std::shared_ptr<CSelectableComponent>> comps;
|
|
|
+ for(auto & skill : skillsToShow)
|
|
|
+ {
|
|
|
+ auto comp = std::make_shared<CSelectableComponent>(ComponentType::SEC_SKILL, skill, hero->getSecSkillLevel(SecondarySkill(skill))+1, CComponent::medium);
|
|
|
+ comp->onChoose = std::bind(&CLevelWindow::close, this);
|
|
|
+ comps.push_back(comp);
|
|
|
+ }
|
|
|
+
|
|
|
+ box = std::make_shared<CComponentBox>(comps, Rect(75, 300, pos.w - 150, 100));
|
|
|
+ }
|
|
|
+
|
|
|
+ setRedrawParent(true);
|
|
|
+ redraw();
|
|
|
+}
|
|
|
+
|
|
|
void CLevelWindow::close()
|
|
|
{
|
|
|
//FIXME: call callback if there was nothing to select?
|
|
|
if (box && box->selectedIndex() != -1)
|
|
|
- cb(box->selectedIndex());
|
|
|
+ {
|
|
|
+ auto it = std::find(skills.begin(), skills.end(), sortedSkills[(box->selectedIndex() + skillViewOffset) % skills.size()]);
|
|
|
+ cb(std::distance(skills.begin(), it));
|
|
|
+ }
|
|
|
|
|
|
GAME->interface()->showingDialog->setFree();
|
|
|
|