]> git.lizzy.rs Git - dragonfireclient.git/blobdiff - src/guiTable.cpp
Add function to get server info.
[dragonfireclient.git] / src / guiTable.cpp
index e2da4eadaab58ba494f98ef2eb54592913f7db6d..d223e3069b0409f387af40a0e202e65b3669f6f7 100644 (file)
@@ -28,11 +28,14 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include <IGUIScrollBar.h>
 #include "debug.h"
 #include "log.h"
-#include "tile.h"
+#include "client/tile.h"
 #include "gettime.h"
 #include "util/string.h"
 #include "util/numeric.h"
-#include "guiFormSpecMenu.h" // for parseColor()
+#include "util/string.h" // for parseColorString()
+#include "settings.h" // for settings
+#include "porting.h" // for dpi
+#include "guiscalingfilter.h"
 
 /*
        GUITable
@@ -89,6 +92,14 @@ GUITable::GUITable(gui::IGUIEnvironment *env,
        setTabStop(true);
        setTabOrder(-1);
        updateAbsolutePosition();
+
+       core::rect<s32> relative_rect = m_scrollbar->getRelativePosition();
+       s32 width = (relative_rect.getWidth()/(2.0/3.0)) * porting::getDisplayDensity() *
+                       g_settings->getFloat("gui_scaling");
+       m_scrollbar->setRelativePosition(core::rect<s32>(
+                       relative_rect.LowerRightCorner.X-width,relative_rect.UpperLeftCorner.Y,
+                       relative_rect.LowerRightCorner.X,relative_rect.LowerRightCorner.Y
+                       ));
 }
 
 GUITable::~GUITable()
@@ -153,7 +164,7 @@ void GUITable::setTextList(const std::vector<std::string> &content,
                        cell->content_index = allocString(s.substr(2));
                }
                else if (s[0] == '#' && s.size() >= 7 &&
-                               GUIFormSpecMenu::parseColor(
+                               parseColorString(
                                        s.substr(0,7), cell->color, false)) {
                        // single # for color
                        cell->color_defined = true;
@@ -200,15 +211,15 @@ void GUITable::setTable(const TableOptions &options,
                const std::string &name = options[k].name;
                const std::string &value = options[k].value;
                if (name == "color")
-                       GUIFormSpecMenu::parseColor(value, m_color, false);
+                       parseColorString(value, m_color, false);
                else if (name == "background")
-                       GUIFormSpecMenu::parseColor(value, m_background, false);
+                       parseColorString(value, m_background, false);
                else if (name == "border")
                        m_border = is_yes(value);
                else if (name == "highlight")
-                       GUIFormSpecMenu::parseColor(value, m_highlight, false);
+                       parseColorString(value, m_highlight, false);
                else if (name == "highlight_text")
-                       GUIFormSpecMenu::parseColor(value, m_highlight_text, false);
+                       parseColorString(value, m_highlight_text, false);
                else if (name == "opendepth")
                        opendepth = stoi(value);
                else
@@ -405,7 +416,7 @@ void GUITable::setTable(const TableOptions &options,
                else if (columntype == COLUMN_TYPE_COLOR) {
                        for (s32 i = 0; i < rowcount; ++i) {
                                video::SColor cellcolor(255, 255, 255, 255);
-                               if (GUIFormSpecMenu::parseColor(content[i * colcount + j], cellcolor, true))
+                               if (parseColorString(content[i * colcount + j], cellcolor, true))
                                        rows[i].colors.push_back(std::make_pair(cellcolor, j+span));
                        }
                }
@@ -545,24 +556,44 @@ s32 GUITable::getSelected() const
 
 void GUITable::setSelected(s32 index)
 {
+       s32 old_selected = m_selected;
+
        m_selected = -1;
        m_sel_column = 0;
        m_sel_doubleclick = false;
 
-       --index;
+       --index; // Switch from 1-based indexing to 0-based indexing
 
        s32 rowcount = m_rows.size();
-
-       if (index >= rowcount)
+       if (rowcount == 0 || index < 0) {
+               return;
+       } else if (index >= rowcount) {
                index = rowcount - 1;
-       while (index >= 0 && m_rows[index].visible_index < 0)
-               --index;
+       }
+
+       // If the selected row is not visible, open its ancestors to make it visible
+       bool selection_invisible = m_rows[index].visible_index < 0;
+       if (selection_invisible) {
+               std::set<s32> opened_trees;
+               getOpenedTrees(opened_trees);
+               s32 indent = m_rows[index].indent;
+               for (s32 j = index - 1; j >= 0; --j) {
+                       if (m_rows[j].indent < indent) {
+                               opened_trees.insert(j);
+                               indent = m_rows[j].indent;
+                       }
+               }
+               setOpenedTrees(opened_trees);
+       }
+
        if (index >= 0) {
                m_selected = m_rows[index].visible_index;
                assert(m_selected >= 0 && m_selected < (s32) m_visible_rows.size());
        }
 
-       autoScroll();
+       if (m_selected != old_selected || selection_invisible) {
+               autoScroll();
+       }
 }
 
 GUITable::DynamicData GUITable::getDynamicData() const
@@ -585,11 +616,11 @@ void GUITable::setDynamicData(const DynamicData &dyndata)
        m_keynav_time = dyndata.keynav_time;
        m_keynav_buffer = dyndata.keynav_buffer;
 
-       m_scrollbar->setPos(dyndata.scrollpos);
-
        setSelected(dyndata.selected);
        m_sel_column = 0;
        m_sel_doubleclick = false;
+
+       m_scrollbar->setPos(dyndata.scrollpos);
 }
 
 const c8* GUITable::getTypeName() const
@@ -627,10 +658,11 @@ void GUITable::draw()
        client_clip.UpperLeftCorner.Y += 1;
        client_clip.UpperLeftCorner.X += 1;
        client_clip.LowerRightCorner.Y -= 1;
-       client_clip.LowerRightCorner.X -=
-               m_scrollbar->isVisible() ?
-               skin->getSize(gui::EGDS_SCROLLBAR_SIZE) :
-               1;
+       client_clip.LowerRightCorner.X -= 1;
+       if (m_scrollbar->isVisible()) {
+               client_clip.LowerRightCorner.X =
+                               m_scrollbar->getAbsolutePosition().UpperLeftCorner.X;
+       }
        client_clip.clipAgainst(AbsoluteClippingRect);
 
        // draw visible rows
@@ -796,7 +828,7 @@ bool GUITable::OnEvent(const SEvent &event)
                }
                else if (event.KeyInput.PressedDown && event.KeyInput.Char) {
                        // change selection based on text as it is typed
-                       s32 now = getTimeMs();
+                       u64 now = porting::getTimeMs();
                        if (now - m_keynav_time >= 500)
                                m_keynav_buffer = L"";
                        m_keynav_time = now;
@@ -833,7 +865,7 @@ bool GUITable::OnEvent(const SEvent &event)
 
                if (event.MouseInput.Event == EMIE_MOUSE_WHEEL) {
                        m_scrollbar->setPos(m_scrollbar->getPos() +
-                                       (event.MouseInput.Wheel < 0 ? -1 : 1) *
+                                       (event.MouseInput.Wheel < 0 ? -3 : 3) *
                                        - (s32) m_rowheight / 2);
                        return true;
                }
@@ -851,6 +883,14 @@ bool GUITable::OnEvent(const SEvent &event)
                // Update tooltip
                setToolTipText(cell ? m_strings[cell->tooltip_index].c_str() : L"");
 
+               // Fix for #1567/#1806:
+               // IGUIScrollBar passes double click events to its parent,
+               // which we don't want. Detect this case and discard the event
+               if (event.MouseInput.Event != EMIE_MOUSE_MOVED &&
+                               m_scrollbar->isVisible() &&
+                               m_scrollbar->isPointInside(p))
+                       return true;
+
                if (event.MouseInput.isLeftPressed() &&
                                (isPointInside(p) ||
                                 event.MouseInput.Event == EMIE_MOUSE_MOVED)) {
@@ -886,6 +926,11 @@ bool GUITable::OnEvent(const SEvent &event)
                                                sel_doubleclick) {
                                        sendTableEvent(sel_column, sel_doubleclick);
                                }
+
+                               // Treeview: double click opens/closes trees
+                               if (m_has_tree_column && sel_doubleclick) {
+                                       toggleVisibleTree(m_selected, 0, false);
+                               }
                        }
                }
                return true;
@@ -909,7 +954,7 @@ s32 GUITable::allocString(const std::string &text)
        std::map<std::string, s32>::iterator it = m_alloc_strings.find(text);
        if (it == m_alloc_strings.end()) {
                s32 id = m_strings.size();
-               std::wstring wtext = narrow_to_wide(text);
+               std::wstring wtext = utf8_to_wide(text);
                m_strings.push_back(core::stringw(wtext.c_str()));
                m_alloc_strings.insert(std::make_pair(text, id));
                return id;
@@ -1071,7 +1116,9 @@ void GUITable::getOpenedTrees(std::set<s32> &opened_trees) const
 
 void GUITable::setOpenedTrees(const std::set<s32> &opened_trees)
 {
-       s32 old_selected = getSelected();
+       s32 old_selected = -1;
+       if (m_selected >= 0)
+               old_selected = m_visible_rows[m_selected];
 
        std::vector<s32> parents;
        std::vector<s32> closed_parents;
@@ -1123,7 +1170,9 @@ void GUITable::setOpenedTrees(const std::set<s32> &opened_trees)
 
        updateScrollBar();
 
-       setSelected(old_selected);
+       // m_selected must be updated since it is a visible row index
+       if (old_selected >= 0)
+               m_selected = m_rows[old_selected].visible_index;
 }
 
 void GUITable::openTree(s32 to_open)