Ticket #3415: t3415_fix_lists_invisible_scrollbar_v1.patch
File t3415_fix_lists_invisible_scrollbar_v1.patch, 13.6 KB (added by , 9 years ago) |
---|
-
source/gui/CDropDown.cpp
68 68 void CDropDown::HandleMessage(SGUIMessage& Message) 69 69 { 70 70 // Important 71 71 72 72 switch (Message.type) 73 73 { 74 74 case GUIM_SETTINGS_UPDATED: 75 75 { 76 76 // Update cached list rect 77 77 if (Message.value == "size" || 78 78 Message.value == "absolute" || 79 79 Message.value == "dropdown_size" || 80 80 Message.value == "dropdown_buffer" || 81 81 Message.value == "scrollbar_style" || 82 82 Message.value == "button_width") 83 83 { 84 84 SetupListRect(); 85 85 } 86 86 87 87 break; 88 88 } 89 89 90 90 case GUIM_MOUSE_MOTION: 91 91 { 92 92 if (!m_Open) 93 93 break; 94 94 95 95 CPos mouse = GetMousePos(); 96 96 97 97 if (!GetListRect().PointInside(mouse)) 98 98 break; 99 99 100 100 bool scrollbar; 101 101 CGUIList* pList; 102 102 GUI<bool>::GetSetting(this, "scrollbar", scrollbar); 103 103 GUI<CGUIList>::GetSettingPointer(this, "list", pList); 104 104 float scroll = 0.f; 105 105 if (scrollbar) 106 106 scroll = GetScrollBar(0).GetPos(); 107 107 108 108 CRect rect = GetListRect(); 109 109 mouse.y += scroll; 110 110 int set = -1; 111 111 for (int i = 0; i < (int)pList->m_Items.size(); ++i) 112 112 { 113 113 if (mouse.y >= rect.top + m_ItemsYPositions[i] && 114 114 mouse.y < rect.top + m_ItemsYPositions[i+1] && 115 115 // mouse is not over scroll-bar 116 !(mouse.x >= GetScrollBar(0).GetOuterRect().left && 117 mouse.x <= GetScrollBar(0).GetOuterRect().right)) 116 (m_HideScrollBar || 117 mouse.x < GetScrollBar(0).GetOuterRect().left || 118 mouse.x > GetScrollBar(0).GetOuterRect().right)) 118 119 { 119 120 set = i; 120 121 } 121 122 } 122 123 123 124 if (set != -1) 124 125 { 125 126 m_ElementHighlight = set; 126 127 //UpdateAutoScroll(); 127 128 } 128 129 129 130 break; 130 131 } 131 132 132 133 case GUIM_MOUSE_ENTER: 133 134 { 134 135 bool enabled; 135 136 GUI<bool>::GetSetting(this, "enabled", enabled); 136 137 if (!enabled) 137 138 break; 138 139 139 140 CStrW soundPath; 140 141 if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_enter", soundPath) == PSRETURN_OK && !soundPath.empty()) 141 142 g_SoundManager->PlayAsUI(soundPath.c_str(), false); 142 143 break; 143 144 } 144 145 145 146 case GUIM_MOUSE_LEAVE: 146 147 { 147 148 GUI<int>::GetSetting(this, "selected", m_ElementHighlight); 148 149 149 150 bool enabled; 150 151 GUI<bool>::GetSetting(this, "enabled", enabled); 151 152 if (!enabled) 152 153 break; 153 154 154 155 CStrW soundPath; 155 156 if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_leave", soundPath) == PSRETURN_OK && !soundPath.empty()) 156 157 g_SoundManager->PlayAsUI(soundPath.c_str(), false); 157 158 break; 158 159 } 159 160 160 161 // We can't inherent this routine from CList, because we need to include 161 162 // a mouse click to open the dropdown, also the coordinates are changed. 162 163 case GUIM_MOUSE_PRESS_LEFT: 163 164 { 164 165 bool enabled; 165 166 GUI<bool>::GetSetting(this, "enabled", enabled); 166 167 if (!enabled) 167 168 { 168 169 CStrW soundPath; 169 170 if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_disabled", soundPath) == PSRETURN_OK && !soundPath.empty()) 170 171 g_SoundManager->PlayAsUI(soundPath.c_str(), false); 171 172 break; 172 173 } 173 174 174 175 if (!m_Open) 175 176 { 176 177 CGUIList* pList; 177 178 GUI<CGUIList>::GetSettingPointer(this, "list", pList); 178 179 if (pList->m_Items.empty()) 179 180 return; 180 181 181 182 m_Open = true; 182 183 GetScrollBar(0).SetZ(GetBufferedZ()); 183 184 GUI<int>::GetSetting(this, "selected", m_ElementHighlight); 184 185 185 186 // Start at the position of the selected item, if possible. 186 187 GetScrollBar(0).SetPos(m_ItemsYPositions.empty() ? 0 : m_ItemsYPositions[m_ElementHighlight] - 60); 187 188 188 189 CStrW soundPath; 189 190 if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_opened", soundPath) == PSRETURN_OK && !soundPath.empty()) 190 191 g_SoundManager->PlayAsUI(soundPath.c_str(), false); 191 192 192 193 return; // overshadow 193 194 } 194 195 else 195 196 { 196 197 CPos mouse = GetMousePos(); 197 198 198 199 // If the regular area is pressed, then abort, and close. 199 200 if (m_CachedActualSize.PointInside(mouse)) 200 201 { 201 202 m_Open = false; 202 203 GetScrollBar(0).SetZ(GetBufferedZ()); 203 204 204 205 CStrW soundPath; 205 206 if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_closed", soundPath) == PSRETURN_OK && !soundPath.empty()) 206 207 g_SoundManager->PlayAsUI(soundPath.c_str(), false); 207 208 208 209 return; // overshadow 209 210 } 210 211 211 if (!(mouse.x >= GetScrollBar(0).GetOuterRect().left && 212 mouse.x <= GetScrollBar(0).GetOuterRect().right) && 213 mouse.y >= GetListRect().top) 212 if (m_HideScrollBar || 213 mouse.x < GetScrollBar(0).GetOuterRect().left || 214 mouse.x > GetScrollBar(0).GetOuterRect().right || 215 mouse.y < GetListRect().top) 214 216 { 215 217 m_Open = false; 216 218 GetScrollBar(0).SetZ(GetBufferedZ()); 217 219 } 218 220 } 219 221 break; 220 222 } 221 223 222 224 case GUIM_MOUSE_WHEEL_DOWN: 223 225 { 224 226 bool enabled; 225 227 GUI<bool>::GetSetting(this, "enabled", enabled); 226 228 227 229 // Don't switch elements by scrolling when open, causes a confusing interaction between this and the scrollbar. 228 230 if (m_Open || !enabled) 229 231 break; 230 232 231 233 GUI<int>::GetSetting(this, "selected", m_ElementHighlight); 232 234 if (m_ElementHighlight + 1 >= (int)m_ItemsYPositions.size() - 1) 233 235 break; 234 236 235 237 ++m_ElementHighlight; 236 238 GUI<int>::SetSetting(this, "selected", m_ElementHighlight); 237 239 break; 238 240 } 239 241 240 242 case GUIM_MOUSE_WHEEL_UP: 241 243 { 242 244 bool enabled; 243 245 GUI<bool>::GetSetting(this, "enabled", enabled); 244 246 245 247 // Don't switch elements by scrolling when open, causes a confusing interaction between this and the scrollbar. 246 248 if (m_Open || !enabled) 247 249 break; 248 250 249 251 GUI<int>::GetSetting(this, "selected", m_ElementHighlight); 250 252 if (m_ElementHighlight - 1 < 0) 251 253 break; 252 254 253 255 m_ElementHighlight--; 254 256 GUI<int>::SetSetting(this, "selected", m_ElementHighlight); 255 257 break; 256 258 } 257 259 258 260 case GUIM_LOST_FOCUS: 259 261 { 260 262 if (m_Open) 261 263 { -
source/gui/CGUIScrollBarVertical.cpp
9 9 * 0 A.D. is distributed in the hope that it will be useful, 10 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 12 * GNU General Public License for more details. 13 13 * 14 14 * You should have received a copy of the GNU General Public License 15 15 * along with 0 A.D. If not, see <http://www.gnu.org/licenses/>. 16 16 */ 17 17 18 18 #include "precompiled.h" 19 19 20 20 #include "CGUIScrollBarVertical.h" 21 21 22 22 #include "GUI.h" 23 23 24 24 #include "ps/CLogger.h" 25 25 26 26 27 27 CGUIScrollBarVertical::CGUIScrollBarVertical() 28 28 { 29 29 } 30 30 31 31 CGUIScrollBarVertical::~CGUIScrollBarVertical() 32 32 { 33 33 } 34 34 35 35 void CGUIScrollBarVertical::SetPosFromMousePos(const CPos& mouse) 36 36 { 37 37 if (!GetStyle()) 38 38 return; 39 39 40 40 /** 41 41 * Calculate the position for the top of the item being scrolled 42 42 */ 43 43 float emptyBackground = m_Length - m_BarSize; 44 44 if (GetStyle()->m_UseEdgeButtons) 45 45 emptyBackground -= GetStyle()->m_Width * 2; 46 46 m_Pos = m_PosWhenPressed + GetMaxPos() * (mouse.y - m_BarPressedAtPos.y) / emptyBackground; 47 47 } 48 48 49 49 void CGUIScrollBarVertical::Draw() 50 50 { 51 51 if (!GetStyle()) 52 52 { 53 53 LOGWARNING("Attempt to draw scrollbar without a style."); 54 54 return; 55 55 } 56 56 57 if (GetGUI() && GetMaxPos() != 1)57 if (GetGUI() && IsVisible()) 58 58 { 59 59 CRect outline = GetOuterRect(); 60 60 61 61 // Draw background 62 62 GetGUI()->DrawSprite(GetStyle()->m_SpriteBackVertical, 63 63 0, 64 64 m_Z+0.1f, 65 65 CRect(outline.left, 66 66 outline.top+(GetStyle()->m_UseEdgeButtons?GetStyle()->m_Width:0), 67 67 outline.right, 68 68 outline.bottom-(GetStyle()->m_UseEdgeButtons?GetStyle()->m_Width:0)) 69 69 ); 70 70 71 71 if (GetStyle()->m_UseEdgeButtons) 72 72 { 73 73 // Get Appropriate sprites 74 74 const CGUISpriteInstance* button_top; 75 75 const CGUISpriteInstance* button_bottom; 76 76 77 77 // figure out what sprite to use for top button 78 78 if (m_ButtonMinusHovered) 79 79 { 80 80 if (m_ButtonMinusPressed) 81 81 button_top = &GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonTopPressed, GetStyle()->m_SpriteButtonTop); 82 82 else 83 83 button_top = &GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonTopOver, GetStyle()->m_SpriteButtonTop); 84 84 } 85 85 else 86 86 button_top = &GetStyle()->m_SpriteButtonTop; 87 87 88 88 // figure out what sprite to use for bottom button 89 89 if (m_ButtonPlusHovered) 90 90 { 91 91 if (m_ButtonPlusPressed) 92 92 button_bottom = &GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonBottomPressed, GetStyle()->m_SpriteButtonBottom); 93 93 else 94 94 button_bottom = &GUI<>::FallBackSprite(GetStyle()->m_SpriteButtonBottomOver, GetStyle()->m_SpriteButtonBottom); 95 95 } 96 96 else 97 97 button_bottom = &GetStyle()->m_SpriteButtonBottom; 98 98 99 99 // Draw top button 100 100 GetGUI()->DrawSprite(*button_top, 101 101 0, 102 102 m_Z+0.2f, 103 103 CRect(outline.left, 104 104 outline.top, 105 105 outline.right, -
source/gui/CList.cpp
155 155 ScriptEvent("selectionchange"); 156 156 } 157 157 158 158 if (Message.value == "scrollbar") 159 159 SetupText(); 160 160 161 161 // Update scrollbar 162 162 if (Message.value == "scrollbar_style") 163 163 { 164 164 CStr scrollbar_style; 165 165 GUI<CStr>::GetSetting(this, Message.value, scrollbar_style); 166 166 167 167 GetScrollBar(0).SetScrollBarStyle(scrollbar_style); 168 168 169 169 SetupText(); 170 170 } 171 171 172 172 break; 173 173 174 174 case GUIM_MOUSE_PRESS_LEFT: 175 175 { 176 176 bool enabled; 177 177 GUI<bool>::GetSetting(this, "enabled", enabled); 178 178 if (!enabled) 179 179 { 180 180 CStrW soundPath; 181 181 if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_disabled", soundPath) == PSRETURN_OK && !soundPath.empty()) 182 182 g_SoundManager->PlayAsUI(soundPath.c_str(), false); 183 183 break; 184 184 } 185 185 186 186 bool scrollbar; 187 187 CGUIList* pList; 188 188 GUI<bool>::GetSetting(this, "scrollbar", scrollbar); 189 189 GUI<CGUIList>::GetSettingPointer(this, "list", pList); 190 190 float scroll = 0.f; 191 191 if (scrollbar) 192 192 scroll = GetScrollBar(0).GetPos(); 193 193 194 194 CRect rect = GetListRect(); 195 195 CPos mouse = GetMousePos(); 196 196 mouse.y += scroll; 197 197 int set = -1; 198 198 for (int i = 0; i < (int)pList->m_Items.size(); ++i) 199 199 { 200 200 if (mouse.y >= rect.top + m_ItemsYPositions[i] && 201 201 mouse.y < rect.top + m_ItemsYPositions[i+1] && 202 202 // mouse is not over scroll-bar 203 !(mouse.x >= GetScrollBar(0).GetOuterRect().left && 204 mouse.x <= GetScrollBar(0).GetOuterRect().right)) 203 (!scrollbar || !GetScrollBar(0).IsVisible() || 204 mouse.x < GetScrollBar(0).GetOuterRect().left || 205 mouse.x > GetScrollBar(0).GetOuterRect().right)) 205 206 { 206 207 set = i; 207 208 } 208 209 } 209 210 210 211 if (set != -1) 211 212 { 212 213 GUI<int>::SetSetting(this, "selected", set); 213 214 UpdateAutoScroll(); 214 215 215 216 CStrW soundPath; 216 217 if (g_SoundManager && GUI<CStrW>::GetSetting(this, "sound_selected", soundPath) == PSRETURN_OK && !soundPath.empty()) 217 218 g_SoundManager->PlayAsUI(soundPath.c_str(), false); 218 219 } 219 220 break; 220 221 } 221 222 222 223 case GUIM_LOAD: 223 224 { 224 225 CStr scrollbar_style; 225 226 GUI<CStr>::GetSetting(this, "scrollbar_style", scrollbar_style); 226 227 GetScrollBar(0).SetScrollBarStyle(scrollbar_style); 227 228 break; 228 229 } 229 230 230 231 default: 231 232 break; 232 233 } 233 234 234 235 IGUITextOwner::HandleMessage(Message); 235 236 } 236 237 237 238 InReaction CList::ManuallyHandleEvent(const SDL_Event_* ev) 238 239 { 239 240 InReaction result = IN_PASS; 240 241 241 242 if (ev->ev.type == SDL_KEYDOWN) 242 243 { 243 244 int szChar = ev->ev.key.keysym.sym; 244 245 245 246 switch (szChar) 246 247 { 247 248 case SDLK_HOME: 248 249 SelectFirstElement(); 249 250 UpdateAutoScroll(); 250 251 result = IN_HANDLED; 251 252 break; 252 253 -
source/gui/IGUIScrollBar.h
165 165 virtual void Draw() = 0; 166 166 167 167 /** 168 168 * If an object that contains a scrollbar has got messages, send 169 169 * them to the scroll-bar and it will see if the message regarded 170 170 * itself. 171 171 * 172 172 * @see IGUIObject#HandleMessage() 173 173 */ 174 174 virtual void HandleMessage(SGUIMessage& Message) = 0; 175 175 176 176 /** 177 177 * Set m_Pos with g_mouse_x/y input, i.e. when draggin. 178 178 */ 179 179 virtual void SetPosFromMousePos(const CPos& mouse) = 0; 180 180 181 181 /** 182 182 * Hovering the scroll minus button 183 183 * 184 184 * @param mouse current mouse position 185 185 * @return True if mouse positions are hovering the button 186 186 */ 187 187 virtual bool HoveringButtonMinus(const CPos& UNUSED(mouse)) { return false; } 188 188 189 189 /** 190 190 * Hovering the scroll plus button 191 191 * 192 192 * @param mouse current mouse position 193 193 * @return True if mouse positions are hovering the button 194 194 */ 195 195 virtual bool HoveringButtonPlus(const CPos& UNUSED(mouse)) { return false; } 196 196 197 197 /** 198 198 * Get scroll-position 199 199 */ 200 200 float GetPos() const { return m_Pos; } 201 201 202 202 /** 203 203 * Set scroll-position by hand 204 204 */ 205 205 virtual void SetPos(float f) { m_Pos = f; UpdatePosBoundaries(); } 206 206 207 207 /** 208 208 * Get the value of m_Pos that corresponds to the bottom of the scrollable region 209 209 */ 210 210 float GetMaxPos() const { return std::max(1.f, m_ScrollRange - m_ScrollSpace); } 211 211 212 212 /** 213 * Get the value of m_Pos that corresponds to the bottom of the scrollable region 214 */ 215 float IsVisible() const { return GetMaxPos() != 1.f; } 216 217 /** 213 218 * Increase scroll one step 214 219 */ 215 220 virtual void ScrollPlus() { m_Pos += 30.f; UpdatePosBoundaries(); } 216 221 217 222 /** 218 223 * Decrease scroll one step 219 224 */ 220 225 virtual void ScrollMinus() { m_Pos -= 30.f; UpdatePosBoundaries(); } 221 226 222 227 /** 223 228 * Increase scroll three steps 224 229 */ 225 230 virtual void ScrollPlusPlenty() { m_Pos += 90.f; UpdatePosBoundaries(); } 226 231 227 232 /** 228 233 * Decrease scroll three steps 229 234 */ 230 235 virtual void ScrollMinusPlenty() { m_Pos -= 90.f; UpdatePosBoundaries(); } 231 236 232 237 /** 233 238 * Set host object, must be done almost at creation of scroll bar. 234 239 * @param pOwner Pointer to host object. 235 240 */ 236 241 void SetHostObject(IGUIScrollBarOwner* pOwner) { m_pHostObject = pOwner; } 237 242 238 243 /** 239 244 * Get GUI pointer 240 245 * @return CGUI pointer 241 246 */ 242 247 CGUI* GetGUI() const; 243 248 244 249 /** 245 250 * Set GUI pointer 246 251 * @param pGUI pointer to CGUI object. 247 252 */ 248 253 void SetGUI(CGUI* pGUI) { m_pGUI = pGUI; } 249 254 250 255 /** 251 256 * Set Width 252 257 * @param width Width 253 258 */ 254 259 void SetWidth(float width) { m_Width = width; } 255 260 256 261 /** 257 262 * Set X Position 258 263 * @param x Position in this axis 259 264 */ 260 265 void SetX(float x) { m_X = x; }