#pragma once #include //#include "Platform.h" #include "interface/Panel.h" #include "interface/Point.h" #include "interface/Window.h" #include "interface/Component.h" #include "graphics/Graphics.h" using namespace ui; Panel::Panel(Point position, Point size): 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() { for(unsigned i = 0; i < children.size(); ++i) { 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() { return children.size(); } Component* Panel::GetChild(unsigned idx) { return children[idx]; } void Panel::RemoveChild(Component* c) { for(int i = 0; i < children.size(); ++i) { if(children[i] == c) { //remove child from parent. Does not free memory children.erase(children.begin() + i); break; } } } void Panel::RemoveChild(unsigned idx, bool freeMem) { if(freeMem) delete children[idx]; children.erase(children.begin() + idx); } 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) { // the component must be visible if(children[i]->Visible) { //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() ) { Point scrpos = /*screenPos + */children[i]->Position + ViewportPosition; 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*(XRES+BARSIZE)), myVid+(row*(XRES+BARSIZE))+Size.X, lastVid+((screenPos.Y+row)*(XRES+BARSIZE))+screenPos.X); } #endif } void Panel::Tick(float dt) { // tick ourself first XTick(dt); // tick our children for(unsigned i = 0; i < children.size(); ++i) children[i]->Tick(dt); } void Panel::OnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) { XOnKeyPress(key, character, shift, ctrl, alt); } void Panel::OnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bool alt) { XOnKeyRelease(key, character, shift, ctrl, alt); } void Panel::OnMouseClick(int localx, int localy, unsigned button) { bool childclicked = false; //check if clicked a child for(int i = children.size()-1; i >= 0 ; --i) { //child must be unlocked if(!children[i]->Locked) { //is mouse inside? 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 - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, button); break; } } } //if a child wasn't clicked, send click to ourself if(!childclicked) { XOnMouseClick(localx, localy, button); GetParentWindow()->FocusComponent(this); } } void Panel::OnMouseDown(int x, int y, unsigned button) { XOnMouseDown(x, y, button); for(int i = 0; i < children.size(); ++i) { if(!children[i]->Locked) children[i]->OnMouseDown(x, y, button); } } void Panel::OnMouseHover(int localx, int localy) { // check if hovering on children for(int i = children.size() - 1; i >= 0; --i) { if(!children[i]->Locked) { 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 ) { children[i]->OnMouseHover(localx - children[i]->Position.X, localy - children[i]->Position.Y); break; } } } // always allow hover on parent (?) XOnMouseHover(localx, localy); } void Panel::OnMouseMoved(int localx, int localy, int dx, int dy) { XOnMouseMoved(localx, localy, dx, dy); for(int i = 0; i < children.size(); ++i) { if(!children[i]->Locked) children[i]->OnMouseMoved(localx - children[i]->Position.X - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, dx, dy); } } void Panel::OnMouseMovedInside(int localx, int localy, int dx, int dy) { for(int i = 0; i < children.size(); ++i) { if(!children[i]->Locked) { 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? if( local.X >= 0 && local.Y >= 0 && local.X < children[i]->Size.X && local.Y < children[i]->Size.Y ) { 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 && prevlocal.Y >= 0 && prevlocal.X < children[i]->Size.X && prevlocal.Y < children[i]->Size.Y ) ) { children[i]->OnMouseEnter(local.X, local.Y); } } // if not currently inside else { // was the mouse inside? if( prevlocal.X >= 0 && prevlocal.Y >= 0 && prevlocal.X < children[i]->Size.X && prevlocal.Y < children[i]->Size.Y ) { children[i]->OnMouseLeave(local.X, local.Y); } } } } // always allow hover on parent (?) XOnMouseMovedInside(localx, localy, dx, 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); } void Panel::OnMouseUnclick(int localx, int localy, unsigned button) { bool childunclicked = false; //check if clicked a child for(int i = children.size()-1; i >= 0 ; --i) { //child must be unlocked if(!children[i]->Locked) { //is mouse inside? 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 - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, button); break; } } } //if a child wasn't clicked, send click to ourself if(!childunclicked) { XOnMouseUnclick(localx, localy, button); } } void Panel::OnMouseUp(int x, int y, unsigned button) { XOnMouseUp(x, y, button); for(int i = 0; i < children.size(); ++i) { if(!children[i]->Locked) children[i]->OnMouseUp(x, y, button); } } void Panel::OnMouseWheel(int localx, int localy, int d) { XOnMouseWheel(localx, localy, d); for(int i = 0; i < children.size(); ++i) { if(!children[i]->Locked) children[i]->OnMouseWheel(localx - children[i]->Position.X - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, d); } } void Panel::OnMouseWheelInside(int localx, int localy, int d) { XOnMouseWheelInside(localx, localy, d); //check if clicked a child for(int i = children.size()-1; i >= 0 ; --i) { //child must be unlocked if(!children[i]->Locked) { //is mouse inside? 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 - ViewportPosition.X, localy - children[i]->Position.Y - ViewportPosition.Y, d); break; } } } } // ***** OVERRIDEABLES ***** // Kept empty. void Panel::XDraw(const Point& screenPos) { } void Panel::XTick(float dt) { } void Panel::XOnKeyPress(int key, Uint16 character, bool shift, bool ctrl, bool alt) { } void Panel::XOnKeyRelease(int key, Uint16 character, bool shift, bool ctrl, bool alt) { } void Panel::XOnMouseClick(int localx, int localy, unsigned button) { } void Panel::XOnMouseDown(int x, int y, unsigned button) { } void Panel::XOnMouseHover(int localx, int localy) { } void Panel::XOnMouseMoved(int localx, int localy, int dx, int dy) { } void Panel::XOnMouseMovedInside(int localx, int localy, int dx, int dy) { } void Panel::XOnMouseEnter(int localx, int localy) { } void Panel::XOnMouseLeave(int localx, int localy) { } void Panel::XOnMouseUnclick(int localx, int localy, unsigned button) { } void Panel::XOnMouseUp(int x, int y, unsigned button) { } void Panel::XOnMouseWheel(int localx, int localy, int d) { } void Panel::XOnMouseWheelInside(int localx, int localy, int d) { }