summaryrefslogtreecommitdiff
path: root/src/interface
diff options
context:
space:
mode:
authorSimon Robertshaw <simon@hardwired.org.uk>2012-07-26 20:51:30 (GMT)
committer Simon Robertshaw <simon@hardwired.org.uk>2012-07-26 20:51:30 (GMT)
commitf8ca8af387b8611c18ca7c5357efd19c8bc28941 (patch)
treefe790e2abede326949bb299b564ba8e75a979ecf /src/interface
parent121e7c772cfc7b3e1305a03144264fc5b66564c2 (diff)
downloadpowder-f8ca8af387b8611c18ca7c5357efd19c8bc28941.zip
powder-f8ca8af387b8611c18ca7c5357efd19c8bc28941.tar.gz
Scroll Panel
Diffstat (limited to 'src/interface')
-rw-r--r--src/interface/Component.h2
-rw-r--r--src/interface/Panel.cpp160
-rw-r--r--src/interface/Panel.h18
-rw-r--r--src/interface/ScrollPanel.cpp117
-rw-r--r--src/interface/ScrollPanel.h25
5 files changed, 271 insertions, 51 deletions
diff --git a/src/interface/Component.h b/src/interface/Component.h
index bd3878a..5ef672d 100644
--- a/src/interface/Component.h
+++ b/src/interface/Component.h
@@ -37,6 +37,8 @@ namespace ui
inline Window* const GetParentWindow() const { return parentstate_; }
bool IsFocused() const;
+ void Invalidate() { drawn = false; }
+
Point Position;
Point Size;
bool Locked;
diff --git a/src/interface/Panel.cpp b/src/interface/Panel.cpp
index d2de97e..3b9cfc1 100644
--- a/src/interface/Panel.cpp
+++ b/src/interface/Panel.cpp
@@ -7,25 +7,40 @@
#include "interface/Point.h"
#include "interface/Window.h"
#include "interface/Component.h"
+#include "graphics/Graphics.h"
using namespace ui;
-Panel::Panel(Window* parent_state):
- Component(parent_state)
-{
-
-}
-
Panel::Panel(Point position, Point size):
- Component(position, size)
-{
-
-}
-
-Panel::Panel():
- Component()
-{
-
+ Component(position, size),
+ InnerSize(size),
+ ViewportPosition(0, 0),
+ mouseInside(false)
+{
+#ifdef OGLI
+ GLint lastVid;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &lastVid);
+
+ glEnable(GL_TEXTURE_2D);
+ glGenTextures(1, &myVidTex);
+ glBindTexture(GL_TEXTURE_2D, myVidTex);
+ glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, XRES+BARSIZE, YRES+MENUSIZE, 0, GL_RGBA, GL_FLOAT, NULL);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);
+ glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);
+
+ //FBO
+ glGenFramebuffers(1, &myVid);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, myVid);
+ glEnable(GL_BLEND);
+ glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, myVidTex, 0);
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); // Reset framebuffer binding
+ glDisable(GL_TEXTURE_2D);
+
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, lastVid);
+#else
+ myVid = new pixel[(XRES+BARSIZE)*(YRES+MENUSIZE)];
+#endif
}
Panel::~Panel()
@@ -35,11 +50,18 @@ Panel::~Panel()
if( children[i] )
delete children[i];
}
+#ifdef OGLI
+ glDeleteTextures(1, &myVidTex);
+ glDeleteFramebuffers(1, &myVid);
+#else
+ delete[] myVid;
+#endif
}
void Panel::AddChild(Component* c)
{
c->SetParent(this);
+ c->SetParentWindow(this->GetParentWindow());
}
int Panel::GetChildCount()
@@ -75,8 +97,20 @@ void Panel::RemoveChild(unsigned idx, bool freeMem)
void Panel::Draw(const Point& screenPos)
{
+
// draw ourself first
XDraw(screenPos);
+#ifdef OGLI
+ GLint lastVid;
+ glGetIntegerv(GL_FRAMEBUFFER_BINDING, &lastVid);
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, myVid);
+ glClearColor(1.0f, 0.0f, 0.0f, 0.0f);
+ glClear(GL_COLOR_BUFFER_BIT);
+#else
+ pixel * lastVid = ui::Engine::Ref().g->vid;
+ ui::Engine::Ref().g->vid = myVid;
+ std::fill(myVid, myVid+((XRES+BARSIZE)*(YRES+MENUSIZE)), 0);
+#endif
// attempt to draw all children
for(int i = 0; i < children.size(); ++i)
@@ -84,26 +118,52 @@ void Panel::Draw(const Point& screenPos)
// the component must be visible
if(children[i]->Visible)
{
- if(GetParentWindow()->AllowExclusiveDrawing)
+ //check if the component is in the screen, draw if it is
+ if( children[i]->Position.X + ViewportPosition.X + children[i]->Size.X >= 0 &&
+ children[i]->Position.Y + ViewportPosition.Y + children[i]->Size.Y >= 0 &&
+ children[i]->Position.X + ViewportPosition.X < ui::Engine::Ref().GetWidth() &&
+ children[i]->Position.Y + ViewportPosition.Y < ui::Engine::Ref().GetHeight() )
{
- //who cares if the component is off the screen? draw anyway.
- Point scrpos = screenPos + children[i]->Position;
+ Point scrpos = /*screenPos + */children[i]->Position + ViewportPosition;
children[i]->Draw(scrpos);
}
- else
- {
- //check if the component is in the screen, draw if it is
- if( children[i]->Position.X + children[i]->Size.X >= 0 &&
- children[i]->Position.Y + children[i]->Size.Y >= 0 &&
- children[i]->Position.X < ui::Engine::Ref().GetWidth() &&
- children[i]->Position.Y < ui::Engine::Ref().GetHeight() )
- {
- Point scrpos = screenPos + children[i]->Position;
- children[i]->Draw(scrpos);
- }
- }
}
}
+
+#ifdef OGLI
+ glBindFramebuffer(GL_DRAW_FRAMEBUFFER, lastVid);
+
+ glEnable(GL_TEXTURE_2D);
+ glBindTexture(GL_TEXTURE_2D, myVidTex);
+
+ int x = screenPos.X, y = screenPos.Y;
+ int h = Size.Y, w = Size.X;
+
+ double texX = double(Size.X)/double(XRES+BARSIZE), texY = 1, texYB = 1-(double(Size.Y)/double(YRES+MENUSIZE));
+
+ glColor4f(1.0f, 1.0f, 1.0f, 1.0f);
+ glBegin(GL_QUADS);
+ glTexCoord2d(0, texYB);
+ glVertex2f(x, y+h);
+ glTexCoord2d(texX, texYB);
+ glVertex2f(x+w, y+h);
+ glTexCoord2d(texX, texY);
+ glVertex2f(x+w, y);
+ glTexCoord2d(0, texY);
+ glVertex2f(x, y);
+ glEnd();
+
+ glBindTexture(GL_TEXTURE_2D, 0);
+ glDisable(GL_TEXTURE_2D);
+#else
+ ui::Engine::Ref().g->vid = lastVid;
+
+ //dst=(pixel *)sdl_scrn->pixels+y*sdl_scrn->pitch/PIXELSIZE+x;
+ for (int row = 0; row < Size.Y; row++)
+ {
+ std::copy(myVid+(row*Size.W), myVid+(row*Size.W)+Size.W, lastVid+(screenPos.Y*(XRES+BARSIZE))+screenPos.X);
+ }
+#endif
}
void Panel::Tick(float dt)
@@ -137,14 +197,14 @@ void Panel::OnMouseClick(int localx, int localy, unsigned button)
if(!children[i]->Locked)
{
//is mouse inside?
- if( localx >= children[i]->Position.X &&
- localy >= children[i]->Position.Y &&
- localx < children[i]->Position.X + children[i]->Size.X &&
- localy < children[i]->Position.Y + children[i]->Size.Y )
+ if( localx >= children[i]->Position.X + ViewportPosition.X &&
+ localy >= children[i]->Position.Y + ViewportPosition.Y &&
+ localx < children[i]->Position.X + ViewportPosition.X + children[i]->Size.X &&
+ localy < children[i]->Position.Y + ViewportPosition.Y + children[i]->Size.Y )
{
childclicked = true;
GetParentWindow()->FocusComponent(children[i]);
- children[i]->OnMouseClick(localx - children[i]->Position.X, localy - children[i]->Position.Y, button);
+ children[i]->OnMouseClick(localx - children[i]->Position.X - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, button);
break;
}
}
@@ -196,7 +256,7 @@ void Panel::OnMouseMoved(int localx, int localy, int dx, int dy)
for(int i = 0; i < children.size(); ++i)
{
if(!children[i]->Locked)
- children[i]->OnMouseMoved(localx - children[i]->Position.X, localy - children[i]->Position.Y, dx, dy);
+ children[i]->OnMouseMoved(localx - children[i]->Position.X - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, dx, dy);
}
}
@@ -206,7 +266,7 @@ void Panel::OnMouseMovedInside(int localx, int localy, int dx, int dy)
{
if(!children[i]->Locked)
{
- Point local (localx - children[i]->Position.X, localy - children[i]->Position.Y)
+ Point local (localx - children[i]->Position.X - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y)
, prevlocal (local.X - dx, local.Y - dy);
// mouse currently inside?
@@ -215,7 +275,7 @@ void Panel::OnMouseMovedInside(int localx, int localy, int dx, int dy)
local.X < children[i]->Size.X &&
local.Y < children[i]->Size.Y )
{
- children[i]->OnMouseMovedInside(localx - children[i]->Position.X, localy - children[i]->Position.Y, dx, dy);
+ children[i]->OnMouseMovedInside(localx - children[i]->Position.X - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, dx, dy);
// was the mouse outside?
if(!(prevlocal.X >= 0 &&
@@ -248,11 +308,13 @@ void Panel::OnMouseMovedInside(int localx, int localy, int dx, int dy)
void Panel::OnMouseEnter(int localx, int localy)
{
+ mouseInside = true;
XOnMouseEnter(localx, localy);
}
void Panel::OnMouseLeave(int localx, int localy)
{
+ mouseInside = false;
XOnMouseLeave(localx, localy);
}
@@ -267,13 +329,13 @@ void Panel::OnMouseUnclick(int localx, int localy, unsigned button)
if(!children[i]->Locked)
{
//is mouse inside?
- if( localx >= children[i]->Position.X &&
- localy >= children[i]->Position.Y &&
- localx < children[i]->Position.X + children[i]->Size.X &&
- localy < children[i]->Position.Y + children[i]->Size.Y )
+ if( localx >= children[i]->Position.X + ViewportPosition.X &&
+ localy >= children[i]->Position.Y + ViewportPosition.Y &&
+ localx < children[i]->Position.X + ViewportPosition.X + children[i]->Size.X &&
+ localy < children[i]->Position.Y + ViewportPosition.Y + children[i]->Size.Y )
{
childunclicked = true;
- children[i]->OnMouseUnclick(localx - children[i]->Position.X, localy - children[i]->Position.Y, button);
+ children[i]->OnMouseUnclick(localx - children[i]->Position.X - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, button);
break;
}
}
@@ -302,7 +364,7 @@ void Panel::OnMouseWheel(int localx, int localy, int d)
for(int i = 0; i < children.size(); ++i)
{
if(!children[i]->Locked)
- children[i]->OnMouseWheel(localx - children[i]->Position.X, localy - children[i]->Position.Y, d);
+ children[i]->OnMouseWheel(localx - children[i]->Position.X - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, d);
}
}
@@ -316,12 +378,12 @@ void Panel::OnMouseWheelInside(int localx, int localy, int d)
if(!children[i]->Locked)
{
//is mouse inside?
- if( localx >= children[i]->Position.X &&
- localy >= children[i]->Position.Y &&
- localx < children[i]->Position.X + children[i]->Size.X &&
- localy < children[i]->Position.Y + children[i]->Size.Y )
+ if( localx >= children[i]->Position.X + ViewportPosition.X &&
+ localy >= children[i]->Position.Y + ViewportPosition.Y &&
+ localx < children[i]->Position.X + ViewportPosition.X + children[i]->Size.X &&
+ localy < children[i]->Position.Y + ViewportPosition.Y + children[i]->Size.Y )
{
- children[i]->OnMouseWheelInside(localx - children[i]->Position.X, localy - children[i]->Position.Y, d);
+ children[i]->OnMouseWheelInside(localx - children[i]->Position.X - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, d);
break;
}
}
diff --git a/src/interface/Panel.h b/src/interface/Panel.h
index a5d80e3..cfeace3 100644
--- a/src/interface/Panel.h
+++ b/src/interface/Panel.h
@@ -6,6 +6,12 @@
#include "interface/Window.h"
#include "interface/Component.h"
+#ifdef OGLI
+#include "graphics/OpenGLHeaders.h"
+#endif
+
+
+class Graphics;
namespace ui
{
/* class XComponent
@@ -15,15 +21,22 @@ namespace ui
*
* See sys::Component
*/
+
class Component;
class Panel : public Component
{
public:
friend class Component;
- Panel(Window* parent_state);
+#ifdef OGLI
+ GLuint myVid, myVidTex;
+#else
+ pixel * myVid;
+#endif
+ ui::Point InnerSize;
+ ui::Point ViewportPosition;
+
Panel(Point position, Point size);
- Panel();
virtual ~Panel();
/* Add a child component.
@@ -65,6 +78,7 @@ class Component;
protected:
// child components
std::vector<ui::Component*> children;
+ bool mouseInside;
//UI functions:
/*
diff --git a/src/interface/ScrollPanel.cpp b/src/interface/ScrollPanel.cpp
new file mode 100644
index 0000000..36ce5f8
--- /dev/null
+++ b/src/interface/ScrollPanel.cpp
@@ -0,0 +1,117 @@
+#include <iostream>
+#include "ScrollPanel.h"
+
+using namespace ui;
+
+ScrollPanel::ScrollPanel(Point position, Point size):
+ Panel(position, size),
+ maxOffset(0, 0),
+ offsetX(0),
+ offsetY(0),
+ yScrollVel(0.0f),
+ xScrollVel(0.0f),
+ scrollBarWidth(0)
+{
+
+}
+
+int ScrollPanel::GetScrollLimit()
+{
+ if(maxOffset.Y == -ViewportPosition.Y)
+ return 1;
+ else if(ViewportPosition.Y == 0)
+ return -1;
+ return 0;
+}
+
+void ScrollPanel::XOnMouseWheelInside(int localx, int localy, int d)
+{
+ if(!d)
+ return;
+ yScrollVel -= d;
+}
+
+void ScrollPanel::XDraw(const Point& screenPos)
+{
+ Graphics * g = ui::Engine::Ref().g;
+
+ //Vertical scroll bar
+ if(maxOffset.Y>0 && InnerSize.Y>0)
+ {
+ float scrollHeight = float(Size.Y)*(float(Size.Y)/float(InnerSize.Y));
+ float scrollPos = 0;
+ if(-ViewportPosition.Y>0)
+ {
+ scrollPos = float(Size.Y-scrollHeight)*(float(offsetY)/float(maxOffset.Y));
+ }
+
+ g->fillrect(screenPos.X+(Size.X-scrollBarWidth), screenPos.Y, scrollBarWidth, Size.Y, 255, 255, 255, 55);
+ g->fillrect(screenPos.X+(Size.X-scrollBarWidth), screenPos.Y+scrollPos, scrollBarWidth, scrollHeight, 255, 255, 255, 255);
+ }
+}
+
+void ScrollPanel::XTick(float dt)
+{
+ if(yScrollVel > 7.0f) yScrollVel = 7.0f;
+ if(yScrollVel < -7.0f) yScrollVel = -7.0f;
+ if(yScrollVel > -0.5f && yScrollVel < 0.5)
+ yScrollVel = 0;
+
+ if(xScrollVel > 7.0f) xScrollVel = 7.0f;
+ if(xScrollVel < -7.0f) xScrollVel = -7.0f;
+ if(xScrollVel > -0.5f && xScrollVel < 0.5)
+ xScrollVel = 0;
+
+ maxOffset = InnerSize-Size;
+
+ int oldOffsetY = offsetY;
+ offsetY += yScrollVel;
+ int oldOffsetX = offsetX;
+ offsetX += xScrollVel;
+
+ yScrollVel*=0.99f;
+ xScrollVel*=0.99f;
+
+ if(oldOffsetY!=int(offsetY))
+ {
+ if(offsetY<0)
+ {
+ offsetY = 0;
+ yScrollVel = 0;
+ //commentsBegin = true;
+ //commentsEnd = false;
+ }
+ else if(offsetY>maxOffset.Y)
+ {
+ offsetY = maxOffset.Y;
+ yScrollVel = 0;
+ //commentsEnd = true;
+ //commentsBegin = false;
+ }
+ else
+ {
+ //commentsEnd = false;
+ //commentsBegin = false;
+ }
+ ViewportPosition.Y = -offsetY;
+ }
+ else
+ {
+ if(offsetY<0)
+ {
+ offsetY = 0;
+ yScrollVel = 0;
+ ViewportPosition.Y = -offsetY;
+ }
+ else if(offsetY>maxOffset.Y)
+ {
+ offsetY = maxOffset.Y;
+ ViewportPosition.Y = -offsetY;
+ }
+ }
+
+ if(mouseInside && scrollBarWidth < 6)
+ scrollBarWidth++;
+ else if(!mouseInside && scrollBarWidth > 0)
+ scrollBarWidth--;
+} \ No newline at end of file
diff --git a/src/interface/ScrollPanel.h b/src/interface/ScrollPanel.h
new file mode 100644
index 0000000..ae2a4ce
--- /dev/null
+++ b/src/interface/ScrollPanel.h
@@ -0,0 +1,25 @@
+#pragma once
+
+#include "Panel.h"
+
+namespace ui
+{
+ class ScrollPanel: public Panel
+ {
+ protected:
+ int scrollBarWidth;
+ Point maxOffset;
+ float offsetX;
+ float offsetY;
+ float yScrollVel;
+ float xScrollVel;
+ public:
+ ScrollPanel(Point position, Point size);
+
+ int GetScrollLimit();
+
+ virtual void XDraw(const Point& screenPos);
+ virtual void XTick(float dt);
+ virtual void XOnMouseWheelInside(int localx, int localy, int d);
+ };
+} \ No newline at end of file