diff --git a/screenshot/shipyard_view_w_vidlink_and_vscroll.png b/screenshot/shipyard_view_w_vidlink_and_vscroll.png new file mode 100644 index 0000000..76cf8d1 Binary files /dev/null and b/screenshot/shipyard_view_w_vidlink_and_vscroll.png differ diff --git a/src/gui_container.cpp b/src/gui_container.cpp index e3bc856..18e1bfe 100644 --- a/src/gui_container.cpp +++ b/src/gui_container.cpp @@ -7,6 +7,10 @@ Container::Container(void) { onMouseLeave.connect(sigc::mem_fun(this, &Container::_OnMouseLeave)); } +Container::~Container(void) { + DeleteAllChildren(); +} + void Container::_OnMouseLeave(void) { for(std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { if((*i).w->IsMouseOver() == true) diff --git a/src/gui_container.h b/src/gui_container.h index 8d55051..f34da48 100644 --- a/src/gui_container.h +++ b/src/gui_container.h @@ -8,6 +8,7 @@ namespace Gui { class Container : public Widget { public: Container(void); + virtual ~Container(void); bool OnMouseDown(MouseButtonEvent* e); bool OnMouseUp(MouseButtonEvent* e); bool OnMouseMotion(MouseMotionEvent* e); diff --git a/src/gui_screen.cpp b/src/gui_screen.cpp index 66775ca..c5ab115 100644 --- a/src/gui_screen.cpp +++ b/src/gui_screen.cpp @@ -35,6 +35,7 @@ void Screen::Init(int real_width, int real_height, int ui_width, int ui_height) Screen::fontScale = 1.0/fontscale; Screen::baseContainer = new Gui::Fixed(Screen::width, Screen::height); Screen::baseContainer->SetPosition(0,0); + Screen::baseContainer->Show(); } GLint Screen::Project(GLdouble objX, GLdouble objY, GLdouble objZ, const GLdouble* model, @@ -77,6 +78,10 @@ void Screen::Draw(void) { LeaveOrtho(); } +bool Screen::IsBaseWidget(const Widget* w) { + return w == static_cast(baseContainer); +} + void Screen::AddBaseWidget(Widget* w, int x, int y) { baseContainer->Add(w, x, y); } @@ -217,5 +222,9 @@ void Screen::AddShortcutWidget(Widget* w) { kbshortcut_widgets.push_back(w); } +void Screen::RemoveShortcutWidget(Widget* w) { + kbshortcut_widgets.remove(w); +} + } diff --git a/src/gui_screen.h b/src/gui_screen.h index 3a8a26a..50abf65 100644 --- a/src/gui_screen.h +++ b/src/gui_screen.h @@ -32,6 +32,8 @@ namespace Gui { const GLdouble* proj, const GLint* view, GLdouble* winX, GLdouble* winY, GLdouble* winZ); friend void Widget::SetShortcut(SDLKey key, SDLMod mod); + friend Widget::~Widget(void); + static bool IsBaseWidget(const Widget*); private: struct LabelPos { LabelPos(float _x, float _y) : x(_x), y(_y) {} @@ -42,6 +44,7 @@ namespace Gui { static void OnClickTestLabels(const Gui::MouseButtonEvent& ev); static bool CanPutLabel(float x, float y); static void AddShortcutWidget(Widget* w); + static void RemoveShortcutWidget(Widget* w); static void SDLEventCoordToScreenCoord(int sdlev_x, int sdlev_y, float* x, float* y); static bool init; diff --git a/src/gui_widget.cpp b/src/gui_widget.cpp index 7dd9ccd..d191f9e 100644 --- a/src/gui_widget.cpp +++ b/src/gui_widget.cpp @@ -9,6 +9,21 @@ Widget::Widget(void) { m_eventMask = EVENT_NONE; m_tooltipWidget = 0; m_tooltipTimerSignal.connect(sigc::mem_fun(this, &Widget::OnToolTip)); + m_shortcut.sym = (SDLKey)0; + m_shortcut.mod = (SDLMod)0; +} + +bool Widget::IsVisible(void) const { + if(!m_visible) return false; + Container* parent = m_parent; + while((parent) && (parent->m_parent)) { + if(parent->m_visible == false) return false; + parent = parent->m_parent; + } + if(Screen::IsBaseWidget(parent)) + return parent->m_visible; + else + return false; } void Widget::SetClipping(float width, float height) { @@ -35,7 +50,13 @@ void Widget::EndClipping(void) { glDisable(GL_CLIP_PLANE3); } -void Widget::SetShortcut(SDLKey key, SDLMod mod) { +void Widget::SetShortcut(SDLKey key, SDLMod mod) {a + /* + * Because AddShortcut will add more than once. Fix this otherwise + * on destruct we leave bad pointers in the + * Screen shortcut widgets lists. + */ + assert(m_shortcut.sym == 0); m_shortcut.sym = key; m_shortcut.mod = mod; Screen::AddShortcutWidget(this); @@ -122,6 +143,8 @@ Widget::~Widget(void) { Screen::RemoveBaseWidget(m_tooltipWidget); delete m_tooltipWidget; } + Screen::RemoveShortcutWidget(this); + Gui::RemoveTimer(&m_tooltipTimerSignal); } } diff --git a/src/gui_widget.h b/src/gui_widget.h index 66d2cf4..5fa4169 100644 --- a/src/gui_widget.h +++ b/src/gui_widget.h @@ -25,7 +25,7 @@ namespace Gui { void EndClipping(void); virtual void Show(void) { m_visible = true; } virtual void Hide(void); - bool IsVisible(void) { return m_visible; } + bool IsVisible(void) const; Container* GetParent(void) const { return m_parent; } void SetParent(Container* p) { m_parent = p; } void SetToolTip(std::string s) { m_tooltip = s; } diff --git a/src/ship.cpp b/src/ship.cpp index 54393b1..2a82f2e 100644 --- a/src/ship.cpp +++ b/src/ship.cpp @@ -392,6 +392,8 @@ void Ship::SetDockedWith(SpaceStation* s, int port) { Enable(); m_dockedWith = 0; + } else if(!s) { + } else { m_dockedWith = s; m_dockedWithPort = port; diff --git a/src/space_station_view.cpp b/src/space_station_view.cpp index b6e81e8..1ced1c4 100644 --- a/src/space_station_view.cpp +++ b/src/space_station_view.cpp @@ -3,6 +3,89 @@ #include "player.h" #include "world_view.h" +#define TEXSIZE 128 +#define ADD_VIDEO_WIDGET Add(new DeadVideoLink(295, 285), 5, 40) + +class DeadVideoLink: public Gui::Widget { +public: + void PutRandomCrapIntoTexture(void) { + int* randcrap = (int*)alloca(TEXSIZE*TEXSIZE); + for(unsigned int i = < 0; i < TEXSIZE*TEXSIZE/sizeof(int); i++) randcrap[i] = (L3D::rng.Int32() & 0xfcfcfcfc) >> 2; + glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, TEXSIZE, TEXSIZE, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, randcrap); + } + DeadVideoLink(float w, float h) { + m_w = w; m_h = h; + m_created = SDL_GetTicks(); + m_message = new Gui::Tooltip("Video link down"); + glEnable(GL_TEXTURE_2D); + glGenTextures(1, &m_tex); + PutRandomCrapIntoTexture(); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glDisable(GL_TEXTURE_2D); + } + virtual ~DeadVideoLink(void) { + delete m_message; + } + virtual void Draw(void) { + float size[2]; GetSize(size); + if(SDL_GetTicks() - m_created < 1500) { + m_message->SetText("Connecting..."); + glBegin(GL_QUADS); + glColor3f(0,0,0); + glVertex2f(0,0); + glVertex2f(0, size[1]); + glVertex2f(size[0], sizep[1]); + glVertex2f(size[0], 0); + glEnd(); + DrawMessage(); + } else { + m_message->SetText("Video link down"); + + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, m_tex); + PutRandomCrapIntoTexture(); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glBegin(GL_QUADS); + glColor3f(0,0,0); + glTexCoord2f(0,0); + glVertex2f(0,0); + glTexCoord2f(0, 1); + glVertex2f(0, size[1]); + glTexCoord2f(1,1); + glVertex2f(size[0], size[1]); + glTexCoord2f(1,0); + glVertex2f(size[0], 0); + glEnd(); + glDisable(GL_TEXTURE_2D); + if(SDL_GetTicks() & 0x400) { + DrawMessage(); + } + } + } + virtual void GetSizeRequested(float size[2]) { + size[0] = m_w; + size[1] = m_h; + } +private: + void DrawMessage(void) { + float size[2]; + float msgSize[2]; + GetSize(size); + m_message->GetSize(msgSize); + glPushMatrix(); + glTranslatef(size[0]*0.5-msgSize[0]*0.5, size[1]*0.5-msgSize[1]*0.5, 0); + m_message->Draw(); + glPopMatrix(); + } + Uint32 m_created; + GLuint m_tex; + float m_w, m_h; + Gui::ToolTip* m_message; +} + class StationSubView: public Gui::Fixed { public: StationSubView(SpaceStationView* parent): Gui::Fixed(Gui::Screen::GetWidth(), Gui::Screen::GetHeight()-64) { @@ -16,6 +99,7 @@ protected: class StationFrontView: public StationSubView { public: StationFrontView(SpaceStationView* parent); + virtual void ShowAll(void); private: void OnClickRequestLaunch(void) { L3D::player->SetDockedWith(0,0); @@ -30,7 +114,18 @@ private: StationFrontView::StationFrontView(SpaceStationView* parent): StationSubView(parent) { SetTransparency(false); +} +void StationFrontView::ShowAll(void) { + DeleteAllChildren(); + SpaceStation* station = L3D::player->GetDockedWith(); + + if(!station) return; + { + char buf[256]; + snprintf(buf, sizeof(buf), "Welcome to %s", station->GetLabel().c_str()); + Add(new Gui::Label(buf), 10, 10); + } Gui::Label* l = new Gui::Label("Hello friend! Thankyou for docking with this space station! " "You may have noticed that the docking procedure was not entirely " "physically correct. this is a result of unimplemented physics in this " @@ -42,22 +137,28 @@ StationFrontView::StationFrontView(SpaceStationView* parent): StationSubView(par " ADOPT A CAT: THEY CHEW IMPORTANT CABLES!"); - Gui::Fixed* fbox = new Gui::Fixed(720, 400); + Gui::Fixed* fbox = new Gui::Fixed(450, 400); fbox->Add(l, 0, 0); - Add(fbox, 40, 100); + Add(fbox, 320, 40); fbox->ShowAll(); Gui::SolidButton* b = new Gui::SolidButton(); + b->SetShortcut(SDLK_1, KMOD_NONE); b->onClick.connect(sigc::mem_fun(this, &StationFrontView::OnClickRequestLaunch)); - Add(b, 40, 300); + Add(b, 340, 240); l = new Gui::Label("Request Launch"); - Add(l, 65, 300); + Add(l, 365, 240); b = new Gui::SolidButton(); + b->SetShortcut(SDLK_2, KMOD_NONE); b->onClick.connect(sigc::mem_fun(this, &StationFrontView::OnClickGotoShipYard)); - Add(b, 40, 360); + Add(b, 340, 300); l = new Gui::Label("Shipyard"); - Add(l, 65, 360); + Add(l, 365, 300); + + ADD_VIDEO_WIDGET; + + Gui::Fixed::ShowAll(); } /**********************************************************/ @@ -78,9 +179,14 @@ void StationShipyardView::ShowAll(void) { SpaceStation* station = L3D::player->GetDockedWith(); assert(station); SetTransparency(false); + { + char buf[256]; + snprintf(buf, sizeof(buf), "Welcome to %s shipyard", station->GetLabel().c_str()); + Add(new Gui::Label(buf), 10, 10); + } - Gui::Fixed* fbox = new Gui::Fixed(500, 200); - Add(fbox, 300, 100); + Gui::Fixed* fbox = new Gui::Fixed(470, 200); + Add(fbox, 320, 40); Gui::VScrollBar* scroll = new Gui::VScrollBar(); Gui::VScrollPortal* portal = new Gui::VScrollPortal(450, 200); @@ -120,6 +226,7 @@ void StationShipyardView::ShowAll(void) { portal->Add(innerbox); portal->ShowAll(); fbox->ShowAll(); + ADD_VIDEO_WIDGET; Gui::Fixed::ShowAll();