diff --git a/changes.diff b/changes.diff deleted file mode 100644 index bf6467d..0000000 --- a/changes.diff +++ /dev/null @@ -1,498 +0,0 @@ -diff --git a/src/client/gui/components/GuiElementContainer.cpp b/src/client/gui/components/GuiElementContainer.cpp -index 9cfbb09..4fdaf22 100755 ---- a/src/client/gui/components/GuiElementContainer.cpp -+++ b/src/client/gui/components/GuiElementContainer.cpp -@@ -35,6 +35,17 @@ void GuiElementContainer::removeChild( GuiElement* element ) { - children.erase(it); - } - -+bool GuiElementContainer::containsPointInChildren(int x, int y) const { -+ for (std::vector::const_iterator it = children.begin(); it != children.end(); ++it) { -+ GuiElement* child = *it; -+ if (child == NULL || !child->visible) continue; -+ if (child->pointInside(x, y)) return true; -+ const GuiElementContainer* container = dynamic_cast(child); -+ if (container != NULL && container->containsPointInChildren(x, y)) return true; -+ } -+ return false; -+} -+ - void GuiElementContainer::tick( Minecraft* minecraft ) { - for(std::vector::iterator it = children.begin(); it != children.end(); ++it) { - (*it)->tick(minecraft); -diff --git a/src/client/gui/components/GuiElementContainer.h b/src/client/gui/components/GuiElementContainer.h -index d20f9d3..06df761 100755 ---- a/src/client/gui/components/GuiElementContainer.h -+++ b/src/client/gui/components/GuiElementContainer.h -@@ -5,16 +5,17 @@ - class Tesselator; - class Minecraft; - --class GuiElementContainer : public GuiElement { --public: -- GuiElementContainer(bool active=false, bool visible=true, int x = 0, int y = 0, int width=24, int height=24); -- virtual ~GuiElementContainer(); -- virtual void render(Minecraft* minecraft, int xm, int ym); -- virtual void setupPositions(); -- virtual void addChild(GuiElement* element); -- virtual void removeChild(GuiElement* element); -- -- virtual void tick( Minecraft* minecraft ); -+class GuiElementContainer : public GuiElement { -+public: -+ GuiElementContainer(bool active=false, bool visible=true, int x = 0, int y = 0, int width=24, int height=24); -+ virtual ~GuiElementContainer(); -+ virtual void render(Minecraft* minecraft, int xm, int ym); -+ virtual void setupPositions(); -+ virtual void addChild(GuiElement* element); -+ virtual void removeChild(GuiElement* element); -+ bool containsPointInChildren(int x, int y) const; -+ -+ virtual void tick( Minecraft* minecraft ); - - virtual void mouseClicked( Minecraft* minecraft, int x, int y, int buttonNum ); - virtual void mouseReleased( Minecraft* minecraft, int x, int y, int buttonNum ); -diff --git a/src/client/gui/components/OptionsGroup.cpp b/src/client/gui/components/OptionsGroup.cpp -index 54212d5..61695bb 100755 ---- a/src/client/gui/components/OptionsGroup.cpp -+++ b/src/client/gui/components/OptionsGroup.cpp -@@ -1,115 +1,230 @@ --#include "OptionsGroup.h" --#include "../../Minecraft.h" --#include "ImageButton.h" --#include "OptionsItem.h" --#include "Slider.h" --#include "../../../locale/I18n.h" --#include "TextOption.h" --#include "KeyOption.h" -- --OptionsGroup::OptionsGroup( std::string labelID ) { -- label = I18n::get(labelID); --} -- --void OptionsGroup::setupPositions() { -- // First we write the header and then we add the items -- int curY = y + 18; -- for(std::vector::iterator it = children.begin(); it != children.end(); ++it) { -- (*it)->width = width - 5; -- -- (*it)->y = curY; -- (*it)->x = x + 10; -- (*it)->setupPositions(); -- curY += (*it)->height + 3; -- } -- height = curY; --} -- --void OptionsGroup::render( Minecraft* minecraft, int xm, int ym ) { -- float padX = 10.0f; -- float padY = 5.0f; -- -- minecraft->font->draw(label, (float)x + padX, (float)y + padY, 0xffffffff, false); -- -- super::render(minecraft, xm, ym); --} -- --OptionsGroup& OptionsGroup::addOptionItem(OptionId optId, Minecraft* minecraft ) { -- auto option = minecraft->options.getOpt(optId); -- -- if (option == nullptr) return *this; -- -- // TODO: do a options key class to check it faster via dynamic_cast -- if (option->getStringId().find("options.key") != std::string::npos) createKey(optId, minecraft); -- else if (dynamic_cast(option)) createToggle(optId, minecraft); -- else if (dynamic_cast(option)) createProgressSlider(optId, minecraft); -- else if (dynamic_cast(option)) createStepSlider(optId, minecraft); -- else if (dynamic_cast(option)) createTextbox(optId, minecraft); -- -- return *this; --} -- --// TODO: wrap this copypaste shit into templates -- --void OptionsGroup::createToggle(OptionId optId, Minecraft* minecraft ) { -- ImageDef def; -- -- def.setSrc(IntRectangle(160, 206, 39, 20)); -- def.name = "gui/touchgui.png"; -- def.width = 39 * 0.7f; -- def.height = 20 * 0.7f; -- -- OptionButton* element = new OptionButton(optId); -- element->setImageDef(def, true); -- element->updateImage(&minecraft->options); -- -- std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -- -- OptionsItem* item = new OptionsItem(optId, itemLabel, element); -- -- addChild(item); -- setupPositions(); --} -- --void OptionsGroup::createProgressSlider(OptionId optId, Minecraft* minecraft ) { -- Slider* element = new SliderFloat(minecraft, optId); -- element->width = 100; -- element->height = 20; -- -- std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -- OptionsItem* item = new OptionsItem(optId, itemLabel, element); -- addChild(item); -- setupPositions(); --} -- --void OptionsGroup::createStepSlider(OptionId optId, Minecraft* minecraft ) { -- Slider* element = new SliderInt(minecraft, optId); -- element->width = 100; -- element->height = 20; -- std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -- OptionsItem* item = new OptionsItem(optId, itemLabel, element); -- addChild(item); -- setupPositions(); --} -- --void OptionsGroup::createTextbox(OptionId optId, Minecraft* minecraft) { -- TextBox* element = new TextOption(minecraft, optId); -- element->width = 100; -- element->height = 20; -- -- std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -- OptionsItem* item = new OptionsItem(optId, itemLabel, element); -- addChild(item); -- setupPositions(); --} -- --void OptionsGroup::createKey(OptionId optId, Minecraft* minecraft) { -- KeyOption* element = new KeyOption(minecraft, optId); -- element->width = 50; -- element->height = 20; -- -- std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -- OptionsItem* item = new OptionsItem(optId, itemLabel, element); -- addChild(item); -- setupPositions(); --} -\ No newline at end of file -+#include "OptionsGroup.h" -+#include "../../Minecraft.h" -+#include "ImageButton.h" -+#include "OptionsItem.h" -+#include "Slider.h" -+#include "../../../locale/I18n.h" -+#include "TextOption.h" -+#include "KeyOption.h" -+#include -+#include "../Gui.h" -+#include "../Screen.h" -+#include "../../../platform/input/Mouse.h" -+#include "../../../util/Mth.h" -+ -+OptionsGroup::OptionsGroup( std::string labelID ) -+: contentHeight(0), -+ scrollOffsetY(0.0f), -+ maxScrollOffsetY(0.0f), -+ trackingScrollGesture(false), -+ scrollingGesture(false), -+ touchDispatched(false), -+ dragStartX(0), -+ dragStartY(0), -+ lastDragY(0), -+ touchStartX(0), -+ touchStartY(0) { -+ label = I18n::get(labelID); -+} -+ -+void OptionsGroup::setupPositions() { -+ const int labelHeight = 18; -+ const int bottomPadding = 36; -+ const float requestedScroll = scrollOffsetY; -+ const int scrollOffset = (int)requestedScroll; -+ int curY = y + labelHeight - scrollOffset; -+ const int contentStartY = y + labelHeight; -+ -+ // First we write the header and then we add the items -+ for(std::vector::iterator it = children.begin(); it != children.end(); ++it) { -+ (*it)->width = width - 5; -+ -+ (*it)->y = curY; -+ (*it)->x = x + 10; -+ (*it)->setupPositions(); -+ curY += (*it)->height + 3; -+ } -+ curY += bottomPadding; -+ contentHeight = std::max(0, curY - contentStartY + scrollOffset); -+ maxScrollOffsetY = std::max(0, contentHeight - (height - labelHeight)); -+ const float clampedScroll = Mth::clamp(requestedScroll, 0.0f, maxScrollOffsetY); -+ if (clampedScroll != requestedScroll) { -+ scrollOffsetY = clampedScroll; -+ setupPositions(); -+ } -+} -+ -+void OptionsGroup::render( Minecraft* minecraft, int xm, int ym ) { -+ float padX = 10.0f; -+ float padY = 5.0f; -+ const int labelHeight = 18; -+ -+ minecraft->font->draw(label, (float)x + padX, (float)y + padY, 0xffffffff, false); -+ -+ glEnable2(GL_SCISSOR_TEST); -+ glScissor( -+ Gui::GuiScale * x, -+ minecraft->height - Gui::GuiScale * (y + height), -+ Gui::GuiScale * width, -+ Gui::GuiScale * (height - labelHeight) -+ ); -+ -+ super::render(minecraft, xm, ym); -+ glDisable2(GL_SCISSOR_TEST); -+} -+ -+void OptionsGroup::tick(Minecraft* minecraft) { -+ int xm = Mouse::getX(); -+ int ym = Mouse::getY(); -+ if (minecraft->screen != NULL) { -+ minecraft->screen->toGUICoordinate(xm, ym); -+ } -+ -+ bool leftDown = Mouse::isButtonDown(MouseAction::ACTION_LEFT); -+ -+ if (trackingScrollGesture && leftDown) { -+ int dy = ym - lastDragY; -+ int dx = xm - dragStartX; -+ if (!scrollingGesture) { -+ int totalDx = xm - dragStartX; -+ int totalDy = ym - dragStartY; -+ if (std::abs(totalDx) >= ScrollStartThreshold || std::abs(totalDy) >= ScrollStartThreshold) { -+ if (std::abs(totalDy) >= std::abs(totalDx)) { -+ scrollingGesture = true; -+ } else if (!touchDispatched) { -+ super::mouseClicked(minecraft, touchStartX, touchStartY, MouseAction::ACTION_LEFT); -+ touchDispatched = true; -+ } -+ } -+ } -+ if (scrollingGesture && dy != 0) { -+ scrollByPixels((float)dy); -+ } -+ lastDragY = ym; -+ } -+ super::tick(minecraft); -+} -+ -+void OptionsGroup::mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum) { -+ trackingScrollGesture = false; -+ scrollingGesture = false; -+ touchDispatched = false; -+ -+ if (buttonNum == MouseAction::ACTION_LEFT && pointInside(x, y)) { -+ trackingScrollGesture = true; -+ dragStartX = x; -+ dragStartY = y; -+ lastDragY = y; -+ touchStartX = x; -+ touchStartY = y; -+ return; -+ } -+ -+ super::mouseClicked(minecraft, x, y, buttonNum); -+} -+ -+void OptionsGroup::mouseReleased(Minecraft* minecraft, int x, int y, int buttonNum) { -+ bool wasScrolling = scrollingGesture; -+ bool wasTracking = trackingScrollGesture; -+ trackingScrollGesture = false; -+ scrollingGesture = false; -+ if (buttonNum == MouseAction::ACTION_LEFT && wasTracking && !touchDispatched && pointInside(touchStartX, touchStartY)) { -+ super::mouseClicked(minecraft, touchStartX, touchStartY, buttonNum); -+ touchDispatched = true; -+ } -+ -+ if (!wasScrolling) { -+ super::mouseReleased(minecraft, x, y, buttonNum); -+ } -+} -+ -+void OptionsGroup::scrollByPixels(float deltaY) { -+ if (deltaY == 0.0f || maxScrollOffsetY <= 0.0f) return; -+ -+ scrollOffsetY = Mth::clamp(scrollOffsetY - deltaY, 0.0f, maxScrollOffsetY); -+ setupPositions(); -+} -+ -+bool OptionsGroup::isScrollingGestureActive() const { -+ return trackingScrollGesture || scrollingGesture; -+} -+ -+OptionsGroup& OptionsGroup::addOptionItem(OptionId optId, Minecraft* minecraft ) { -+ auto option = minecraft->options.getOpt(optId); -+ -+ if (option == nullptr) return *this; -+ -+ // TODO: do a options key class to check it faster via dynamic_cast -+ if (option->getStringId().find("options.key") != std::string::npos) createKey(optId, minecraft); -+ else if (dynamic_cast(option)) createToggle(optId, minecraft); -+ else if (dynamic_cast(option)) createProgressSlider(optId, minecraft); -+ else if (dynamic_cast(option)) createStepSlider(optId, minecraft); -+ else if (dynamic_cast(option)) createTextbox(optId, minecraft); -+ -+ return *this; -+} -+ -+// TODO: wrap this copypaste shit into templates -+ -+void OptionsGroup::createToggle(OptionId optId, Minecraft* minecraft ) { -+ ImageDef def; -+ -+ def.setSrc(IntRectangle(160, 206, 39, 20)); -+ def.name = "gui/touchgui.png"; -+ def.width = 39 * 0.7f; -+ def.height = 20 * 0.7f; -+ -+ OptionButton* element = new OptionButton(optId); -+ element->setImageDef(def, true); -+ element->updateImage(&minecraft->options); -+ -+ std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -+ -+ OptionsItem* item = new OptionsItem(optId, itemLabel, element); -+ -+ addChild(item); -+ setupPositions(); -+} -+ -+void OptionsGroup::createProgressSlider(OptionId optId, Minecraft* minecraft ) { -+ Slider* element = new SliderFloat(minecraft, optId); -+ element->width = 100; -+ element->height = 20; -+ -+ std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -+ OptionsItem* item = new OptionsItem(optId, itemLabel, element); -+ addChild(item); -+ setupPositions(); -+} -+ -+void OptionsGroup::createStepSlider(OptionId optId, Minecraft* minecraft ) { -+ Slider* element = new SliderInt(minecraft, optId); -+ element->width = 100; -+ element->height = 20; -+ std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -+ OptionsItem* item = new OptionsItem(optId, itemLabel, element); -+ addChild(item); -+ setupPositions(); -+} -+ -+void OptionsGroup::createTextbox(OptionId optId, Minecraft* minecraft) { -+ TextBox* element = new TextOption(minecraft, optId); -+ element->width = 100; -+ element->height = 20; -+ -+ std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -+ OptionsItem* item = new OptionsItem(optId, itemLabel, element); -+ addChild(item); -+ setupPositions(); -+} -+ -+void OptionsGroup::createKey(OptionId optId, Minecraft* minecraft) { -+ KeyOption* element = new KeyOption(minecraft, optId); -+ element->width = 50; -+ element->height = 20; -+ -+ std::string itemLabel = I18n::get(minecraft->options.getOpt(optId)->getStringId()); -+ OptionsItem* item = new OptionsItem(optId, itemLabel, element); -+ addChild(item); -+ setupPositions(); -+} -diff --git a/src/client/gui/components/OptionsGroup.h b/src/client/gui/components/OptionsGroup.h -index 24d28bd..ac90e3d 100755 ---- a/src/client/gui/components/OptionsGroup.h -+++ b/src/client/gui/components/OptionsGroup.h -@@ -11,22 +11,39 @@ - class Font; - class Minecraft; - --class OptionsGroup: public GuiElementContainer { -- typedef GuiElementContainer super; --public: -- OptionsGroup(std::string labelID); -- virtual void setupPositions(); -- virtual void render(Minecraft* minecraft, int xm, int ym); -- OptionsGroup& addOptionItem(OptionId optId, Minecraft* minecraft); --protected: -+class OptionsGroup: public GuiElementContainer { -+ typedef GuiElementContainer super; -+public: -+ OptionsGroup(std::string labelID); -+ virtual void setupPositions(); -+ virtual void render(Minecraft* minecraft, int xm, int ym); -+ virtual void tick(Minecraft* minecraft); -+ virtual void mouseClicked(Minecraft* minecraft, int x, int y, int buttonNum); -+ virtual void mouseReleased(Minecraft* minecraft, int x, int y, int buttonNum); -+ OptionsGroup& addOptionItem(OptionId optId, Minecraft* minecraft); -+ void scrollByPixels(float deltaY); -+ bool isScrollingGestureActive() const; -+protected: - - void createToggle(OptionId optId, Minecraft* minecraft); - void createProgressSlider(OptionId optId, Minecraft* minecraft); - void createStepSlider(OptionId optId, Minecraft* minecraft); - void createTextbox(OptionId optId, Minecraft* minecraft); -- void createKey(OptionId optId, Minecraft* minecraft); -- -- std::string label; --}; -+ void createKey(OptionId optId, Minecraft* minecraft); -+ -+ std::string label; -+ int contentHeight; -+ float scrollOffsetY; -+ float maxScrollOffsetY; -+ bool trackingScrollGesture; -+ bool scrollingGesture; -+ bool touchDispatched; -+ int dragStartX; -+ int dragStartY; -+ int lastDragY; -+ int touchStartX; -+ int touchStartY; -+ static const int ScrollStartThreshold = 5; -+}; - - #endif /*NET_MINECRAFT_CLIENT_GUI_COMPONENTS__OptionsGroup_H__*/ -diff --git a/src/client/gui/screens/OptionsScreen.cpp b/src/client/gui/screens/OptionsScreen.cpp -index 88fbb63..b58f3fe 100755 ---- a/src/client/gui/screens/OptionsScreen.cpp -+++ b/src/client/gui/screens/OptionsScreen.cpp -@@ -121,6 +121,7 @@ void OptionsScreen::setupPositions() { - (*it)->x = categoryButtons[0]->width; - (*it)->y = bHeader->height; - (*it)->width = width - categoryButtons[0]->width; -+ (*it)->height = height - bHeader->height; - - (*it)->setupPositions(); - } -@@ -253,6 +254,12 @@ void OptionsScreen::mouseReleased(int x, int y, int buttonNum) { - super::mouseReleased(x, y, buttonNum); - } - -+void OptionsScreen::mouseWheel(int dx, int dy, int xm, int ym) { -+ if (currentOptionsGroup != NULL && currentOptionsGroup->pointInside(xm, ym) && dy != 0) { -+ currentOptionsGroup->scrollByPixels((float)dy * 18.0f); -+ } -+} -+ - void OptionsScreen::keyPressed(int eventKey) { - if (currentOptionsGroup != NULL) - currentOptionsGroup->keyPressed(minecraft, eventKey); -diff --git a/src/client/gui/screens/OptionsScreen.h b/src/client/gui/screens/OptionsScreen.h -index b02c7b8..dd1e73e 100755 ---- a/src/client/gui/screens/OptionsScreen.h -+++ b/src/client/gui/screens/OptionsScreen.h -@@ -27,6 +27,7 @@ public: - - virtual void mouseClicked(int x, int y, int buttonNum); - virtual void mouseReleased(int x, int y, int buttonNum); -+ virtual void mouseWheel(int dx, int dy, int xm, int ym); - virtual void keyPressed(int eventKey); - virtual void charPressed(char inputChar); -