1
0
forked from 0ad/0ad

CDropDown and the CGUIList type. This code is kind of rough around the edges as of yet. I'll work on it more.

This was SVN commit r2164.
This commit is contained in:
Gee 2005-04-23 23:21:54 +00:00
parent 15759ff4d7
commit 15f951bfbc
4 changed files with 479 additions and 0 deletions

337
source/gui/CDropDown.cpp Normal file
View File

@ -0,0 +1,337 @@
/*
CDropDown
by Gustav Larsson
gee@pyro.nu
*/
#include "precompiled.h"
#include "GUI.h"
#include "CDropDown.h"
#include "ogl.h"
using namespace std;
//-------------------------------------------------------------------
// Constructor / Destructor
//-------------------------------------------------------------------
CDropDown::CDropDown() : m_Open(false), m_HideScrollBar(false), m_ElementHighlight(-1)
{
AddSetting(GUIST_float, "dropdown_size");
AddSetting(GUIST_float, "dropdown_buffer");
AddSetting(GUIST_CStr, "font");
AddSetting(GUIST_CGUISpriteInstance, "sprite"); // Background that sits around the size
AddSetting(GUIST_CGUISpriteInstance, "sprite_list"); // Background of the drop down list
AddSetting(GUIST_CGUISpriteInstance, "sprite2"); // Button that sits to the right
AddSetting(GUIST_CGUISpriteInstance, "sprite2_over");
AddSetting(GUIST_CGUISpriteInstance, "sprite2_pressed");
AddSetting(GUIST_CGUISpriteInstance, "sprite2_disabled");
AddSetting(GUIST_float, "button_width");
AddSetting(GUIST_EVAlign, "text_valign");
AddSetting(GUIST_CColor, "textcolor_over");
AddSetting(GUIST_CColor, "textcolor_pressed");
AddSetting(GUIST_CColor, "textcolor_disabled");
// Scrollbar is forced to be true.
GUI<bool>::SetSetting(this, "scrollbar", true);
}
CDropDown::~CDropDown()
{
}
void CDropDown::SetupText()
{
CList::SetupText();
SetupListRect();
}
void CDropDown::HandleMessage(const SGUIMessage &Message)
{
// Important
switch (Message.type)
{
case GUIM_SETTINGS_UPDATED:
bool scrollbar;
GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
// Update scroll-bar
// TODO Gee: (2004-09-01) Is this really updated each time it should?
if (scrollbar &&
(Message.value == CStr("dropdown_size")/* ||
Message.value == CStr("")*/))
{
CRect rect = GetListRect();
GetScrollBar(0).SetX( rect.right );
GetScrollBar(0).SetY( rect.top );
GetScrollBar(0).SetZ( GetBufferedZ() );
GetScrollBar(0).SetLength( rect.bottom - rect.top );
}
// Update cached list rect
if (Message.value == CStr("size") ||
Message.value == CStr("absolute") ||
Message.value == CStr("dropdown_size") ||
Message.value == CStr("dropdown_buffer") ||
Message.value == CStr("scrollbar_style") ||
Message.value == CStr("button_width"))
{
SetupListRect();
}
break;
case GUIM_MOUSE_MOTION:{
if (m_Open)
{
CPos mouse = GetMousePos();
if (GetListRect().PointInside(mouse))
{
bool scrollbar;
CGUIList *pList;
GUI<bool>::GetSetting(this, "scrollbar", scrollbar);
GUI<CGUIList>::GetSettingPointer(this, "list", pList);
float scroll=0.f;
if (scrollbar)
{
scroll = GetScrollBar(0).GetPos();
}
CRect rect = GetListRect();
mouse.y += scroll;
int set=-1;
for (int i=0; i<pList->m_Items.size(); ++i)
{
if (mouse.y >= rect.top + m_ItemsYPositions[i] &&
mouse.y < rect.top + m_ItemsYPositions[i+1] &&
// mouse is not over scroll-bar
!(mouse.x >= GetScrollBar(0).GetOuterRect().left &&
mouse.x <= GetScrollBar(0).GetOuterRect().right))
{
set = i;
}
}
if (set != -1)
{
//GUI<int>::SetSetting(this, "selected", set);
m_ElementHighlight = set;
//UpdateAutoScroll();
}
}
}
}break;
case GUIM_MOUSE_LEAVE:{
GUI<int>::GetSetting(this, "selected", m_ElementHighlight);
}break;
// We can't inherent this routine from CList, because we need to include
// a mouse click to open the dropdown, also the coordinates are changed.
case GUIM_MOUSE_PRESS_LEFT:
{
if (!m_Open)
{
m_Open = true;
GetScrollBar(0).SetPos(0.f);
UpdateAutoScroll();
GUI<int>::GetSetting(this, "selected", m_ElementHighlight);
return; // overshadow
}
else
{
CPos mouse = GetMousePos();
// If the regular area is pressed, then abort, and close.
if (m_CachedActualSize.PointInside(mouse))
{
m_Open = false;
return; // overshadow
}
if (!(mouse.x >= GetScrollBar(0).GetOuterRect().left &&
mouse.x <= GetScrollBar(0).GetOuterRect().right) &&
mouse.y >= GetListRect().top)
{
m_Open = false;
}
}
} break;
case GUIM_LOST_FOCUS:
m_Open=false;
break;
case GUIM_LOAD:
SetupListRect();
break;
default:
break;
}
// Important that this is after, so that overshadowed implementations aren't processed
CList::HandleMessage(Message);
}
int CDropDown::ManuallyHandleEvent(const SDL_Event* ev)
{
int szChar = ev->key.keysym.sym;
bool update_highlight = false;
switch (szChar)
{
case '\r':
m_Open=false;
break;
case SDLK_HOME:
case SDLK_END:
case SDLK_UP:
case SDLK_DOWN:
case SDLK_PAGEUP:
case SDLK_PAGEDOWN:
if (!m_Open)
return EV_PASS;
// Set current selected item to highlighted, before
// then really processing these in CList::ManuallyHandleEvent()
GUI<int>::SetSetting(this, "selected", m_ElementHighlight);
update_highlight = true;
break;
default:
break;
}
CList::ManuallyHandleEvent(ev);
if (update_highlight)
GUI<int>::GetSetting(this, "selected", m_ElementHighlight);
return EV_HANDLED;
}
void CDropDown::SetupListRect()
{
float size, buffer, button_width;
GUI<float>::GetSetting(this, "dropdown_size", size);
GUI<float>::GetSetting(this, "dropdown_buffer", buffer);
GUI<float>::GetSetting(this, "button_width", button_width);
if (m_ItemsYPositions.empty() || m_ItemsYPositions.back() >= size)
{
m_CachedListRect = CRect(m_CachedActualSize.left, m_CachedActualSize.bottom+buffer,
m_CachedActualSize.right, m_CachedActualSize.bottom+buffer + size);
m_HideScrollBar = false;
}
else
{
m_CachedListRect = CRect(m_CachedActualSize.left, m_CachedActualSize.bottom+buffer,
m_CachedActualSize.right - GetScrollBar(0).GetStyle()->m_Width, m_CachedActualSize.bottom+buffer + m_ItemsYPositions.back());
// We also need to hide the scrollbar
m_HideScrollBar = true;
}
}
CRect CDropDown::GetListRect() const
{
return m_CachedListRect;
}
bool CDropDown::MouseOver()
{
if(!GetGUI())
throw PS_NEEDS_PGUI;
if (m_Open)
{
CRect rect(m_CachedActualSize.left, m_CachedActualSize.top,
m_CachedActualSize.right, GetListRect().bottom);
return rect.PointInside(GetMousePos());
}
else
return m_CachedActualSize.PointInside(GetMousePos());
}
void CDropDown::Draw()
{
if (!GetGUI())
return;
float bz = GetBufferedZ();
float dropdown_size, button_width;
GUI<float>::GetSetting(this, "dropdown_size", dropdown_size);
GUI<float>::GetSetting(this, "button_width", button_width);
CGUISpriteInstance *sprite, *sprite2, *sprite2_second;
int cell_id, selected=0;
CColor color;
GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite", sprite);
GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite2", sprite2);
GUI<int>::GetSetting(this, "cell_id", cell_id);
GUI<int>::GetSetting(this, "selected", selected);
GUI<CColor>::GetSetting(this, "textcolor", color);
bool enabled;
GUI<bool>::GetSetting(this, "enabled", enabled);
GetGUI()->DrawSprite(*sprite, cell_id, bz, m_CachedActualSize);
if (button_width > 0.f)
{
CRect rect(m_CachedActualSize.right-button_width, m_CachedActualSize.top,
m_CachedActualSize.right, m_CachedActualSize.bottom);
if (!enabled)
{
GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite2_disabled", sprite2_second);
GetGUI()->DrawSprite(GUI<>::FallBackSprite(*sprite2_second, *sprite2), cell_id, bz+0.05f, rect);
}
else
if (m_Open)
{
GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite2_pressed", sprite2_second);
GetGUI()->DrawSprite(GUI<>::FallBackSprite(*sprite2_second, *sprite2), cell_id, bz+0.05f, rect);
}
else
if (m_MouseHovering)
{
GUI<CGUISpriteInstance>::GetSettingPointer(this, "sprite2_over", sprite2_second);
GetGUI()->DrawSprite(GUI<>::FallBackSprite(*sprite2_second, *sprite2), cell_id, bz+0.05f, rect);
}
else
GetGUI()->DrawSprite(*sprite2, cell_id, bz+0.05f, rect);
}
CPos pos(m_CachedActualSize.left, m_CachedActualSize.top);
IGUITextOwner::Draw(selected, color, pos, bz+0.1f);
bool *scrollbar=NULL, old;
GUI<bool>::GetSettingPointer(this, "scrollbar", scrollbar);
old = *scrollbar;
if (m_Open)
{
if (m_HideScrollBar)
*scrollbar = false;
DrawList(m_ElementHighlight, "sprite_list", "sprite_selectarea", "textcolor");
if (m_HideScrollBar)
*scrollbar = old;
}
}

119
source/gui/CDropDown.h Normal file
View File

@ -0,0 +1,119 @@
/*
GUI Object - Drop Down (list)
by Gustav Larsson
gee@pyro.nu
--Overview--
Works just like a list-box, but it hides
all the elements that aren't selected. They
can be brought up by pressing the control.
--More info--
Check GUI.h
*/
#ifndef CDropDown_H
#define CDropDown_H
//--------------------------------------------------------
// Includes / Compiler directives
//--------------------------------------------------------
#include "GUI.h"
#include "CList.h"
//class CList;
//--------------------------------------------------------
// Macros
//--------------------------------------------------------
//--------------------------------------------------------
// Types
//--------------------------------------------------------
//--------------------------------------------------------
// Declarations
//--------------------------------------------------------
/**
* @author Gustav Larsson
*
* Drop Down
*
* The control can be pressed, but we will not inherent
* this behavior from IGUIButtonBehavior, because when
* you press this control, the list with elements will
* immediately appear, and not first after release
* (which is the whole gist of the IGUIButtonBehavior).
*/
class CDropDown : public CList
{
GUI_OBJECT(CDropDown)
public:
CDropDown();
virtual ~CDropDown();
// virtual void ResetStates() { IGUIButtonBehavior::ResetStates(); }
/**
* Handle Messages
*
* @param Message GUI Message
*/
virtual void HandleMessage(const SGUIMessage &Message);
/**
* Handle events manually to catch keyboard inputting.
*/
virtual int ManuallyHandleEvent(const SDL_Event* ev);
/**
* Draws the Button
*/
virtual void Draw();
// This is one of the few classes we actually need to redefine this function
// this is because the size of the control changes whether it is open
// or closed.
virtual bool MouseOver();
protected:
/**
* Sets up text, should be called every time changes has been
* made that can change the visual.
*/
void SetupText();
// Sets up the cached GetListRect. Decided whether it should
// have a scrollbar, and so on.
virtual void SetupListRect();
// Specify a new List rectangle.
virtual CRect GetListRect() const;
/**
* Placement of text.
*/
CPos m_TextPos;
// Is the dropdown opened?
bool m_Open;
// I didn't cache this at first, but it's just as easy as caching
// m_CachedActualSize, so I thought, what the heck it's used a lot.
CRect m_CachedListRect;
// Hide scrollbar when it's not needed
bool m_HideScrollBar;
// Not necessarily the element that is selected, this is just
// which element should be highlighted. When opening the dropdown
// it is set to "selected", but then when moving the mouse it will
// change.
int m_ElementHighlight;
};
#endif

6
source/gui/CGUIList.cpp Normal file
View File

@ -0,0 +1,6 @@
#include "precompiled.h"
#include "CGUIList.h"

17
source/gui/CGUIList.h Normal file
View File

@ -0,0 +1,17 @@
#ifndef CGUIList_H
#define CGUIList_H
class CGUIList
{
public: // struct:ish (but for consistency I call it _C_GUIList, and
// for the same reason it is a class, so that confusion doesn't
// appear when forward declaring.
/**
* List of items (as text), the post-processed result is stored in
* the IGUITextOwner structure of this class.
*/
std::vector<CGUIString> m_Items;
};
#endif