• entries
    707
  • comments
    1173
  • views
    434104

One last update for this

Sign in to follow this  

165 views

Ok, this will probably be my last update about the GUI until tomorrow. I need to get some work done on Malathedra.

I fixed the selection problem. I'm not quite sure what the problem was, but no matter what, clicking on the top item selected the first item (meaning Item 1.) I also took a moment to test my ListBox system and it works exactly how I wanted it to. Here are two different images:


ListBox with scrolling



ListBox with scrolling


The second one uses the same exact code except for the allocation code (I had to switch to a different class.) Here's the first image's class:

class ListBoxItem : public Widget
{
protected:
static int m_nIndex;
public:
ListBoxItem();
~ListBoxItem();

bool OnLeftClick(const InputEvent& Event);
bool OnLeftRelease(const InputEvent& Event);

virtual void Set(Widget* pParent, const std::string& Text);

void Render(Texture* pTexture, Graphics* pGraphics, Font* pFont);
virtual void Render(int nIndex, int nItemHeight, Texture* pTexture, Graphics* pGraphics, Font* pFont);
};



int ListBox::ListBoxItem::m_nIndex = 0;

ListBox::ListBoxItem::ListBoxItem()
{
m_nType = Widget::WidgetTypes::ListBoxItem;
m_nID = m_nIndex;
++m_nIndex;
}

ListBox::ListBoxItem::~ListBoxItem()
{
}

bool ListBox::ListBoxItem::OnLeftClick(const InputEvent& Event)
{
if(m_bVisible)
{
for(std::map<int, boost::shared_ptr >::iterator Itor = m_Children.begin(); Itor != m_Children.end(); ++Itor)
{
if(((*Itor).second.get())->OnLeftClick(Event))
return true;
}

if(PointIsIn(Event.m_AbsMousePos))
{
m_bDragging = true;
m_nState = 2;
return true;
}
}
return false;

}

bool ListBox::ListBoxItem::OnLeftRelease(const InputEvent& Event)
{
if(m_bVisible)
{
for(std::map<int, boost::shared_ptr >::iterator Itor = m_Children.begin(); Itor != m_Children.end(); ++Itor)
{
if(((*Itor).second.get())->OnLeftRelease(Event))
return true;
}

m_bDragging = false;
m_nState = 0;
if(PointIsIn(Event.m_AbsMousePos))
{
((ListBox*)m_pParent)->SetActiveItem(this);
return true;
}
}
return false;
}

void ListBox::ListBoxItem::Set(Widget* pParent, const std::string& Text)
{
Widget::Set(pParent, Text, 0, 0, 0, 0, m_nIndex);

if(pParent)
{
if(pParent->GetType() == Widget::WidgetTypes::ListBox)
((ListBox*)pParent)->SetItemHeight(24);
}
}

void ListBox::ListBoxItem::Render(Texture* pTexture, Graphics* pGraphics, Font* pFont)
{
if(m_bVisible)
{
D3DXVECTOR3 Position = m_Position;
if(m_pParent)
Position += m_pParent->GetPosition();

if(m_nState > 0 || m_bActive)
{
int nBorderColor = 0xffcc9900;
int nBackgroundColor = 0xff000000;

if(m_bActive)
{
nBorderColor = 0xffffbf00;
nBackgroundColor = 0xff333333;
}

switch(m_nState)
{
case 1:
{
nBorderColor = 0xffffbf00;
nBackgroundColor = 0xff333333;
break;
}

case 2:
{
nBorderColor = 0xff333333;
nBackgroundColor = 0xffcc9900;
break;
}
}

Vertex* pTempVertices = new Vertex[12];
int nVertexCount = 12;
Vertex::FillQuad(&pTempVertices[0], Position.x + 3, Position.y + 3, m_nWidth - 6, m_nHeight - 6, nBorderColor, 0, 0);
Vertex::FillQuad(&pTempVertices[6], Position.x + 4, Position.y + 4, m_nWidth - 8, m_nHeight - 8, nBackgroundColor, 0, 0);

Vertex* pVertices = 0;
IDirect3DVertexBuffer9* pBuffer = 0;
pGraphics->GetDeviceComPtr()->CreateVertexBuffer(nVertexCount * Vertex::SIZE, 0, Vertex::FVF, D3DPOOL_MANAGED, &pBuffer, 0);
if(pBuffer)
{
pBuffer->Lock(0, 0, (void**)&pVertices, 0);
memcpy(pVertices, pTempVertices, nVertexCount * Vertex::SIZE);
pBuffer->Unlock();

pGraphics->SetFVF(Vertex::FVF);
pGraphics->SetTexture(0, 0);
pGraphics->GetDeviceComPtr()->SetStreamSource(0, pBuffer, 0, Vertex::SIZE);
pGraphics->GetDeviceComPtr()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);
pBuffer->Release();
}
delete [] pTempVertices;
}

RECT Rect = {Position.x + 6, Position.y, Position.x + m_nWidth, Position.y + m_nHeight};
pFont->GetComPtr()->DrawTextA(0, m_Text.c_str(), -1, &Rect, DT_VCENTER, 0xffffffff);
}
}

void ListBox::ListBoxItem::Render(int nIndex, int nItemHeight, Texture* pTexture, Graphics* pGraphics, Font* pFont)
{
Move(0, nIndex * nItemHeight);
Resize(m_pParent->GetWidth(), nItemHeight);

if(m_Position.y >= 0 && m_Position.y + nItemHeight < m_pParent->GetHeight())
Render(pTexture, pGraphics, pFont);
}



And here is the class from the second image (derived from the first class.)
*Note - This is just a hacked class, I don't plan on using it. Also, my Graphics class handle's setting textures, so calling SetTexture() for each object isn't as slow (my Graphics class checks for setting the same texture and null textures.)

class InventoryLBI : public ListBox::ListBoxItem
{
Texture* m_pTexture;
public:
void Set(Widget* pParent, const std::string& Text)
{
Widget::Set(pParent, Text, 0, 0, 0, 0, m_nIndex);

if(pParent)
{
if(pParent->GetType() == Widget::WidgetTypes::ListBox)
((ListBox*)pParent)->SetItemHeight(50);
}

m_pTexture = Texture::LoadTexture("test.bmp", "LBI_TEST");
}

void Render(Texture* pTexture, Graphics* pGraphics, Font* pFont)
{
if(m_bVisible)
{
D3DXVECTOR3 Position = m_Position;
if(m_pParent)
Position += m_pParent->GetPosition();

if(m_nState > 0 || m_bActive)
{
int nBorderColor = 0xffcc9900;
int nBackgroundColor = 0xff000000;

if(m_bActive)
{
nBorderColor = 0xffffbf00;
nBackgroundColor = 0xff333333;
}

switch(m_nState)
{
case 1:
{
nBorderColor = 0xffffbf00;
nBackgroundColor = 0xff333333;
break;
}

case 2:
{
nBorderColor = 0xff333333;
nBackgroundColor = 0xffcc9900;
break;
}
}

Vertex* pTempVertices = new Vertex[12];
int nVertexCount = 12;
Vertex::FillQuad(&pTempVertices[0], Position.x + 3, Position.y + 3, m_nWidth - 6, m_nHeight - 6, nBorderColor, 0, 0);
Vertex::FillQuad(&pTempVertices[6], Position.x + 4, Position.y + 4, m_nWidth - 8, m_nHeight - 8, nBackgroundColor, 0, 0);

Vertex* pVertices = 0;
IDirect3DVertexBuffer9* pBuffer = 0;
pGraphics->GetDeviceComPtr()->CreateVertexBuffer(nVertexCount * Vertex::SIZE, 0, Vertex::FVF, D3DPOOL_MANAGED, &pBuffer, 0);
if(pBuffer)
{
pBuffer->Lock(0, 0, (void**)&pVertices, 0);
memcpy(pVertices, pTempVertices, nVertexCount * Vertex::SIZE);
pBuffer->Unlock();

pGraphics->SetFVF(Vertex::FVF);
pGraphics->SetTexture(0, 0);
pGraphics->GetDeviceComPtr()->SetStreamSource(0, pBuffer, 0, Vertex::SIZE);
pGraphics->GetDeviceComPtr()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 4);

pBuffer->Release();
}
delete [] pTempVertices;
}

RECT SrcRect = {0, 0, 30, 30};

Vertex* pTempVertices = new Vertex[6];
int nVertexCount = 6;
Vertex::FillQuad(pTempVertices, Position.x + 6, Position.y + 6, 30, 30, 0xffffffff, &SrcRect, m_pTexture);

Vertex* pVertices = 0;
IDirect3DVertexBuffer9* pBuffer = 0;
pGraphics->GetDeviceComPtr()->CreateVertexBuffer(nVertexCount * Vertex::SIZE, 0, Vertex::FVF, D3DPOOL_MANAGED, &pBuffer, 0);
if(pBuffer)
{
pBuffer->Lock(0, 0, (void**)&pVertices, 0);
memcpy(pVertices, pTempVertices, nVertexCount * Vertex::SIZE);
pBuffer->Unlock();

pGraphics->SetFVF(Vertex::FVF);
pGraphics->SetTexture(0, m_pTexture);
pGraphics->GetDeviceComPtr()->SetStreamSource(0, pBuffer, 0, Vertex::SIZE);
pGraphics->GetDeviceComPtr()->DrawPrimitive(D3DPT_TRIANGLELIST, 0, 2);

pBuffer->Release();
}
delete [] pTempVertices;

RECT Rect = {Position.x + 39, Position.y, Position.x + m_nWidth, Position.y + m_nHeight};
pFont->GetComPtr()->DrawTextA(0, m_Text.c_str(), -1, &Rect, DT_VCENTER, 0xffffffff);
}
}
};


Sorry, no demo this time[sad].
Comments/questions/suggestions?
Sign in to follow this  


6 Comments


Recommended Comments

I don't think you want to be creating vertex buffers on the fly, as it may be quite slow. This is what DrawPrimitiveUP is for.

Also, if you know up front you only want 6 vertices, just make a local array of them instead of new[] and delete[].

Share this comment


Link to comment
The rendering code isn't finished ATM, hence the "*Note"[wink].

I don't know up front that I'll only need 6 vertices. This (hacked) code is just copied and pasted from my other rendering function (and some of the other classes have 6, 12, 18, and eventually 54 vertices.)

Also, I had tried using DrawPrimitiveUP() and I recieved no speed gain so it would be pointless to convert my code.

Share this comment


Link to comment
Creating & deleting VBs at runtime is the slowest possible way to do it. Right now you are likely bound by other things. The way to go for small things like this is drawprimitiveup or locking a dynamic vb ( with the proper flags ).

Share this comment


Link to comment
Yea, I completely misworded my reply; sorry. What I meant was there is no reason to convert my code at this time. My final rendering code won't create vb's at run-time, they'll be created at load-time.

I didn't realize that creating & releasing VB's at runtime was so slow. Thanks for the info!

Share this comment


Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now