Browse Source

Attempt to unscuff the GUI framework

kiwec 2 months ago
parent
commit
fa80119687

+ 0 - 1
neosu.vcxproj

@@ -351,7 +351,6 @@ copy $(SolutionDir)libraries\libcurl\curl-ca-bundle.crt $(SolutionDir)build\$(Pl
     <ClCompile Include="src\gui\CBaseUIButton.cpp" />
     <ClCompile Include="src\gui\CBaseUICheckbox.cpp" />
     <ClCompile Include="src\gui\CBaseUIContainer.cpp" />
-    <ClCompile Include="src\gui\CBaseUIContainerBase.cpp" />
     <ClCompile Include="src\gui\CBaseUIElement.cpp" />
     <ClCompile Include="src\gui\CBaseUIImage.cpp" />
     <ClCompile Include="src\gui\CBaseUIImageButton.cpp" />

+ 2 - 2
src/App/Osu/Changelog.cpp

@@ -378,7 +378,7 @@ void Changelog::updateLayout() {
         changelog.title->setSizeToContent();
 
         yCounter += changelog.title->getSize().y;
-        changelog.title->setScrollPos(15 * dpiScale, yCounter);
+        changelog.title->setRelPos(15 * dpiScale, yCounter);
         /// yCounter += 10 * dpiScale;
 
         for(CBaseUIButton *change : changelog.changes) {
@@ -386,7 +386,7 @@ void Changelog::updateLayout() {
             change->setSizeToContent();
             change->setSizeY(change->getSize().y * 2.0f);
             yCounter += change->getSize().y /* + 13 * dpiScale*/;
-            change->setScrollPos(35 * dpiScale, yCounter);
+            change->setRelPos(35 * dpiScale, yCounter);
         }
 
         // gap to previous version

+ 4 - 4
src/App/Osu/MainMenu.cpp

@@ -1165,11 +1165,11 @@ void MainMenu::updateLayout() {
     const float size = Osu::getUIScale(324.0f);
     m_vSize = Vector2(size, size);
 
-    m_cube->setScrollPos(m_vCenter - m_vSize / 2.0f - Vector2(m_fCenterOffsetAnim, 0.0f));
+    m_cube->setRelPos(m_vCenter - m_vSize / 2.0f - Vector2(m_fCenterOffsetAnim, 0.0f));
     m_cube->setSize(m_vSize);
 
     m_pauseButton->setSize(30 * dpiScale, 30 * dpiScale);
-    m_pauseButton->setScrollPos(osu->getScreenWidth() - m_pauseButton->getSize().x * 2 - 10 * dpiScale,
+    m_pauseButton->setRelPos(osu->getScreenWidth() - m_pauseButton->getSize().x * 2 - 10 * dpiScale,
                              m_pauseButton->getSize().y + 10 * dpiScale);
 
     if(m_updateAvailableButton != NULL) {
@@ -1180,7 +1180,7 @@ void MainMenu::updateLayout() {
 
     m_versionButton->onResized();  // HACKHACK: framework, setSizeToContent() does not update string metrics
     m_versionButton->setSizeToContent(8 * dpiScale, 8 * dpiScale);
-    m_versionButton->setScrollPos(-1, osu->getScreenSize().y - m_versionButton->getSize().y);
+    m_versionButton->setRelPos(-1, osu->getScreenSize().y - m_versionButton->getSize().y);
 
     int numButtons = m_menuElements.size();
     int menuElementHeight = m_vSize.y / numButtons;
@@ -1195,7 +1195,7 @@ void MainMenu::updateLayout() {
         curY += (i > 0 ? menuElementHeight + menuElementPadding : 0.0f);
 
         m_menuElements[i]->onResized();  // HACKHACK: framework, setSize() does not update string metrics
-        m_menuElements[i]->setScrollPos(m_cube->getRelPos().x + m_cube->getSize().x * offsetPercent -
+        m_menuElements[i]->setRelPos(m_cube->getRelPos().x + m_cube->getSize().x * offsetPercent -
                                          menuElementExtraWidth * offsetPercent +
                                          menuElementExtraWidth * (1.0f - offsetPercent),
                                      curY);

+ 2 - 2
src/App/Osu/ModSelector.cpp

@@ -970,7 +970,7 @@ void ModSelector::updateExperimentalLayout() {
     int experimentalOffsetY = 6 * dpiScale;
     for(int i = 0; i < m_experimentalMods.size(); i++) {
         CBaseUIElement *e = m_experimentalMods[i].element;
-        e->setScrollPosY(yCounter);
+        e->setRelPosY(yCounter);
         e->setSizeY(e->getRelSize().y * dpiScale);
 
         // custom
@@ -1003,7 +1003,7 @@ void ModSelector::updateExperimentalLayout() {
 
     for(int i = 0; i < m_experimentalMods.size(); i++) {
         CBaseUIElement *e = m_experimentalMods[i].element;
-        e->setScrollPosY(yCounter);
+        e->setRelPosY(yCounter);
 
         if(e->getSize().x > experimentalMaxWidth) experimentalMaxWidth = e->getSize().x;
 

+ 24 - 24
src/App/Osu/OptionsMenu.cpp

@@ -1862,14 +1862,14 @@ void OptionsMenu::updateLayout() {
 
     const int categoriesWidth = optionsWidth * categoriesOptionsPercent;
 
-    m_options->setScrollPosX((!m_bFullscreen ? -1 : osu->getScreenWidth() / 2 - (optionsWidth + categoriesWidth) / 2) +
+    m_options->setRelPosX((!m_bFullscreen ? -1 : osu->getScreenWidth() / 2 - (optionsWidth + categoriesWidth) / 2) +
                           categoriesWidth);
     m_options->setSize(optionsWidth, osu->getScreenHeight() + 1);
 
-    m_search->setScrollPos(m_options->getRelPos());
+    m_search->setRelPos(m_options->getRelPos());
     m_search->setSize(m_options->getSize());
 
-    m_categories->setScrollPosX(m_options->getRelPos().x - categoriesWidth);
+    m_categories->setRelPosX(m_options->getRelPos().x - categoriesWidth);
     m_categories->setSize(categoriesWidth, osu->getScreenHeight() + 1);
 
     // reset
@@ -2024,8 +2024,8 @@ void OptionsMenu::updateLayout() {
         if(m_elements[i].resetButton != NULL) {
             CBaseUIButton *resetButton = m_elements[i].resetButton;
             resetButton->setSize(Vector2(35, 50) * dpiScale);
-            resetButton->setScrollPosY(yCounter);
-            resetButton->setScrollPosX(0);
+            resetButton->setRelPosY(yCounter);
+            resetButton->setRelPosX(0);
         }
 
         for(int j = 0; j < m_elements[i].elements.size(); j++) {
@@ -2059,8 +2059,8 @@ void OptionsMenu::updateLayout() {
             } else
                 e->setSizeX(elementWidth);
 
-            e->setScrollPosX(sideMargin + sideMarginAdd);
-            e->setScrollPosY(yCounter);
+            e->setRelPosX(sideMargin + sideMarginAdd);
+            e->setRelPosY(yCounter);
 
             yCounter += e->getSize().y;
         } else if(m_elements[i].elements.size() == 2 || isKeyBindButton) {
@@ -2087,22 +2087,22 @@ void OptionsMenu::updateLayout() {
                 const float dividerMiddle = 5.0f / 8.0f;
                 const float dividerEnd = 2.0f / 8.0f;
 
-                e1->setScrollPos(sideMargin, yCounter);
+                e1->setRelPos(sideMargin, yCounter);
                 e1->setSizeX(e1->getSize().y);
 
-                e2->setScrollPos(sideMargin + e1->getSize().x + 0.5f * spacing, yCounter);
+                e2->setRelPos(sideMargin + e1->getSize().x + 0.5f * spacing, yCounter);
                 e2->setSizeX(elementWidth * dividerMiddle - spacing);
 
-                e3->setScrollPos(sideMargin + e1->getSize().x + e2->getSize().x + 1.5f * spacing, yCounter);
+                e3->setRelPos(sideMargin + e1->getSize().x + e2->getSize().x + 1.5f * spacing, yCounter);
                 e3->setSizeX(elementWidth * dividerEnd - spacing);
             } else {
                 float dividerEnd = 1.0f / 2.0f;
                 float dividerBegin = 1.0f - dividerEnd;
 
-                e1->setScrollPos(sideMargin + sideMarginAdd, yCounter);
+                e1->setRelPos(sideMargin + sideMarginAdd, yCounter);
                 e1->setSizeX(elementWidth * dividerBegin - spacing);
 
-                e2->setScrollPos(sideMargin + e1->getSize().x + 2 * spacing, yCounter);
+                e2->setRelPos(sideMargin + e1->getSize().x + 2 * spacing, yCounter);
                 e2->setSizeX(elementWidth * dividerEnd - spacing);
             }
 
@@ -2129,9 +2129,9 @@ void OptionsMenu::updateLayout() {
                 e2->setSizeX(buttonSize);
                 e3->setSizeX(buttonSize);
 
-                e1->setScrollPos(sideMargin, yCounter);
-                e2->setScrollPos(e1->getRelPos().x + e1->getSize().x + buttonButtonLabelOffset, yCounter);
-                e3->setScrollPos(e2->getRelPos().x + e2->getSize().x + buttonButtonLabelOffset, yCounter);
+                e1->setRelPos(sideMargin, yCounter);
+                e2->setRelPos(e1->getRelPos().x + e1->getSize().x + buttonButtonLabelOffset, yCounter);
+                e3->setRelPos(e2->getRelPos().x + e2->getSize().x + buttonButtonLabelOffset, yCounter);
             } else {
                 const int labelSliderLabelOffset = 15 * dpiScale;
 
@@ -2163,12 +2163,12 @@ void OptionsMenu::updateLayout() {
                     sliderSize = 100;
                 }
 
-                e1->setScrollPos(sideMargin + elementTextStartOffset, yCounter);
+                e1->setRelPos(sideMargin + elementTextStartOffset, yCounter);
 
-                e2->setScrollPos(e1->getRelPos().x + e1->getSize().x + labelSliderLabelOffset, yCounter);
+                e2->setRelPos(e1->getRelPos().x + e1->getSize().x + labelSliderLabelOffset, yCounter);
                 e2->setSizeX(sliderSize - 2 * elementTextStartOffset - labelSliderLabelOffset * 2);
 
-                e3->setScrollPos(e2->getRelPos().x + e2->getSize().x + labelSliderLabelOffset, yCounter);
+                e3->setRelPos(e2->getRelPos().x + e2->getSize().x + labelSliderLabelOffset, yCounter);
             }
 
             yCounter += e2->getSize().y;
@@ -2206,7 +2206,7 @@ void OptionsMenu::updateLayout() {
     for(int i = 0; i < m_categoryButtons.size(); i++) {
         OptionsMenuCategoryButton *category = m_categoryButtons[i];
         category->onResized();  // HACKHACK: framework, setSize*() does not update string metrics
-        category->setScrollPosY(categoryPaddingTopBottom + categoryHeight * i);
+        category->setRelPosY(categoryPaddingTopBottom + categoryHeight * i);
         category->setSize(m_categories->getSize().x - 1, categoryHeight);
     }
     m_categories->getContainer()->update_pos();
@@ -2454,7 +2454,7 @@ void OptionsMenu::onSkinSelect() {
 
         if(m_bVisible) {
             m_contextMenu->setPos(m_skinSelectLocalButton->getPos());
-            m_contextMenu->setScrollPos(m_skinSelectLocalButton->getRelPos());
+            m_contextMenu->setRelPos(m_skinSelectLocalButton->getRelPos());
         } else {
             // Put it 50px from top, we'll move it later
             m_contextMenu->setPos(Vector2{0, 100});
@@ -2573,7 +2573,7 @@ void OptionsMenu::onResolutionSelect() {
 
     // build context menu
     m_contextMenu->setPos(m_resolutionSelectButton->getPos());
-    m_contextMenu->setScrollPos(m_resolutionSelectButton->getRelPos());
+    m_contextMenu->setRelPos(m_resolutionSelectButton->getRelPos());
     m_contextMenu->begin();
     for(int i = 0; i < resolutions.size(); i++) {
         if(resolutions[i].x > nativeResolution.x || resolutions[i].y > nativeResolution.y) continue;
@@ -2605,7 +2605,7 @@ void OptionsMenu::onOutputDeviceSelect() {
 
     // build context menu
     m_contextMenu->setPos(m_outputDeviceSelectButton->getPos());
-    m_contextMenu->setScrollPos(m_outputDeviceSelectButton->getRelPos());
+    m_contextMenu->setRelPos(m_outputDeviceSelectButton->getRelPos());
     m_contextMenu->begin();
     for(auto device : outputDevices) {
         CBaseUIButton *button = m_contextMenu->addButton(device.name);
@@ -2663,7 +2663,7 @@ void OptionsMenu::onCM360CalculatorLinkClicked() {
 void OptionsMenu::onNotelockSelect() {
     // build context menu
     m_contextMenu->setPos(m_notelockSelectButton->getPos());
-    m_contextMenu->setScrollPos(m_notelockSelectButton->getRelPos());
+    m_contextMenu->setRelPos(m_notelockSelectButton->getRelPos());
     m_contextMenu->begin(m_notelockSelectButton->getSize().x);
     {
         for(int i = 0; i < m_notelockTypes.size(); i++) {
@@ -2698,7 +2698,7 @@ void OptionsMenu::onNotelockSelectResetUpdate() {
 void OptionsMenu::onHPDrainSelect() {
     // build context menu
     m_contextMenu->setPos(m_hpDrainSelectButton->getPos());
-    m_contextMenu->setScrollPos(m_hpDrainSelectButton->getRelPos());
+    m_contextMenu->setRelPos(m_hpDrainSelectButton->getRelPos());
     m_contextMenu->begin(m_hpDrainSelectButton->getSize().x);
     {
         for(int i = 1; i < m_drainTypes.size(); i++) {

+ 8 - 8
src/App/Osu/RankingScreen.cpp

@@ -244,7 +244,7 @@ void RankingScreen::draw(Graphics *g) {
 
     // draw active mods
     const Vector2 modPosStart =
-        Vector2(m_rankings->getSize().x - osu->getUIScale(20), m_rankings->getScrollPosY() + osu->getUIScale(260));
+        Vector2(m_rankings->getSize().x - osu->getUIScale(20), m_rankings->getRelPosY() + osu->getUIScale(260));
     Vector2 modPos = modPosStart;
     Vector2 modPosMax;
     if(m_bModTD) drawModImage(g, osu->getSkin()->getSelectionModTD(), modPos, modPosMax);
@@ -537,7 +537,7 @@ void RankingScreen::updateLayout() {
                              Osu::getImageScale(m_rankingTitle->getImage(), 75.0f) * uiScale);
     m_rankingTitle->setSize(m_rankingTitle->getImage()->getWidth() * m_rankingTitle->getScale().x,
                             m_rankingTitle->getImage()->getHeight() * m_rankingTitle->getScale().y);
-    m_rankingTitle->setScrollPos(getSize().x - m_rankingTitle->getSize().x - osu->getUIScale(20.0f), 0);
+    m_rankingTitle->setRelPos(getSize().x - m_rankingTitle->getSize().x - osu->getUIScale(20.0f), 0);
 
     m_songInfo->setSize(osu->getScreenWidth(),
                         max(m_songInfo->getMinimumHeight(),
@@ -552,7 +552,7 @@ void RankingScreen::updateLayout() {
                         osu->getScreenSize().y - (50 * uiScale * 2.f + 20.f * uiScale));
 
     m_rankings->setSize(osu->getScreenSize().x + 2, osu->getScreenSize().y - m_songInfo->getSize().y + 3);
-    m_rankings->setScrollPosY(m_songInfo->getSize().y - 1);
+    m_rankings->setRelPosY(m_songInfo->getSize().y - 1);
     update_pos();
 
     // NOTE: no uiScale for rankingPanel and rankingGrade, doesn't really work due to legacy layout expectations
@@ -568,10 +568,10 @@ void RankingScreen::updateLayout() {
 
     m_rankingIndex->setSize(m_rankings->getSize().x + 2, osu->getScreenHeight() * 0.07f * uiScale);
     m_rankingIndex->setBackgroundColor(0xff745e13);
-    m_rankingIndex->setScrollPosY(m_rankings->getSize().y + 1);
+    m_rankingIndex->setRelPosY(m_rankings->getSize().y + 1);
 
     m_rankingBottom->setSize(m_rankings->getSize().x + 2, osu->getScreenHeight() * 0.2f);
-    m_rankingBottom->setScrollPosY(m_rankingIndex->getRelPos().y + m_rankingIndex->getSize().y);
+    m_rankingBottom->setRelPosY(m_rankingIndex->getRelPos().y + m_rankingIndex->getSize().y);
 
     setGrade(m_grade);
 
@@ -628,7 +628,7 @@ void RankingScreen::setGrade(FinishedScore::Grade grade) {
     m_rankingGrade->setScale(rankingGradeImageScale, rankingGradeImageScale);
     m_rankingGrade->setSize(m_rankingGrade->getImage()->getWidth() * m_rankingGrade->getScale().x,
                             m_rankingGrade->getImage()->getHeight() * m_rankingGrade->getScale().y);
-    m_rankingGrade->setScrollPos(m_rankings->getSize().x - osu->getUIScale(120) -
+    m_rankingGrade->setRelPos(m_rankings->getSize().x - osu->getUIScale(120) -
                                   m_rankingGrade->getImage()->getWidth() * m_rankingGrade->getScale().x / 2.0f,
                               -m_rankings->getRelPos().y +
                                   osu->getUIScale(osu->getSkin()->getVersion() > 1.0f ? 200 : 170) -
@@ -655,11 +655,11 @@ Vector2 RankingScreen::getPPPosRaw() {
     float ppStringWidth = osu->getTitleFont()->getStringWidth(ppString);
     return Vector2(m_rankingGrade->getPos().x, 0) +
            Vector2(m_rankingGrade->getSize().x / 2 - ppStringWidth / 2,
-                   m_rankings->getScrollPosY() + osu->getUIScale(400) + osu->getTitleFont()->getHeight() / 2);
+                   m_rankings->getRelPosY() + osu->getUIScale(400) + osu->getTitleFont()->getHeight() / 2);
 }
 
 Vector2 RankingScreen::getPPPosCenterRaw() {
     return Vector2(m_rankingGrade->getPos().x, 0) +
            Vector2(m_rankingGrade->getSize().x / 2,
-                   m_rankings->getScrollPosY() + osu->getUIScale(400) + osu->getTitleFont()->getHeight() / 2);
+                   m_rankings->getRelPosY() + osu->getUIScale(400) + osu->getTitleFont()->getHeight() / 2);
 }

+ 3 - 4
src/App/Osu/SongBrowser/Button.cpp

@@ -211,8 +211,8 @@ void Button::updateLayoutEx() {
         m_view->getSize().x -
             getActualSize().x * 0.15f);  // WARNING: hardcoded to match 0.85f above for buttonWidthCompensation
 
-    setScrollPosX(offsetX);
-    setScrollPosY(m_fTargetRelPosY + getSize().y * 0.125f * m_fHoverMoveAwayAnimation);
+    setRelPosX(offsetX);
+    setRelPosY(m_fTargetRelPosY + getSize().y * 0.125f * m_fHoverMoveAwayAnimation);
 }
 
 Button *Button::setVisible(bool visible) {
@@ -233,7 +233,6 @@ Button *Button::setVisible(bool visible) {
         m_fCenterOffsetVelocityAnimation = centerOffsetVelocityAnimationTarget;
 
         // force early layout update
-        updateLayout();
         updateLayoutEx();
     }
 
@@ -310,7 +309,7 @@ void Button::onMouseOutside() {
 
 void Button::setTargetRelPosY(float targetRelPosY) {
     m_fTargetRelPosY = targetRelPosY;
-    setScrollPosY(m_fTargetRelPosY);
+    setRelPosY(m_fTargetRelPosY);
 }
 
 Vector2 Button::getActualOffset() const {

+ 1 - 1
src/App/Osu/SongBrowser/CollectionButton.cpp

@@ -100,7 +100,7 @@ void CollectionButton::triggerContextMenu(Vector2 pos) {
 
     if(m_contextMenu != NULL) {
         m_contextMenu->setPos(pos);
-        m_contextMenu->setScrollPos(pos);
+        m_contextMenu->setRelPos(pos);
         m_contextMenu->begin(0, true);
         {
             m_contextMenu->addButton("[...]      Rename Collection", 1);

+ 1 - 1
src/App/Osu/SongBrowser/ScoreButton.cpp

@@ -511,7 +511,7 @@ void ScoreButton::onRightMouseUpInside() {
 
     if(m_contextMenu != NULL) {
         m_contextMenu->setPos(pos);
-        m_contextMenu->setScrollPos(pos);
+        m_contextMenu->setRelPos(pos);
         m_contextMenu->begin(0, true);
         {
             m_contextMenu->addButton("Use Mods", 1);  // for scores without mods this will just nomod

+ 23 - 23
src/App/Osu/SongBrowser/SongBrowser.cpp

@@ -1792,7 +1792,7 @@ void SongBrowser::scrollToSongButton(Button *songButton, bool alignOnTop) {
                         m_fNextScrollToSongButtonJumpFixOldScrollSizeY;  // technically not correct but feels a lot
                                                                          // better for KEY_LEFT navigation
         }
-        m_songBrowser->scrollToY(m_songBrowser->getScrollPosY() - delta, false);
+        m_songBrowser->scrollToY(m_songBrowser->getRelPosY() - delta, false);
     }
 
     m_songBrowser->scrollToY(-songButton->getRelPos().y +
@@ -2247,7 +2247,7 @@ void SongBrowser::updateLayout() {
                           max(osu->getSkin()->getSongSelectTop()->getHeight() * m_fSongSelectTopScale *
                                   osu_songbrowser_topbar_left_percent.getFloat(),
                               m_songInfo->getMinimumHeight() + margin));
-    m_songInfo->setScrollPos(margin, margin);
+    m_songInfo->setRelPos(margin, margin);
     m_songInfo->setSize(m_topbarLeft->getSize().x - margin,
                         max(m_topbarLeft->getSize().y * 0.75f, m_songInfo->getMinimumHeight() + margin));
 
@@ -2257,7 +2257,7 @@ void SongBrowser::updateLayout() {
     for(int i = 0; i < m_topbarLeftButtons.size(); i++) {
         m_topbarLeftButtons[i]->onResized();  // HACKHACK: framework bug (should update string metrics on setSize())
         m_topbarLeftButtons[i]->setSize(topbarLeftButtonWidth, topbarLeftButtonHeight);
-        m_topbarLeftButtons[i]->setScrollPos(
+        m_topbarLeftButtons[i]->setRelPos(
             m_topbarLeft->getSize().x - (i + 1) * (topbarLeftButtonMargin + topbarLeftButtonWidth),
             m_topbarLeft->getSize().y - m_topbarLeftButtons[i]->getSize().y);
     }
@@ -2269,7 +2269,7 @@ void SongBrowser::updateLayout() {
     for(int i = 0; i < m_topbarLeftTabButtons.size(); i++) {
         m_topbarLeftTabButtons[i]->onResized();  // HACKHACK: framework bug (should update string metrics on setSize())
         m_topbarLeftTabButtons[i]->setSize(topbarLeftTabButtonWidth, topbarLeftTabButtonHeight);
-        m_topbarLeftTabButtons[i]->setScrollPos((topbarLeftTabButtonMargin + i * topbarLeftTabButtonWidth),
+        m_topbarLeftTabButtons[i]->setRelPos((topbarLeftTabButtonMargin + i * topbarLeftTabButtonWidth),
                                              m_topbarLeft->getSize().y - m_topbarLeftTabButtons[i]->getSize().y);
     }
 
@@ -2284,21 +2284,21 @@ void SongBrowser::updateLayout() {
 
     float btn_margin = 10.f * dpiScale;
     m_sortButton->setSize(200.f * dpiScale, 30.f * dpiScale);
-    m_sortButton->setScrollPos(m_topbarRight->getSize().x - (m_sortButton->getSize().x + btn_margin), btn_margin);
+    m_sortButton->setRelPos(m_topbarRight->getSize().x - (m_sortButton->getSize().x + btn_margin), btn_margin);
 
     m_sortLabel->onResized();  // HACKHACK: framework bug (should update string metrics on setSizeToContent())
     m_sortLabel->setSizeToContent(3 * dpiScale);
-    m_sortLabel->setScrollPos(
+    m_sortLabel->setRelPos(
         m_sortButton->getRelPos().x - (m_sortLabel->getSize().x + btn_margin),
         (m_sortLabel->getSize().y + btn_margin) / 2.f
     );
 
     m_groupButton->setSize(m_sortButton->getSize());
-    m_groupButton->setScrollPos(m_sortLabel->getRelPos().x - (m_sortButton->getSize().x + 30.f * dpiScale + btn_margin), btn_margin);
+    m_groupButton->setRelPos(m_sortLabel->getRelPos().x - (m_sortButton->getSize().x + 30.f * dpiScale + btn_margin), btn_margin);
 
     m_groupLabel->onResized();  // HACKHACK: framework bug (should update string metrics on setSizeToContent())
     m_groupLabel->setSizeToContent(3 * dpiScale);
-    m_groupLabel->setScrollPos(
+    m_groupLabel->setRelPos(
         m_groupButton->getRelPos().x - (m_groupLabel->getSize().x + btn_margin),
         (m_groupLabel->getSize().y + btn_margin) / 2.f
     );
@@ -2325,18 +2325,18 @@ void SongBrowser::updateLayout() {
 
         // new, hardcoded offsets instead of dynamically using the button skin image widths (except starting at 3rd
         // button)
-        m_bottombarNavButtons[i]->setScrollPosX(
+        m_bottombarNavButtons[i]->setRelPosX(
             navBarXCounter + gap + (i > 0 ? Osu::getUIScale(57.6f) : 0) +
             (i > 1 ? max((i - 1) * Osu::getUIScale(48.0f), m_bottombarNavButtons[i - 1]->getSize().x) : 0));
 
         // old, overflows with some skins (e.g. kyu)
-        // m_bottombarNavButtons[i]->setScrollPosX((i == 0 ? navBarXCounter : 0) + gap + (i > 0 ?
+        // m_bottombarNavButtons[i]->setRelPosX((i == 0 ? navBarXCounter : 0) + gap + (i > 0 ?
         // m_bottombarNavButtons[i-1]->getRelPos().x + m_bottombarNavButtons[i-1]->getSize().x : 0));
     }
 
     const int userButtonHeight = m_bottombar->getSize().y * 0.9f;
     m_userButton->setSize(userButtonHeight * 3.5f, userButtonHeight);
-    m_userButton->setScrollPos(max(m_bottombar->getSize().x / 2 - m_userButton->getSize().x / 2,
+    m_userButton->setRelPos(max(m_bottombar->getSize().x / 2 - m_userButton->getSize().x / 2,
                                 m_bottombarNavButtons[m_bottombarNavButtons.size() - 1]->getRelPos().x +
                                     m_bottombarNavButtons[m_bottombarNavButtons.size() - 1]->getSize().x + 10),
                             m_bottombar->getSize().y - m_userButton->getSize().y - 1);
@@ -2401,10 +2401,10 @@ void SongBrowser::updateScoreBrowserLayout() {
         m_localBestContainer->setPos(m_scoreBrowser->getPos().x,
                                      m_scoreBrowser->getPos().y + m_scoreBrowser->getSize().y);
         m_localBestContainer->setSize(m_scoreBrowser->getPos().x, local_best_size);
-        m_localBestLabel->setScrollPos(m_scoreBrowser->getPos().x, 0);
+        m_localBestLabel->setRelPos(m_scoreBrowser->getPos().x, 0);
         m_localBestLabel->setSize(m_scoreBrowser->getSize().x, 40);
         if(m_localBestButton) {
-            m_localBestButton->setScrollPos(m_scoreBrowser->getPos().x, 40);
+            m_localBestButton->setRelPos(m_scoreBrowser->getPos().x, 40);
             m_localBestButton->setSize(m_scoreBrowser->getSize().x, scoreHeight);
         }
     }
@@ -2413,19 +2413,19 @@ void SongBrowser::updateScoreBrowserLayout() {
     for(size_t i = 0; i < elements.size(); i++) {
         CBaseUIElement *scoreButton = elements[i];
         scoreButton->setSize(m_scoreBrowser->getSize().x, scoreHeight);
-        scoreButton->setScrollPos(scoreBrowserExtraPaddingRight, i * scoreButton->getSize().y + 5 * dpiScale);
+        scoreButton->setRelPos(scoreBrowserExtraPaddingRight, i * scoreButton->getSize().y + 5 * dpiScale);
     }
     m_scoreBrowserScoresStillLoadingElement->setSize(m_scoreBrowser->getSize().x * 0.9f, scoreHeight * 0.75f);
-    m_scoreBrowserScoresStillLoadingElement->setScrollPos(
+    m_scoreBrowserScoresStillLoadingElement->setRelPos(
         m_scoreBrowser->getSize().x / 2 - m_scoreBrowserScoresStillLoadingElement->getSize().x / 2,
         (browserHeight / 2) * 0.65f - m_scoreBrowserScoresStillLoadingElement->getSize().y / 2);
     m_scoreBrowserNoRecordsYetElement->setSize(m_scoreBrowser->getSize().x * 0.9f, scoreHeight * 0.75f);
     if(elements[0] == m_scoreBrowserNoRecordsYetElement) {
-        m_scoreBrowserNoRecordsYetElement->setScrollPos(
+        m_scoreBrowserNoRecordsYetElement->setRelPos(
             m_scoreBrowser->getSize().x / 2 - m_scoreBrowserScoresStillLoadingElement->getSize().x / 2,
             (browserHeight / 2) * 0.65f - m_scoreBrowserScoresStillLoadingElement->getSize().y / 2);
     } else {
-        m_scoreBrowserNoRecordsYetElement->setScrollPos(
+        m_scoreBrowserNoRecordsYetElement->setRelPos(
             m_scoreBrowser->getSize().x / 2 - m_scoreBrowserScoresStillLoadingElement->getSize().x / 2, 45);
     }
     m_localBestContainer->update_pos();
@@ -2948,7 +2948,7 @@ void SongBrowser::rebuildSongButtonsAndVisibleSongButtonsWithSearchMatchSupport(
 
 void SongBrowser::onSortScoresClicked(CBaseUIButton *button) {
     m_contextMenu->setPos(button->getPos());
-    m_contextMenu->setScrollPos(button->getRelPos());
+    m_contextMenu->setRelPos(button->getRelPos());
     m_contextMenu->begin(button->getSize().x);
     {
         CBaseUIButton *button = m_contextMenu->addButton("Online Leaderboard");
@@ -2997,7 +2997,7 @@ void SongBrowser::onWebClicked(CBaseUIButton *button) {
 
 void SongBrowser::onGroupClicked(CBaseUIButton *button) {
     m_contextMenu->setPos(button->getPos());
-    m_contextMenu->setScrollPos(button->getRelPos());
+    m_contextMenu->setRelPos(button->getRelPos());
     m_contextMenu->begin(button->getSize().x);
     {
         for(size_t i = 0; i < m_groupings.size(); i++) {
@@ -3059,7 +3059,7 @@ void SongBrowser::onGroupChange(UString text, int id) {
 
 void SongBrowser::onSortClicked(CBaseUIButton *button) {
     m_contextMenu->setPos(button->getPos());
-    m_contextMenu->setScrollPos(button->getRelPos());
+    m_contextMenu->setRelPos(button->getRelPos());
     m_contextMenu->begin(button->getSize().x);
     {
         for(size_t i = 0; i < m_sortingMethods.size(); i++) {
@@ -3261,7 +3261,7 @@ void SongBrowser::onAfterSortingOrGroupChange(bool autoScroll) {
 
 void SongBrowser::onSelectionMode() {
     m_contextMenu->setPos(m_bottombarNavButtons[0]->getPos());
-    m_contextMenu->setScrollPos(m_bottombarNavButtons[0]->getRelPos());
+    m_contextMenu->setRelPos(m_bottombarNavButtons[0]->getRelPos());
     m_contextMenu->begin(0, true);
     {
         UIContextMenuButton *standardButton = m_contextMenu->addButton("Standard", 0);
@@ -3285,7 +3285,7 @@ void SongBrowser::onSelectionMode() {
     m_contextMenu->setPos(m_contextMenu->getPos() -
                           Vector2((m_contextMenu->getSize().x - m_bottombarNavButtons[0]->getSize().x) / 2.0f,
                                   m_contextMenu->getSize().y));
-    m_contextMenu->setScrollPos(m_contextMenu->getRelPos() -
+    m_contextMenu->setRelPos(m_contextMenu->getRelPos() -
                              Vector2((m_contextMenu->getSize().x - m_bottombarNavButtons[0]->getSize().x) / 2.0f,
                                      m_contextMenu->getSize().y));
     m_contextMenu->end(true, false);
@@ -3470,7 +3470,7 @@ void SongBrowser::onSongButtonContextMenu(SongButton *songButton, UString text,
     }
 
     if(updateUIScheduled) {
-        const float prevScrollPosY = m_songBrowser->getScrollPosY();  // usability
+        const float prevScrollPosY = m_songBrowser->getRelPosY();  // usability
         const auto previouslySelectedCollectionName =
             (m_selectionPreviousCollectionButton != NULL ? m_selectionPreviousCollectionButton->getCollectionName()
                                                          : "");  // usability

+ 1 - 1
src/App/Osu/SongBrowser/SongButton.cpp

@@ -272,7 +272,7 @@ void SongButton::onRightMouseUpInside() { triggerContextMenu(engine->getMouse()-
 void SongButton::triggerContextMenu(Vector2 pos) {
     if(m_contextMenu != NULL) {
         m_contextMenu->setPos(pos);
-        m_contextMenu->setScrollPos(pos);
+        m_contextMenu->setRelPos(pos);
         m_contextMenu->begin(0, true);
         {
             if(m_databaseBeatmap != NULL && m_databaseBeatmap->getDifficulties().size() < 1)

+ 4 - 4
src/App/Osu/UIContextMenu.cpp

@@ -257,7 +257,7 @@ void UIContextMenu::end(bool invertAnimation, bool clampUnderflowAndOverflowAndE
             if(m_vPos.y < 0) {
                 const float underflow = std::abs(m_vPos.y);
 
-                setScrollPosY(m_vPos.y + underflow);
+                setRelPosY(m_vPos.y + underflow);
                 setPosY(m_vPos.y + underflow);
                 setSizeY(m_vSize.y - underflow);
 
@@ -295,7 +295,7 @@ void UIContextMenu::setVisible2(bool visible2) {
 void UIContextMenu::onResized() { setSize(m_vSize); }
 
 void UIContextMenu::onMoved() {
-    setScrollPos(m_vPos);
+    setRelPos(m_vPos);
     setPos(m_vPos);
 }
 
@@ -322,7 +322,7 @@ void UIContextMenu::onHitEnter(UIContextMenuTextbox *textbox) {
 void UIContextMenu::clampToBottomScreenEdge(UIContextMenu *menu) {
     if(menu->getRelPos().y + menu->getSize().y > osu->getScreenHeight()) {
         int newRelPosY = osu->getScreenHeight() - menu->getSize().y - 1;
-        menu->setScrollPosY(newRelPosY);
+        menu->setRelPosY(newRelPosY);
         menu->setPosY(newRelPosY);
     }
 }
@@ -330,7 +330,7 @@ void UIContextMenu::clampToBottomScreenEdge(UIContextMenu *menu) {
 void UIContextMenu::clampToRightScreenEdge(UIContextMenu *menu) {
     if(menu->getRelPos().x + menu->getSize().x > osu->getScreenWidth()) {
         const int newRelPosX = osu->getScreenWidth() - menu->getSize().x - 1;
-        menu->setScrollPosX(newRelPosX);
+        menu->setRelPosX(newRelPosX);
         menu->setPosX(newRelPosX);
     }
 }

+ 1 - 16
src/GUI/CBaseUIBoxShadow.h

@@ -1,15 +1,4 @@
-//================ Copyright (c) 2013, PG, All rights reserved. =================//
-//
-// Purpose:		box shadows
-//
-// $NoKeywords: $bshad
-//===============================================================================//
-
-// TODO: fix this
-
-#ifndef CBASEUIBOXSHADOW_H
-#define CBASEUIBOXSHADOW_H
-
+#pragma once
 #include "CBaseUIElement.h"
 
 class Shader;
@@ -23,8 +12,6 @@ class CBaseUIBoxShadow : public CBaseUIElement {
                      float ySize = 0, UString name = "");
     virtual ~CBaseUIBoxShadow();
 
-    ELEMENT_BODY(CBaseUIBoxShadow)
-
     virtual void draw(Graphics *g);
     void renderOffscreen(Graphics *g);
 
@@ -79,5 +66,3 @@ class GaussianBlur {
     GaussianBlurKernel *m_kernel;
     Shader *m_blurShader;
 };
-
-#endif

+ 0 - 2
src/GUI/CBaseUIButton.h

@@ -9,8 +9,6 @@ class CBaseUIButton : public CBaseUIElement {
                   UString text = "");
     virtual ~CBaseUIButton() { ; }
 
-    ELEMENT_BODY(CBaseUIButton);
-
     virtual void draw(Graphics *g);
 
     void click() { onClicked(); }

+ 1 - 14
src/GUI/CBaseUICheckbox.h

@@ -1,13 +1,4 @@
-//================ Copyright (c) 2014, PG, All rights reserved. =================//
-//
-// Purpose:		a simple checkbox
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef CBASEUICHECKBOX_H
-#define CBASEUICHECKBOX_H
-
+#pragma once
 #include "CBaseUIButton.h"
 
 class CBaseUICheckbox : public CBaseUIButton {
@@ -16,8 +7,6 @@ class CBaseUICheckbox : public CBaseUIButton {
                     UString text = "");
     virtual ~CBaseUICheckbox() { ; }
 
-    ELEMENT_BODY(CBaseUICheckbox)
-
     virtual void draw(Graphics *g);
 
     inline float getBlockSize() { return m_vSize.y / 2; }
@@ -40,5 +29,3 @@ class CBaseUICheckbox : public CBaseUIButton {
     bool m_bChecked;
     CheckboxChangeCallback m_changeCallback;
 };
-
-#endif

+ 8 - 12
src/GUI/CBaseUIContainer.cpp

@@ -21,7 +21,7 @@ void CBaseUIContainer::empty() { m_vElements = std::vector<CBaseUIElement *>();
 CBaseUIContainer *CBaseUIContainer::addBaseUIElement(CBaseUIElement *element, float xPos, float yPos) {
     if(element == NULL) return this;
 
-    element->setScrollPos(xPos, yPos);
+    element->setRelPos(xPos, yPos);
     element->setPos(m_vPos + element->getRelPos());
     m_vElements.push_back(element);
 
@@ -31,7 +31,7 @@ CBaseUIContainer *CBaseUIContainer::addBaseUIElement(CBaseUIElement *element, fl
 CBaseUIContainer *CBaseUIContainer::addBaseUIElement(CBaseUIElement *element) {
     if(element == NULL) return this;
 
-    element->setScrollPos(element->getPos().x, element->getPos().y);
+    element->setRelPos(element->getPos().x, element->getPos().y);
     element->setPos(m_vPos + element->getRelPos());
     m_vElements.push_back(element);
 
@@ -41,7 +41,7 @@ CBaseUIContainer *CBaseUIContainer::addBaseUIElement(CBaseUIElement *element) {
 CBaseUIContainer *CBaseUIContainer::addBaseUIElementBack(CBaseUIElement *element, float xPos, float yPos) {
     if(element == NULL) return this;
 
-    element->setScrollPos(xPos, yPos);
+    element->setRelPos(xPos, yPos);
     element->setPos(m_vPos + element->getRelPos());
     m_vElements.insert(m_vElements.begin(), element);
 
@@ -51,7 +51,7 @@ CBaseUIContainer *CBaseUIContainer::addBaseUIElementBack(CBaseUIElement *element
 CBaseUIContainer *CBaseUIContainer::addBaseUIElementBack(CBaseUIElement *element) {
     if(element == NULL) return this;
 
-    element->setScrollPos(element->getPos().x, element->getPos().y);
+    element->setRelPos(element->getPos().x, element->getPos().y);
     element->setPos(m_vPos + element->getRelPos());
     m_vElements.insert(m_vElements.begin(), element);
 
@@ -61,7 +61,7 @@ CBaseUIContainer *CBaseUIContainer::addBaseUIElementBack(CBaseUIElement *element
 CBaseUIContainer *CBaseUIContainer::insertBaseUIElement(CBaseUIElement *element, CBaseUIElement *index) {
     if(element == NULL || index == NULL) return this;
 
-    element->setScrollPos(element->getPos().x, element->getPos().y);
+    element->setRelPos(element->getPos().x, element->getPos().y);
     element->setPos(m_vPos + element->getRelPos());
     for(size_t i = 0; i < m_vElements.size(); i++) {
         if(m_vElements[i] == index) {
@@ -78,7 +78,7 @@ CBaseUIContainer *CBaseUIContainer::insertBaseUIElement(CBaseUIElement *element,
 CBaseUIContainer *CBaseUIContainer::insertBaseUIElementBack(CBaseUIElement *element, CBaseUIElement *index) {
     if(element == NULL || index == NULL) return this;
 
-    element->setScrollPos(element->getPos().x, element->getPos().y);
+    element->setRelPos(element->getPos().x, element->getPos().y);
     element->setPos(m_vPos + element->getRelPos());
     for(size_t i = 0; i < m_vElements.size(); i++) {
         if(m_vElements[i] == index) {
@@ -131,7 +131,7 @@ void CBaseUIContainer::draw(Graphics *g) {
     if(!m_bVisible) return;
 
     for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(!m_vElements[i]->isDrawnManually()) m_vElements[i]->draw(g);
+        m_vElements[i]->draw(g);
     }
 }
 
@@ -154,14 +154,10 @@ void CBaseUIContainer::mouse_update(bool *propagate_clicks) {
 
 void CBaseUIContainer::update_pos() {
     for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(!m_vElements[i]->isPositionedManually()) m_vElements[i]->setPos(m_vPos + m_vElements[i]->getRelPos());
+        m_vElements[i]->setPos(m_vPos + m_vElements[i]->getRelPos());
     }
 }
 
-void CBaseUIContainer::update_pos(CBaseUIElement *element) {
-    if(element != NULL) element->setPos(m_vPos + element->getRelPos());
-}
-
 void CBaseUIContainer::onKeyUp(KeyboardEvent &e) {
     for(size_t i = 0; i < m_vElements.size(); i++) {
         if(m_vElements[i]->isVisible()) m_vElements[i]->onKeyUp(e);

+ 1 - 15
src/GUI/CBaseUIContainer.h

@@ -1,13 +1,4 @@
-//================ Copyright (c) 2011, PG, All rights reserved. =================//
-//
-// Purpose:		a container for UI elements
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef CBASEUICONTAINER_H
-#define CBASEUICONTAINER_H
-
+#pragma once
 #include "CBaseUIElement.h"
 
 class CBaseUIContainer : public CBaseUIElement {
@@ -15,8 +6,6 @@ class CBaseUIContainer : public CBaseUIElement {
     CBaseUIContainer(float xPos = 0, float yPos = 0, float xSize = 0, float ySize = 0, UString name = "");
     virtual ~CBaseUIContainer();
 
-    ELEMENT_BODY(CBaseUIContainer)
-
     void clear();
     void empty();
 
@@ -56,10 +45,7 @@ class CBaseUIContainer : public CBaseUIElement {
     virtual void onDisabled();
 
     void update_pos();
-    void update_pos(CBaseUIElement *element);
 
    protected:
     std::vector<CBaseUIElement *> m_vElements;
 };
-
-#endif

+ 0 - 207
src/GUI/CBaseUIContainerBase.cpp

@@ -1,207 +0,0 @@
-#include "CBaseUIContainerBase.h"
-
-#include "Engine.h"
-
-using namespace std;
-
-CBaseUIContainerBase::CBaseUIContainerBase(UString name) : CBaseUIElement(0, 0, 0, 0, name) { m_bClipping = false; }
-
-CBaseUIContainerBase::~CBaseUIContainerBase() {}
-
-void CBaseUIContainerBase::empty() {
-    for(size_t i = 0; i < m_vElements.size(); i++) m_vElements[i]->setParent(NULL);
-
-    m_vElements = std::vector<std::shared_ptr<CBaseUIElement>>();
-}
-
-CBaseUIContainerBase *CBaseUIContainerBase::addElement(CBaseUIElement *element, bool back) {
-    if(element == NULL) return this;
-
-    element->setParent(this);
-    std::shared_ptr<CBaseUIElement> buffer(element);
-
-    if(back)
-        m_vElements.insert(m_vElements.begin(), buffer);
-    else
-        m_vElements.push_back(buffer);
-
-    updateElement(element);
-    return this;
-}
-
-CBaseUIContainerBase *CBaseUIContainerBase::addElement(std::shared_ptr<CBaseUIElement> element, bool back) {
-    if(element == NULL || element.get() == NULL) return this;
-
-    element->setParent(this);
-
-    if(back)
-        m_vElements.insert(m_vElements.begin(), element);
-    else
-        m_vElements.push_back(element);
-
-    updateElement(element.get());
-    return this;
-}
-
-CBaseUIContainerBase *CBaseUIContainerBase::insertElement(CBaseUIElement *element, CBaseUIElement *index, bool back) {
-    if(element == NULL || index == NULL) return this;
-
-    for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(m_vElements[i].get() == index) {
-            std::shared_ptr<CBaseUIElement> buffer(element);
-            element->setParent(this);
-
-            if(back)
-                m_vElements.insert(m_vElements.begin() + clamp<int>(i + 1, 0, m_vElements.size()), buffer);
-            else
-                m_vElements.insert(m_vElements.begin() + clamp<int>(i, 0, m_vElements.size()), buffer);
-
-            updateElement(element);
-            return this;
-        }
-    }
-
-    debugLog("Warning: %s::insertSlot() couldn't find index: %s\n", getName().toUtf8(), index->getName().toUtf8());
-
-    return this;
-}
-
-CBaseUIContainerBase *CBaseUIContainerBase::insertElement(CBaseUIElement *element,
-                                                          std::shared_ptr<CBaseUIElement> index, bool back) {
-    if(element == NULL || index == NULL || index.get() == NULL) return this;
-
-    for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(m_vElements[i] == index) {
-            std::shared_ptr<CBaseUIElement> buffer(element);
-            element->setParent(this);
-
-            if(back)
-                m_vElements.insert(m_vElements.begin() + clamp<int>(i + 1, 0, m_vElements.size()), buffer);
-            else
-                m_vElements.insert(m_vElements.begin() + clamp<int>(i, 0, m_vElements.size()), buffer);
-
-            updateElement(element);
-            return this;
-        }
-    }
-
-    return this;
-}
-
-CBaseUIContainerBase *CBaseUIContainerBase::insertElement(std::shared_ptr<CBaseUIElement> element,
-                                                          CBaseUIElement *index, bool back) {
-    if(element == NULL || element.get() == NULL || index == NULL) return this;
-
-    for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(m_vElements[i].get() == index) {
-            element.get()->setParent(this);
-
-            if(back)
-                m_vElements.insert(m_vElements.begin() + clamp<int>(i + 1, 0, m_vElements.size()), element);
-            else
-                m_vElements.insert(m_vElements.begin() + clamp<int>(i, 0, m_vElements.size()), element);
-
-            updateElement(element.get());
-            return this;
-        }
-    }
-
-    return this;
-}
-
-CBaseUIContainerBase *CBaseUIContainerBase::insertElement(std::shared_ptr<CBaseUIElement> element,
-                                                          std::shared_ptr<CBaseUIElement> index, bool back) {
-    if(element == NULL || index == NULL || element.get() == NULL || index.get() == NULL) return this;
-
-    for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(m_vElements[i] == index) {
-            element->setParent(this);
-            if(back)
-                m_vElements.insert(m_vElements.begin() + clamp<int>(i + 1, 0, m_vElements.size()), element);
-            else
-                m_vElements.insert(m_vElements.begin() + clamp<int>(i, 0, m_vElements.size()), element);
-            updateElement(element.get());
-            return this;
-        }
-    }
-
-    debugLog("Warning: %s::insertSlot() couldn't find index: %s\n", getName().toUtf8(),
-             index.get()->getName().toUtf8());
-
-    return this;
-}
-
-void CBaseUIContainerBase::removeElement(CBaseUIElement *element) {
-    for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(m_vElements[i].get() == element) {
-            m_vElements[i]->setParent(NULL);
-            m_vElements.erase(m_vElements.begin() + i);
-            updateLayout();
-            return;
-        }
-    }
-
-    debugLog("Warning: CBaseUIContainerBase::removeElement() couldn't find element\n");
-}
-
-void CBaseUIContainerBase::removeElement(std::shared_ptr<CBaseUIElement> element) {
-    for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(m_vElements[i] == element) {
-            m_vElements[i]->setParent(NULL);
-            m_vElements.erase(m_vElements.begin() + i);
-            updateLayout();
-            return;
-        }
-    }
-
-    debugLog("Warning: CBaseUIContainerBase::removeElement() couldn't find element\n");
-}
-
-CBaseUIElement *CBaseUIContainerBase::getElementByName(UString name, bool searchNestedContainers) {
-    for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(m_vElements[i]->getName() == name)
-            return m_vElements[i].get();
-
-        else if(searchNestedContainers) {
-            CBaseUIContainerBase *container = dynamic_cast<CBaseUIContainerBase *>(m_vElements[i].get());
-            if(container != NULL) return container->getElementByName(name, true);
-        }
-    }
-
-    debugLog("Error: CBaseUIContainerBase::getSlotByElementName() \"%s\" does not exist!!!\n", name.toUtf8());
-    return NULL;
-}
-
-std::shared_ptr<CBaseUIElement> CBaseUIContainerBase::getElementSharedByName(UString name,
-                                                                             bool searchNestedContainers) {
-    for(size_t i = 0; i < m_vElements.size(); i++) {
-        if(m_vElements[i]->getName() == name)
-            return m_vElements[i];
-
-        else if(searchNestedContainers) {
-            CBaseUIContainerBase *container = dynamic_cast<CBaseUIContainerBase *>(m_vElements[i].get());
-            if(container != NULL) return container->getElementSharedByName(name, true);
-        }
-    }
-
-    debugLog("Error: CBaseUIContainerBase::getSlotByElementName() \"%s\" does not exist!!!\n", name.toUtf8());
-    return NULL;
-}
-
-void CBaseUIContainerBase::draw(Graphics *g) {
-    if(!m_bVisible) return;
-
-    if(m_bClipping) g->pushClipRect(McRect(m_vPos.x + 1, m_vPos.y + 1, m_vSize.x - 1, m_vSize.y));
-
-    for(size_t i = 0; i < m_vElements.size(); i++) {
-        m_vElements[i]->draw(g);
-    }
-
-    if(m_bClipping) g->popClipRect();
-}
-
-void CBaseUIContainerBase::mouse_update(bool *propagate_clicks) {
-    if(!m_bVisible) return;
-
-    for(size_t i = 0; i < m_vElements.size(); i++) m_vElements[i]->mouse_update(propagate_clicks);
-}

+ 0 - 92
src/GUI/CBaseUIContainerBase.h

@@ -1,92 +0,0 @@
-/*
- * CBaseUIContainerBase.h
- *
- *  Created on: May 31, 2017
- *      Author: Psy
- */
-
-#ifndef GUI_CBASEUICONTAINERBASE_H_
-#define GUI_CBASEUICONTAINERBASE_H_
-
-#define CONTAINER_BODY(T)                                                                                         \
-    ELEMENT_BODY(T)                                                                                               \
-                                                                                                                  \
-    virtual T *addElement(CBaseUIElement *element, bool back = false) {                                           \
-        CBaseUIContainerBase::addElement(element, back);                                                          \
-        return this;                                                                                              \
-    }                                                                                                             \
-    virtual T *addElement(std::shared_ptr<CBaseUIElement> element, bool back = false) {                           \
-        CBaseUIContainerBase::addElement(element, back);                                                          \
-        return this;                                                                                              \
-    }                                                                                                             \
-    virtual T *insertElement(CBaseUIElement *element, CBaseUIElement *index, bool back = false) {                 \
-        CBaseUIContainerBase::insertElement(element, index, back);                                                \
-        return this;                                                                                              \
-    }                                                                                                             \
-    virtual T *insertElement(std::shared_ptr<CBaseUIElement> element, CBaseUIElement *index, bool back = false) { \
-        CBaseUIContainerBase::insertElement(element, index, back);                                                \
-        return this;                                                                                              \
-    }                                                                                                             \
-    virtual T *insertElement(CBaseUIElement *element, std::shared_ptr<CBaseUIElement> index, bool back = false) { \
-        CBaseUIContainerBase::insertElement(element, index, back);                                                \
-        return this;                                                                                              \
-    }                                                                                                             \
-    virtual T *insertElement(std::shared_ptr<CBaseUIElement> element, std::shared_ptr<CBaseUIElement> index,      \
-                             bool back = false) {                                                                 \
-        CBaseUIContainerBase::insertElement(element, index, back);                                                \
-        return this;                                                                                              \
-    }                                                                                                             \
-    virtual T *setClipping(bool clipping) {                                                                       \
-        CBaseUIContainerBase::setClipping(clipping);                                                              \
-        return this;                                                                                              \
-    }
-
-#include "CBaseUIElement.h"
-#include "cbase.h"
-
-class CBaseUIContainerBase : public CBaseUIElement {
-   public:
-    CBaseUIContainerBase(UString name = "");
-    virtual ~CBaseUIContainerBase();
-
-    ELEMENT_BODY(CBaseUIContainerBase);
-
-    virtual CBaseUIContainerBase *addElement(CBaseUIElement *element, bool back = false);
-    virtual CBaseUIContainerBase *addElement(std::shared_ptr<CBaseUIElement> element, bool back = false);
-    virtual CBaseUIContainerBase *insertElement(CBaseUIElement *element, CBaseUIElement *index, bool back = false);
-    virtual CBaseUIContainerBase *insertElement(std::shared_ptr<CBaseUIElement> element, CBaseUIElement *index,
-                                                bool back = false);
-    virtual CBaseUIContainerBase *insertElement(CBaseUIElement *element, std::shared_ptr<CBaseUIElement> index,
-                                                bool back = false);
-    virtual CBaseUIContainerBase *insertElement(std::shared_ptr<CBaseUIElement> element,
-                                                std::shared_ptr<CBaseUIElement> index, bool back = false);
-
-    virtual void removeElement(CBaseUIElement *element);
-    virtual void removeElement(std::shared_ptr<CBaseUIElement> element);
-
-    virtual CBaseUIContainerBase *setClipping(bool clipping) {
-        m_bClipping = clipping;
-        return this;
-    }
-
-    CBaseUIElement *getElementByName(UString name, bool searchNestedContainers = false);
-    std::shared_ptr<CBaseUIElement> getElementSharedByName(UString name, bool searchNestedContainers = false);
-    std::vector<CBaseUIElement *> getAllElements();
-    inline std::vector<std::shared_ptr<CBaseUIElement>> getAllElementsShared() { return m_vElements; }
-    inline std::vector<std::shared_ptr<CBaseUIElement>> *getAllElementsReference() { return &m_vElements; }
-
-    virtual void draw(Graphics *g);
-    virtual void drawDebug(Graphics *g, Color color = COLOR(255, 255, 0, 0)) { ; }
-    virtual void mouse_update(bool *propagate_clicks);
-
-    virtual void empty();
-
-   protected:
-    // events
-    virtual void updateElement(CBaseUIElement *element) { ; }
-
-    bool m_bClipping;
-    std::vector<std::shared_ptr<CBaseUIElement>> m_vElements;
-};
-
-#endif /* GUI_CBASEUICONTAINERBASE_H_ */

+ 0 - 40
src/GUI/CBaseUIElement.cpp

@@ -1,48 +1,8 @@
-//================ Copyright (c) 2013, PG, All rights reserved. =================//
-//
-// Purpose:		the base class for all UI Elements
-//
-// $NoKeywords: $buie
-//===============================================================================//
-
 #include "CBaseUIElement.h"
 
 #include "Engine.h"
 #include "Mouse.h"
 
-CBaseUIElement::CBaseUIElement(float xPos, float yPos, float xSize, float ySize, UString name) {
-    // pos, size, name
-    m_vPos.x = xPos;
-    m_vPos.y = yPos;
-    m_vmPos.x = m_vPos.x;
-    m_vmPos.y = m_vPos.y;
-    m_vSize.x = xSize;
-    m_vSize.y = ySize;
-    m_vmSize.x = m_vSize.x;
-    m_vmSize.y = m_vSize.y;
-    m_vAnchor.x = 0;
-    m_vAnchor.y = 0;
-    m_sName = name;
-    m_parent = NULL;
-
-    // attributes
-    m_bVisible = true;
-    m_bActive = false;
-    m_bBusy = false;
-    m_bEnabled = true;
-
-    m_bKeepActive = false;
-    m_bDrawManually = false;
-    m_bPositionManually = false;
-    m_bMouseInside = false;
-
-    // container options
-    m_bScaleByHeightOnly = false;
-
-    m_bMouseInsideCheck = false;
-    m_bMouseUpCheck = false;
-}
-
 void CBaseUIElement::mouse_update(bool *propagate_clicks) {
     // check if mouse is inside element
     McRect temp = McRect(m_vPos.x + 1, m_vPos.y + 1, m_vSize.x - 1, m_vSize.y - 1);

+ 122 - 399
src/GUI/CBaseUIElement.h

@@ -1,387 +1,27 @@
 #pragma once
+#include "KeyboardListener.h"
 #include "cbase.h"
 
-#define ELEMENT_BODY(T)                                          \
-    virtual T *setPos(float xPos, float yPos) {                  \
-        if(m_vPos.x != xPos || m_vPos.y != yPos) {               \
-            m_vPos.x = xPos - m_vSize.x * m_vAnchor.x;           \
-            m_vPos.y = yPos - m_vSize.y * m_vAnchor.y;           \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setPosX(float xPos) {                             \
-        if(m_vPos.x != xPos) {                                   \
-            m_vPos.x = xPos - m_vSize.x * m_vAnchor.x;           \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setPosY(float yPos) {                             \
-        if(m_vPos.y != yPos) {                                   \
-            m_vPos.y = yPos - m_vSize.y * m_vAnchor.y;           \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setPos(Vector2 position) {                        \
-        if(m_vPos != position) {                                 \
-            m_vPos = position - m_vSize * m_vAnchor;             \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setPosAbsolute(float xPos, float yPos) {          \
-        if(m_vPos.x != xPos || m_vPos.y != yPos) {               \
-            m_vPos.x = xPos;                                     \
-            m_vPos.y = yPos;                                     \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setPosAbsoluteX(float xPos) {                     \
-        if(m_vPos.x != xPos) {                                   \
-            m_vPos.x = xPos;                                     \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setPosAbsoluteY(float yPos) {                     \
-        if(m_vPos.y != yPos) {                                   \
-            m_vPos.y = yPos;                                     \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setPosAbsolute(Vector2 position) {                \
-        if(m_vPos != position) {                                 \
-            m_vPos = position;                                   \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setScrollPos(float xPos, float yPos) {               \
-        if(m_vmPos.x != xPos || m_vmPos.y != yPos) {             \
-            m_vmPos.x = xPos - m_vSize.x * m_vAnchor.x;          \
-            m_vmPos.y = yPos - m_vSize.y * m_vAnchor.y;          \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setScrollPosX(float xPos) {                          \
-        if(m_vmPos.x != xPos) {                                  \
-            m_vmPos.x = xPos - m_vSize.x * m_vAnchor.x;          \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setScrollPosY(float yPos) {                          \
-        if(m_vmPos.y != yPos) {                                  \
-            m_vmPos.y = yPos - m_vSize.x * m_vAnchor.y;          \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setScrollPos(Vector2 position) {                     \
-        if(m_vmPos != position) {                                \
-            m_vmPos = position - m_vSize * m_vAnchor;            \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setScrollPosAbsolute(float xPos, float yPos) {       \
-        if(m_vmPos.x != xPos || m_vmPos.y != yPos) {             \
-            m_vmPos.x = xPos;                                    \
-            m_vmPos.y = yPos;                                    \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setScrollPosAbsoluteX(float xPos) {                  \
-        if(m_vmPos.x != xPos) {                                  \
-            m_vmPos.x = xPos;                                    \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setScrollPosAbsoluteY(float yPos) {                  \
-        if(m_vmPos.y != yPos) {                                  \
-            m_vmPos.y = yPos;                                    \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setScrollPosAbsolute(Vector2 position) {             \
-        if(m_vmPos != position) {                                \
-            m_vmPos = position;                                  \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setSize(float xSize, float ySize) {               \
-        if(m_vSize.x != xSize || m_vSize.y != ySize) {           \
-            m_vPos.x += (m_vSize.x - xSize) * m_vAnchor.x;       \
-            m_vPos.y += (m_vSize.y - ySize) * m_vAnchor.y;       \
-            m_vSize.x = xSize;                                   \
-            m_vSize.y = ySize;                                   \
-            onResized();                                         \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setSizeX(float xSize) {                           \
-        if(m_vSize.x != xSize) {                                 \
-            m_vPos.x += (m_vSize.x - xSize) * m_vAnchor.x;       \
-            m_vSize.x = xSize;                                   \
-            onResized();                                         \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setSizeY(float ySize) {                           \
-        if(m_vSize.y != ySize) {                                 \
-            m_vPos.y += (m_vSize.y - ySize) * m_vAnchor.y;       \
-            m_vSize.y = ySize;                                   \
-            onResized();                                         \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setSize(Vector2 size) {                           \
-        if(m_vSize != size) {                                    \
-            m_vPos += (m_vSize - size) * m_vAnchor;              \
-            m_vSize = size;                                      \
-            onResized();                                         \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setSizeAbsolute(float xSize, float ySize) {       \
-        if(m_vSize.x != xSize || m_vSize.y != ySize) {           \
-            m_vSize.x = xSize;                                   \
-            m_vSize.y = ySize;                                   \
-            onResized();                                         \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setSizeAbsoluteX(float xSize) {                   \
-        if(m_vSize.x != xSize) {                                 \
-            m_vSize.x = xSize;                                   \
-            onResized();                                         \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setSizeAbsoluteY(float ySize) {                   \
-        if(m_vSize.y != ySize) {                                 \
-            m_vSize.y = ySize;                                   \
-            onResized();                                         \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setSizeAbsolute(Vector2 size) {                   \
-        if(m_vSize != size) {                                    \
-            m_vSize = size;                                      \
-            onResized();                                         \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setRelSize(float xSize, float ySize) {            \
-        if(m_vmSize.x != xSize || m_vmSize.y != ySize) {         \
-            m_vmPos.x += (m_vmSize.x - xSize) * m_vAnchor.x;     \
-            m_vmPos.y += (m_vmSize.y - ySize) * m_vAnchor.y;     \
-            m_vmSize.x = xSize;                                  \
-            m_vmSize.y = ySize;                                  \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setRelSizeX(float xSize) {                        \
-        if(m_vmSize.x != xSize) {                                \
-            m_vmPos.x += (m_vmSize.x - xSize) * m_vAnchor.x;     \
-            m_vmSize.x = xSize;                                  \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setRelSizeY(float ySize) {                        \
-        if(m_vmSize.y != ySize) {                                \
-            m_vmPos.y += (m_vmSize.y - ySize) * m_vAnchor.y;     \
-            m_vmSize.y = ySize;                                  \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setRelSize(Vector2 size) {                        \
-        if(m_vmSize != size) {                                   \
-            m_vmPos += (m_vmSize - size) * m_vAnchor;            \
-            m_vmSize = size;                                     \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setRelSizeAbsolute(float xSize, float ySize) {    \
-        if(m_vmSize.x != xSize || m_vmSize.y != ySize) {         \
-            m_vmSize.x = xSize;                                  \
-            m_vmSize.y = ySize;                                  \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setRelSizeAbsoluteX(float xSize) {                \
-        if(m_vmSize.x != xSize) {                                \
-            m_vmSize.x = xSize;                                  \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setRelSizeAbsoluteY(float ySize) {                \
-        if(m_vmSize.y != ySize) {                                \
-            m_vmSize.y = ySize;                                  \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setRelSizeAbsolute(Vector2 size) {                \
-        if(m_vmSize != size) {                                   \
-            m_vmSize = size;                                     \
-            updateLayout();                                      \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setAnchor(float xAnchor, float yAnchor) {         \
-        if(m_vAnchor.x != xAnchor || m_vAnchor.y != yAnchor) {   \
-            m_vmPos.x -= m_vmSize.x * (xAnchor - m_vAnchor.x);   \
-            m_vmPos.y -= m_vmSize.y * (yAnchor - m_vAnchor.y);   \
-            m_vPos.x -= m_vSize.x * (xAnchor - m_vAnchor.x);     \
-            m_vPos.y -= m_vSize.y * (yAnchor - m_vAnchor.y);     \
-            m_vAnchor.x = xAnchor;                               \
-            m_vAnchor.y = yAnchor;                               \
-            if(m_parent != NULL) updateLayout();                 \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setAnchorX(float xAnchor) {                       \
-        if(m_vAnchor.x != xAnchor) {                             \
-            m_vmPos.x -= m_vmSize.x * (xAnchor - m_vAnchor.x);   \
-            m_vPos.x -= m_vSize.x * (xAnchor - m_vAnchor.x);     \
-            m_vAnchor.x = xAnchor;                               \
-            if(m_parent != NULL) updateLayout();                 \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setAnchorY(float yAnchor) {                       \
-        if(m_vAnchor.y != yAnchor) {                             \
-            m_vmPos.y -= m_vmSize.y * (yAnchor - m_vAnchor.y);   \
-            m_vPos.y -= m_vSize.y * (yAnchor - m_vAnchor.y);     \
-            m_vAnchor.y = yAnchor;                               \
-            if(m_parent != NULL) updateLayout();                 \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setAnchor(Vector2 anchor) {                       \
-        if(m_vAnchor != anchor) {                                \
-            m_vmPos -= m_vmSize * (anchor - m_vAnchor);          \
-            m_vPos -= m_vSize * (anchor - m_vAnchor);            \
-            m_vAnchor = anchor;                                  \
-            if(m_parent != NULL) updateLayout();                 \
-            onMoved();                                           \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setAnchorAbsolute(float xAnchor, float yAnchor) { \
-        if(m_vAnchor.x != xAnchor || m_vAnchor.y != yAnchor) {   \
-            m_vAnchor.x = xAnchor, m_vAnchor.y = yAnchor;        \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setAnchorAbsoluteX(float xAnchor) {               \
-        if(m_vAnchor.x != xAnchor) {                             \
-            m_vAnchor.x = xAnchor;                               \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setAnchorAbsoluteY(float yAnchor) {               \
-        if(m_vAnchor.y != yAnchor) {                             \
-            m_vAnchor.y = yAnchor;                               \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setAnchorAbsolute(Vector2 anchor) {               \
-        if(m_vAnchor != anchor) {                                \
-            m_vAnchor = anchor;                                  \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-                                                                 \
-    virtual T *setVisible(bool visible) {                        \
-        m_bVisible = visible;                                    \
-        return this;                                             \
-    }                                                            \
-    virtual T *setActive(bool active) {                          \
-        m_bActive = active;                                      \
-        return this;                                             \
-    }                                                            \
-    virtual T *setKeepActive(bool keepActive) {                  \
-        m_bKeepActive = keepActive;                              \
-        return this;                                             \
-    }                                                            \
-    virtual T *setDrawManually(bool drawManually) {              \
-        m_bDrawManually = drawManually;                          \
-        return this;                                             \
-    }                                                            \
-    virtual T *setPositionManually(bool positionManually) {      \
-        m_bPositionManually = positionManually;                  \
-        return this;                                             \
-    }                                                            \
-    virtual T *setEnabled(bool enabled) {                        \
-        if(enabled != m_bEnabled) {                              \
-            m_bEnabled = enabled;                                \
-            if(m_bEnabled) {                                     \
-                onEnabled();                                     \
-            } else {                                             \
-                onDisabled();                                    \
-            }                                                    \
-        }                                                        \
-        return this;                                             \
-    }                                                            \
-    virtual T *setBusy(bool busy) {                              \
-        m_bBusy = busy;                                          \
-        return this;                                             \
-    }                                                            \
-    virtual T *setName(UString name) {                           \
-        m_sName = name;                                          \
-        return this;                                             \
-    }                                                            \
-    virtual T *setParent(CBaseUIElement *parent) {               \
-        m_parent = parent;                                       \
-        return this;                                             \
-    }                                                            \
-    virtual T *setScaleByHeightOnly(bool scaleByHeightOnly) {    \
-        m_bScaleByHeightOnly = scaleByHeightOnly;                \
-        return this;                                             \
-    }
-
-#include "KeyboardListener.h"
+// Guidelines for avoiding hair pulling:
+// - Don't use m_vmSize
+// - When an element is standalone, use getPos/setPos
+// - In a container or in a scrollview, use getRelPos/setRelPos and call update_pos() on the container
 
 class CBaseUIElement : public KeyboardListener {
    public:
-    CBaseUIElement(float xPos = 0, float yPos = 0, float xSize = 0, float ySize = 0, UString name = "");
+    CBaseUIElement(float xPos = 0, float yPos = 0, float xSize = 0, float ySize = 0, UString name = "") {
+        m_vPos.x = xPos;
+        m_vPos.y = yPos;
+        m_vmPos.x = m_vPos.x;
+        m_vmPos.y = m_vPos.y;
+        m_vSize.x = xSize;
+        m_vSize.y = ySize;
+        m_vmSize.x = m_vSize.x;
+        m_vmSize.y = m_vSize.y;
+        m_sName = name;
+    }
     virtual ~CBaseUIElement() { ; }
 
-    ELEMENT_BODY(CBaseUIElement)
-
     // main
     virtual void draw(Graphics *g) = 0;
     virtual void mouse_update(bool *propagate_clicks);
@@ -398,17 +38,110 @@ class CBaseUIElement : public KeyboardListener {
     inline UString getName() const { return m_sName; }
     inline const Vector2 &getRelPos() const { return m_vmPos; }
     inline const Vector2 &getRelSize() const { return m_vmSize; }
-    inline const Vector2 &getAnchor() const { return m_vAnchor; }
-    inline CBaseUIElement *getParent() const { return m_parent; }
 
     virtual bool isActive() { return m_bActive || isBusy(); }
     virtual bool isVisible() { return m_bVisible; }
     virtual bool isEnabled() { return m_bEnabled; }
     virtual bool isBusy() { return m_bBusy && isVisible(); }
-    virtual bool isDrawnManually() { return m_bDrawManually; }
-    virtual bool isPositionedManually() { return m_bPositionManually; }
     virtual bool isMouseInside() { return m_bMouseInside && isVisible(); }
-    virtual bool isScaledByHeightOnly() { return m_bScaleByHeightOnly; }
+
+    virtual CBaseUIElement *setPos(float xPos, float yPos) {
+        if(m_vPos.x != xPos || m_vPos.y != yPos) {
+            m_vPos.x = xPos;
+            m_vPos.y = yPos;
+            onMoved();
+        }
+        return this;
+    }
+    virtual CBaseUIElement *setPosX(float xPos) {
+        if(m_vPos.x != xPos) {
+            m_vPos.x = xPos;
+            onMoved();
+        }
+        return this;
+    }
+    virtual CBaseUIElement *setPosY(float yPos) {
+        if(m_vPos.y != yPos) {
+            m_vPos.y = yPos;
+            onMoved();
+        }
+        return this;
+    }
+    virtual CBaseUIElement *setPos(Vector2 position) { return setPos(position.x, position.y); }
+
+    virtual CBaseUIElement *setRelPos(float xPos, float yPos) {
+        m_vmPos.x = xPos;
+        m_vmPos.y = yPos;
+        return this;
+    }
+    virtual CBaseUIElement *setRelPosX(float xPos) {
+        m_vmPos.x = xPos;
+        return this;
+    }
+    virtual CBaseUIElement *setRelPosY(float yPos) {
+        m_vmPos.y = yPos;
+        return this;
+    }
+    virtual CBaseUIElement *setRelPos(Vector2 position) { return setRelPos(position.x, position.y); }
+
+    virtual CBaseUIElement *setSize(float xSize, float ySize) {
+        if(m_vSize.x != xSize || m_vSize.y != ySize) {
+            m_vSize.x = xSize;
+            m_vSize.y = ySize;
+            onResized();
+            onMoved();
+        }
+        return this;
+    }
+    virtual CBaseUIElement *setSizeX(float xSize) {
+        if(m_vSize.x != xSize) {
+            m_vSize.x = xSize;
+            onResized();
+            onMoved();
+        }
+        return this;
+    }
+    virtual CBaseUIElement *setSizeY(float ySize) {
+        if(m_vSize.y != ySize) {
+            m_vSize.y = ySize;
+            onResized();
+            onMoved();
+        }
+        return this;
+    }
+    virtual CBaseUIElement *setSize(Vector2 size) { return setSize(size.x, size.y); }
+
+    virtual CBaseUIElement *setVisible(bool visible) {
+        m_bVisible = visible;
+        return this;
+    }
+    virtual CBaseUIElement *setActive(bool active) {
+        m_bActive = active;
+        return this;
+    }
+    virtual CBaseUIElement *setKeepActive(bool keepActive) {
+        m_bKeepActive = keepActive;
+        return this;
+    }
+    virtual CBaseUIElement *setEnabled(bool enabled) {
+        if(enabled != m_bEnabled) {
+            m_bEnabled = enabled;
+            if(m_bEnabled) {
+                onEnabled();
+            } else {
+                onDisabled();
+            }
+        }
+        return this;
+    }
+    virtual CBaseUIElement *setBusy(bool busy) {
+        m_bBusy = busy;
+        return this;
+    }
+    virtual CBaseUIElement *setName(UString name) {
+        m_sName = name;
+        return this;
+    }
 
     // actions
     void stealFocus() {
@@ -416,9 +149,6 @@ class CBaseUIElement : public KeyboardListener {
         m_bActive = false;
         onFocusStolen();
     }
-    void updateLayout() {
-        if(m_parent != NULL) m_parent->updateLayout();
-    }
 
    protected:
     // events
@@ -438,30 +168,23 @@ class CBaseUIElement : public KeyboardListener {
 
     // vars
     UString m_sName;
-    CBaseUIElement *m_parent;
 
     // attributes
-    bool m_bVisible;
-    bool m_bActive;  // we are doing something, e.g. textbox is blinking and ready to receive input
-    bool m_bBusy;    // we demand the focus to be kept on us, e.g. click-drag scrolling in a scrollview
-    bool m_bEnabled;
-
-    bool m_bKeepActive;  // once clicked, don't lose m_bActive, we have to manually release it (e.g. textbox)
-    bool m_bDrawManually;
-    bool m_bPositionManually;
-    bool m_bMouseInside;
+    bool m_bVisible = true;
+    bool m_bActive = false;  // we are doing something, e.g. textbox is blinking and ready to receive input
+    bool m_bBusy = false;    // we demand the focus to be kept on us, e.g. click-drag scrolling in a scrollview
+    bool m_bEnabled = true;
 
-    // container options
-    bool m_bScaleByHeightOnly;
+    bool m_bKeepActive = false;  // once clicked, don't lose m_bActive, we have to manually release it (e.g. textbox)
+    bool m_bMouseInside = false;
 
     // position and size
     Vector2 m_vPos;
     Vector2 m_vmPos;
     Vector2 m_vSize;
     Vector2 m_vmSize;
-    Vector2 m_vAnchor;  // the point of transformation
 
    private:
-    bool m_bMouseInsideCheck;
-    bool m_bMouseUpCheck;
+    bool m_bMouseInsideCheck = false;
+    bool m_bMouseUpCheck = false;
 };

+ 1 - 14
src/GUI/CBaseUIImage.h

@@ -1,13 +1,4 @@
-//================ Copyright (c) 2014, PG, All rights reserved. =================//
-//
-// Purpose:		a simple image class
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef CBASEUIIMAGE_H
-#define CBASEUIIMAGE_H
-
+#pragma once
 #include "CBaseUIElement.h"
 
 class CBaseUIImage : public CBaseUIElement {
@@ -16,8 +7,6 @@ class CBaseUIImage : public CBaseUIElement {
                  UString name = "");
     virtual ~CBaseUIImage() { ; }
 
-    ELEMENT_BODY(CBaseUIImage)
-
     virtual void draw(Graphics *g);
 
     void setImage(Image *img);
@@ -86,5 +75,3 @@ class CBaseUIImage : public CBaseUIElement {
     float m_fRot;
     Vector2 m_vScale;
 };
-
-#endif

+ 1 - 14
src/GUI/CBaseUIImageButton.h

@@ -1,13 +1,4 @@
-//================ Copyright (c) 2015, PG, All rights reserved. =================//
-//
-// Purpose:		a simple image button
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef CBASEUIIMAGEBUTTON_H
-#define CBASEUIIMAGEBUTTON_H
-
+#pragma once
 #include "CBaseUIButton.h"
 
 class CBaseUIImageButton : public CBaseUIButton {
@@ -16,8 +7,6 @@ class CBaseUIImageButton : public CBaseUIButton {
                        float ySize = 0, UString name = "");
     virtual ~CBaseUIImageButton() { ; }
 
-    ELEMENT_BODY(CBaseUIImageButton)
-
     virtual void draw(Graphics *g);
 
     virtual void onResized();
@@ -52,5 +41,3 @@ class CBaseUIImageButton : public CBaseUIButton {
     bool m_bScaleToFit;
     bool m_bKeepAspectRatio;
 };
-
-#endif

+ 0 - 7
src/GUI/CBaseUILabel.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2014, PG, All rights reserved. =================//
-//
-// Purpose:		a simple label
-//
-// $NoKeywords: $
-//===============================================================================//
-
 #include "CBaseUILabel.h"
 
 #include "Engine.h"

+ 6 - 14
src/GUI/CBaseUILabel.h

@@ -1,13 +1,4 @@
-//================ Copyright (c) 2014, PG, All rights reserved. =================//
-//
-// Purpose:		a simple label
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef CBASEUILABEL_H
-#define CBASEUILABEL_H
-
+#pragma once
 #include "CBaseUIElement.h"
 
 class CBaseUILabel : public CBaseUIElement {
@@ -19,11 +10,14 @@ class CBaseUILabel : public CBaseUIElement {
                  UString text = "");
     virtual ~CBaseUILabel() { ; }
 
-    ELEMENT_BODY(CBaseUILabel)
-
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
 
+    // cancer
+    void setRelSizeX(float x) {
+        m_vmSize.x = x;
+    }
+
     // set
     CBaseUILabel *setDrawFrame(bool drawFrame) {
         m_bDrawFrame = drawFrame;
@@ -103,5 +97,3 @@ class CBaseUILabel : public CBaseUIElement {
 
     TEXT_JUSTIFICATION m_textJustification;
 };
-
-#endif

+ 2 - 4
src/GUI/CBaseUIScrollView.h

@@ -10,8 +10,6 @@ class CBaseUIScrollView : public CBaseUIElement {
 
     void clear();
 
-    ELEMENT_BODY(CBaseUIScrollView)
-
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
 
@@ -94,8 +92,8 @@ class CBaseUIScrollView : public CBaseUIElement {
 
     // get
     inline CBaseUIContainer *getContainer() const { return m_container; }
-    inline float getScrollPosY() const { return m_vScrollPos.y; }
-    inline float getScrollPosX() const { return m_vScrollPos.x; }
+    inline float getRelPosY() const { return m_vScrollPos.y; }
+    inline float getRelPosX() const { return m_vScrollPos.x; }
     inline Vector2 getScrollSize() const { return m_vScrollSize; }
     inline Vector2 getVelocity() const { return (m_vScrollPos - m_vVelocity); }
 

+ 0 - 2
src/GUI/CBaseUISlider.h

@@ -10,8 +10,6 @@ class CBaseUISlider : public CBaseUIElement {
     CBaseUISlider(float xPos = 0, float yPos = 0, float xSize = 0, float ySize = 0, UString name = "");
     virtual ~CBaseUISlider() { ; }
 
-    ELEMENT_BODY(CBaseUISlider)
-
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
 

+ 2 - 2
src/GUI/CBaseUITextField.cpp

@@ -32,8 +32,8 @@ void CBaseUITextField::onResized() {
     CBaseUIScrollView::onResized();
     m_textObject->setParentSize(m_vSize);
     // m_textObject->setSize(m_vSize);
-    scrollToX(getScrollPosX());
-    scrollToY(getScrollPosY());
+    scrollToX(getRelPosX());
+    scrollToY(getRelPosY());
     setScrollSizeToContent(0);
 }
 

+ 1 - 16
src/GUI/CBaseUITextField.h

@@ -1,15 +1,4 @@
-//================ Copyright (c) 2014, PG, All rights reserved. =================//
-//
-// Purpose:		a not so simple textfield
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef CBASEUITEXTFIELD_H
-#define CBASEUITEXTFIELD_H
-
-// TODO: finish this
-
+#pragma once
 #include "CBaseUIScrollView.h"
 
 class CBaseUITextField : public CBaseUIScrollView {
@@ -18,8 +7,6 @@ class CBaseUITextField : public CBaseUIScrollView {
                      UString text = "");
     virtual ~CBaseUITextField() { ; }
 
-    ELEMENT_BODY(CBaseUITextField)
-
     virtual void draw(Graphics *g);
 
     CBaseUITextField *setFont(McFont *font) {
@@ -79,5 +66,3 @@ class CBaseUITextField : public CBaseUIScrollView {
 
     TextObject *m_textObject;
 };
-
-#endif

+ 0 - 2
src/GUI/CBaseUITextbox.h

@@ -8,8 +8,6 @@ class CBaseUITextbox : public CBaseUIElement {
     CBaseUITextbox(float xPos = 0.0f, float yPos = 0.0f, float xSize = 0.0f, float ySize = 0.0f, UString name = "");
     virtual ~CBaseUITextbox() { ; }
 
-    ELEMENT_BODY(CBaseUITextbox)
-
     virtual void draw(Graphics *g);
     virtual void mouse_update(bool *propagate_clicks);
     virtual void onFocusStolen();

+ 2 - 2
src/GUI/CBaseUIWindow.cpp

@@ -491,10 +491,10 @@ void CBaseUIWindow::onMouseUpOutside() {
 }
 
 void CBaseUIWindow::updateTitleBarMetrics() {
-    m_closeButton->setScrollPos(
+    m_closeButton->setRelPos(
         m_vSize.x - m_closeButton->getSize().x - (m_iTitleBarHeight - m_closeButton->getSize().x) / 2.0f,
         m_iTitleBarHeight / 2.0f - m_closeButton->getSize().y / 2.0f);
-    m_minimizeButton->setScrollPos(
+    m_minimizeButton->setRelPos(
         m_vSize.x - m_minimizeButton->getSize().x * 2 - (m_iTitleBarHeight - m_minimizeButton->getSize().x) / 2.0f - 6,
         m_iTitleBarHeight / 2.0f - m_minimizeButton->getSize().y / 2.0f);
 

+ 1 - 14
src/GUI/CBaseUIWindow.h

@@ -1,13 +1,4 @@
-//================ Copyright (c) 2014, PG, All rights reserved. =================//
-//
-// Purpose:		base class for windows
-//
-// $NoKeywords: $
-//===============================================================================//
-
-#ifndef CBASEUIWINDOW_H
-#define CBASEUIWINDOW_H
-
+#pragma once
 #include "CBaseUIElement.h"
 
 class CBaseUIButton;
@@ -21,8 +12,6 @@ class CBaseUIWindow : public CBaseUIElement {
     CBaseUIWindow(float xPos = 0, float yPos = 0, float xSize = 0, float ySize = 0, UString name = "");
     ~CBaseUIWindow();
 
-    ELEMENT_BODY(CBaseUIWindow)
-
     virtual void draw(Graphics *g);
     virtual void drawCustomContent(Graphics *g) { (void)g; }
     virtual void mouse_update(bool *propagate_clicks);
@@ -180,5 +169,3 @@ class CBaseUIWindow : public CBaseUIElement {
     RenderTarget *m_rt;
     CBaseUIBoxShadow *m_shadow;
 };
-
-#endif

+ 3 - 3
src/GUI/Windows/Console.cpp

@@ -263,10 +263,10 @@ void Console::onResized() {
     /// m_newLog->setSize(m_vSize.x - 2*CONSOLE_BORDER, m_vSize.y - getTitleBarHeight() - 2*CONSOLE_BORDER -
     /// m_textbox->getSize().y - 1);
     m_textbox->setSize(m_vSize.x - 2 * CONSOLE_BORDER, m_textbox->getSize().y);
-    m_textbox->setScrollPosY(m_log->getRelPos().y + m_log->getSize().y + CONSOLE_BORDER + 1);
+    m_textbox->setRelPosY(m_log->getRelPos().y + m_log->getSize().y + CONSOLE_BORDER + 1);
 
-    m_log->scrollToY(m_log->getScrollPosY());
-    // m_newLog->scrollY(m_newLog->getScrollPosY());
+    m_log->scrollToY(m_log->getRelPosY());
+    // m_newLog->scrollY(m_newLog->getRelPosY());
 }
 
 //***********************//

+ 8 - 8
src/GUI/Windows/VinylScratcher/VSControlBar.cpp

@@ -259,16 +259,16 @@ void VSControlBar::onDisabled() {
 }
 
 void VSControlBar::onResized() {
-    m_play->setScrollPosX(m_vSize.x / 2 - m_play->getSize().x / 2);
-    m_prev->setScrollPosX(m_play->getRelPos().x - m_prev->getSize().x);
-    m_next->setScrollPosX(m_play->getRelPos().x + m_play->getSize().x);
-    m_info->setScrollPosX(m_next->getRelPos().x + m_next->getSize().x);
+    m_play->setRelPosX(m_vSize.x / 2 - m_play->getSize().x / 2);
+    m_prev->setRelPosX(m_play->getRelPos().x - m_prev->getSize().x);
+    m_next->setRelPosX(m_play->getRelPos().x + m_play->getSize().x);
+    m_info->setRelPosX(m_next->getRelPos().x + m_next->getSize().x);
     m_volume->setSizeX(m_prev->getRelPos().x);
 
-    m_shuffle->setScrollPosX(m_vSize.x - m_shuffle->getSize().x);
-    m_repeat->setScrollPosX(m_vSize.x - 2 * m_repeat->getSize().x);
-    m_eq->setScrollPos(m_vSize.x - 2 * m_eq->getSize().x, m_eq->getSize().y);
-    m_settings->setScrollPos(m_vSize.x - m_settings->getSize().x, m_settings->getSize().y);
+    m_shuffle->setRelPosX(m_vSize.x - m_shuffle->getSize().x);
+    m_repeat->setRelPosX(m_vSize.x - 2 * m_repeat->getSize().x);
+    m_eq->setRelPos(m_vSize.x - 2 * m_eq->getSize().x, m_eq->getSize().y);
+    m_settings->setRelPos(m_vSize.x - m_settings->getSize().x, m_settings->getSize().y);
 
     m_info->setSizeX(m_repeat->getRelPos().x - (m_next->getRelPos().x + m_next->getSize().x) + 1);  // +1 fudge
 

+ 2 - 9
src/GUI/Windows/VinylScratcher/VSMusicBrowser.cpp

@@ -1,10 +1,3 @@
-//================ Copyright (c) 2014, PG, All rights reserved. =================//
-//
-// Purpose:		a simple drive and file selector
-//
-// $NoKeywords: $
-//===============================================================================//
-
 #include "VSMusicBrowser.h"
 
 #include "AnimationHandler.h"
@@ -625,12 +618,12 @@ void VSMusicBrowser::onMoved() { m_mainContainer->setPos(m_vPos); }
 void VSMusicBrowser::onResized() {
     for(size_t i = 0; i < m_columns.size(); i++) {
         m_columns[i].view->setSizeY(m_vSize.y);
-        m_columns[i].view->scrollToY(m_columns[i].view->getScrollPosY());
+        m_columns[i].view->scrollToY(m_columns[i].view->getRelPosY());
     }
 
     m_mainContainer->setSize(m_vSize);
     m_mainContainer->setScrollSizeToContent(0);
-    m_mainContainer->scrollToX(m_mainContainer->getScrollPosX());
+    m_mainContainer->scrollToX(m_mainContainer->getRelPosX());
 }
 
 void VSMusicBrowser::onFocusStolen() {

+ 1 - 1
src/GUI/Windows/VinylScratcher/VinylScratcher.cpp

@@ -177,7 +177,7 @@ void VinylScratcher::onResized() {
 
     m_titleBar->setSizeX(m_vSize.x + 2);
     m_controlBar->setSizeX(m_vSize.x);
-    m_controlBar->setScrollPosY(m_vSize.y - getTitleBarHeight() - m_controlBar->getSize().y);
+    m_controlBar->setRelPosY(m_vSize.y - getTitleBarHeight() - m_controlBar->getSize().y);
     m_musicBrowser->setSize(m_vSize.x,
                             m_vSize.y - m_controlBar->getSize().y - m_titleBar->getSize().y - getTitleBarHeight());