diff options
| author | Simon 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) |
| commit | f8ca8af387b8611c18ca7c5357efd19c8bc28941 (patch) | |
| tree | fe790e2abede326949bb299b564ba8e75a979ecf /src/interface | |
| parent | 121e7c772cfc7b3e1305a03144264fc5b66564c2 (diff) | |
| download | powder-f8ca8af387b8611c18ca7c5357efd19c8bc28941.zip powder-f8ca8af387b8611c18ca7c5357efd19c8bc28941.tar.gz | |
Scroll Panel
Diffstat (limited to 'src/interface')
| -rw-r--r-- | src/interface/Component.h | 2 | ||||
| -rw-r--r-- | src/interface/Panel.cpp | 160 | ||||
| -rw-r--r-- | src/interface/Panel.h | 18 | ||||
| -rw-r--r-- | src/interface/ScrollPanel.cpp | 117 | ||||
| -rw-r--r-- | src/interface/ScrollPanel.h | 25 |
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 |
