diff --git a/src/generic_system_view.cpp b/src/generic_system_view.cpp index 1a3df94..fad687f 100644 --- a/src/generic_system_view.cpp +++ b/src/generic_system_view.cpp @@ -5,8 +5,9 @@ GenericSystemView::GenericSystemView(void) : View() { px = py = pidx = 0xdeadbeef; - m_scannerLayout = new Gui::Fixed(140, 2, 360, 60); + m_scannerLayout = new Gui::Fixed(360, 60); m_scannerLayout->SetTransparency(true); + Gui::Screen::AddBaseWidget(m_scannerLayout, 140, 2); m_systemName = new Gui::Label(""); m_systemName->SetColor(1, 1, 0); diff --git a/src/glfreetype.cpp b/src/glfreetype.cpp index a5a1a3a..cb0b556 100644 --- a/src/glfreetype.cpp +++ b/src/glfreetype.cpp @@ -299,6 +299,36 @@ void FontFace::RenderString(const char* str) { glPopMatrix(); } +/* 'Markup' indeed. #rgb hex is change colour, no sensible escape. */ +void FontFace::RenderMarkup(const char* str) { + glPushMatrix(); + int len = strlen(str); + for(unsigned int i = 0; i < len; i++) { + if(str[i] == '#') { + int hexcol; + if(sscanf(str+i, "#%3x", &hexcol)==1) { + Uint8 col[3]; + col[0] = (hexcol&0xf00)>>4; + col[1] = (hexcol&0xf0); + col[2] = (hexcol&0xf)<<4; + glColor3ubv(col); + i+=3; + continue; + } + } + if(str[i] == '\n') { + glPopMatrix(); + glTranslatef(0, -m_height, 0); + glPushMatrix(); + } else { + glfglyph_t* glyph = &m_glyphs[str[i]]; + if(glyph->numidx) RenderGlyph(str[i]); + glTranslatef(glyph->advx, 0, 0); + } + } + glPopMatrix(); +} + FontFace::FontFace(const char* filename_ttf) { FT_Face face; if(0 != FT_New_Face(library, filename_ttf, 0, &face)) { diff --git a/src/glfreetype.h b/src/glfreetype.h index 7e1074a..52fb433 100644 --- a/src/glfreetype.h +++ b/src/glfreetype.h @@ -7,6 +7,7 @@ public: FontFace(const char* filename_ttf); void RenderGlyph(int chr); void RenderString(const char* str); + void RenderMarkup(const char* str); /* Of Ms. */ float GetHeight(void) { return m_height; } diff --git a/src/gui_button.cpp b/src/gui_button.cpp index 05c22a0..278fc6a 100644 --- a/src/gui_button.cpp +++ b/src/gui_button.cpp @@ -11,20 +11,22 @@ Button::Button(void) { SetSize(BUTTON_SIZE, BUTTON_SIZE); } -void Button::OnMouseDown(MouseButtonEvent* e) { +bool Button::OnMouseDown(MouseButtonEvent* e) { if(e->button == 1) { m_isPressed = true; onPress.emit(); /* Wait for mouse release, regardless of where on screen. */ _m_release = RawEvents::onMouseUp.connect(sigc::mem_fun(this, &Button::OnRawMouseUp)); } + return false; } -void Button::OnMouseUp(MouseButtonEvent* e) { +bool Button::OnMouseUp(MouseButtonEvent* e) { if((e->button == 1) && m_isPressed) { m_isPressed = false; onClick.emit(); } + return false; } void Button::OnActivate(void) { diff --git a/src/gui_button.h b/src/gui_button.h index d8b3031..b85ebca 100644 --- a/src/gui_button.h +++ b/src/gui_button.h @@ -7,8 +7,8 @@ namespace Gui { public: Button(void); virtual ~Button(void) {} - virtual void OnMouseDown(MouseButtonEvent* e); - virtual void OnMouseUp(MouseButtonEvent* e); + virtual bool OnMouseDown(MouseButtonEvent* e); + virtual bool OnMouseUp(MouseButtonEvent* e); virtual void OnActivate(void); /* diff --git a/src/gui_container.cpp b/src/gui_container.cpp index a897783..977671d 100644 --- a/src/gui_container.cpp +++ b/src/gui_container.cpp @@ -3,7 +3,8 @@ namespace Gui { -void Container::HandleMouseEvent(MouseButtonEvent* e) { + +bool Container::HandleMouseEvent(MouseButtonEvent* e) { float x = e->x; float y = e->y; for(std::list::iterator i = m_children.begin(); i != m_children.end(); ++i) { @@ -22,13 +23,16 @@ void Container::HandleMouseEvent(MouseButtonEvent* e) { (y >= pos[1]) && (y < pos[1]+size[1])) { e->x = x-pos[0]; e->y = y-pos[1]; + bool alive; if(e->isdown) { - (*i).w->OnMouseDown(e); + alive = (*i).w->OnMouseDown(e); } else { - (*i).w->OnMouseUp(e); + alive = (*i).w->OnMouseUp(e); } + if(!alive) return false; } } + return true; } void Container::DeleteAllChildren(void) { @@ -66,12 +70,12 @@ void Container::Draw(void) { } } -void Container::OnMouseDown(MouseButtonEvent* e) { - HandleMouseEvent(e); +bool Container::OnMouseDown(MouseButtonEvent* e) { + return HandleMouseEvent(e); } -void Container::OnMouseUp(MouseButtonEvent* e) { - HandleMouseEvent(e); +bool Container::OnMouseUp(MouseButtonEvent* e) { + return HandleMouseEvent(e); } void Container::ShowAll(void) { diff --git a/src/gui_container.h b/src/gui_container.h index 50e6734..982c15f 100644 --- a/src/gui_container.h +++ b/src/gui_container.h @@ -7,14 +7,14 @@ namespace Gui { class Container : public Widget { public: - void OnMouseDown(MouseButtonEvent* e); - void OnMouseUp(MouseButtonEvent* e); + bool OnMouseDown(MouseButtonEvent* e); + bool OnMouseUp(MouseButtonEvent* e); void DeleteAllChildren(void); virtual void Draw(void); virtual void ShowAll(void); virtual void HideAll(void); private: - void HandleMouseEvent(MouseButtonEvent* e); + bool HandleMouseEvent(MouseButtonEvent* e); protected: void PrependChild(Widget* w, float x, float y); void AppendChild(Widget* w, float x, float y); diff --git a/src/gui_events.h b/src/gui_events.h index 2ab060c..5da523e 100644 --- a/src/gui_events.h +++ b/src/gui_events.h @@ -3,7 +3,8 @@ namespace Gui { struct MouseButtonEvent { Uint8 isdown; Uint8 button; - float x, y; + float x, y; /* Widget coords. */ + float screenX, screenY; /* Screen coords. */ }; } diff --git a/src/gui_fixed.cpp b/src/gui_fixed.cpp index a58706e..0805e1c 100644 --- a/src/gui_fixed.cpp +++ b/src/gui_fixed.cpp @@ -4,14 +4,12 @@ namespace Gui { -Fixed::Fixed(float x, float y, float w, float h) { - SetPosition(x, y); +Fixed::Fixed(float w, float h) { SetSize(w, h); memcpy(m_bgcol, Color::bg, 3*sizeof(float)); m_w = w; m_h = h; m_transparent = false; m_eventMask = EVENT_ALL; - Screen::AddBaseWidget(this); } void Fixed::GetSizeRequested(float size[2]) { diff --git a/src/gui_fixed.h b/src/gui_fixed.h index 8544ece..b69b9c6 100644 --- a/src/gui_fixed.h +++ b/src/gui_fixed.h @@ -7,7 +7,7 @@ namespace Gui { class Fixed : public Container { public: - Fixed(float x, float y, float w, float h); + Fixed(float w, float h); void Add(Widget* child, float x, float y); void Remove(Widget* child); virtual void Draw(void); diff --git a/src/gui_label.cpp b/src/gui_label.cpp index 6f59633..9587776 100644 --- a/src/gui_label.cpp +++ b/src/gui_label.cpp @@ -22,7 +22,7 @@ void Label::SetText(std::string& text) { void Label::Draw(void) { glColor3fv(m_color); - Screen::RenderString(m_text); + Screen::RenderMarkup(m_text); } void Label::GetSizeRequested(float size[2]) { diff --git a/src/gui_radio_button.cpp b/src/gui_radio_button.cpp index f80852c..975d962 100644 --- a/src/gui_radio_button.cpp +++ b/src/gui_radio_button.cpp @@ -15,9 +15,10 @@ RadioButton::~RadioButton(void) { } -void RadioButton::OnMouseDown(MouseButtonEvent* e) { +bool RadioButton::OnMouseDown(MouseButtonEvent* e) { onPress.emit(); OnActivate(); + return false; } void RadioButton::OnActivate(void) { diff --git a/src/gui_radio_button.h b/src/gui_radio_button.h index 5febb17..a151f24 100644 --- a/src/gui_radio_button.h +++ b/src/gui_radio_button.h @@ -14,7 +14,7 @@ namespace Gui { virtual ~RadioButton(); virtual void Draw(); virtual void GetSizeRequested(float &w, float &h); - virtual void OnMouseDown(MouseButtonEvent *e); + virtual bool OnMouseDown(MouseButtonEvent *e); virtual void OnActivate(); virtual void SetSelected(bool state) { m_pressed = state; } bool GetSelected() { return m_pressed; } diff --git a/src/gui_screen.cpp b/src/gui_screen.cpp index 693c09a..af14297 100644 --- a/src/gui_screen.cpp +++ b/src/gui_screen.cpp @@ -79,7 +79,8 @@ void Screen::Draw(void) { LeaveOrtho(); } -void Screen::AddBaseWidget(Widget* w) { +void Screen::AddBaseWidget(Widget* w, int x, int y) { + w->SetPosition(x, y); Screen::widgets.push_back(w); } @@ -97,6 +98,8 @@ void Screen::OnClick(SDL_MouseButtonEvent* e) { ev.isdown = (e->type == SDL_MOUSEBUTTONDOWN); ev.x = x; ev.y = y; + ev.screenX = x; + ev.screenY = y; OnClickTestLabels(ev); for(std::list::iterator i = Screen::widgets.begin(); i != Screen::widgets.end(); ++i) { float size[2], pos[2]; @@ -151,6 +154,13 @@ void Screen::RenderString(const std::string& s) { glPopMatrix(); } +void Screen::RenderMarkup(const std::string& s) { + glPushMatrix(); + glScalef(Screen::font_xsize, Screen::font_ysize, 1); + font->RenderMarkup(s.c_str()); + glPopMatrix(); +} + bool Screen::CanPutLabel(float x, float y) { for(std::vector::iterator i = labelPositions.begin(); i != labelPositions.end(); ++i) { if((fabs(x-(*i).x) < 5) && diff --git a/src/gui_screen.h b/src/gui_screen.h index ab72bcb..dad9894 100644 --- a/src/gui_screen.h +++ b/src/gui_screen.h @@ -9,11 +9,12 @@ namespace Gui { public: static void Init(int real_width, int real_height, int ui_width, int ui_height); static void Draw(void); - static void AddBaseWidget(Widget* w); + static void AddBaseWidget(Widget* w, int x, int y); static void RemoveBaseWidget(Widget* w); static void OnClick(SDL_MouseButtonEvent* e); static void OnKeyDown(const SDL_keysym* sym); static void RenderString(const std::string& s); + static void RenderMarkup(const std::string& s); static void PutClickableLabel(const std::string& s, float x, float y, sigc::slot slot); static void RenderLabel(const std::string& s, float x, float y); diff --git a/src/gui_toggle_button.cpp b/src/gui_toggle_button.cpp index 7321469..5c6a009 100644 --- a/src/gui_toggle_button.cpp +++ b/src/gui_toggle_button.cpp @@ -10,7 +10,7 @@ ToggleButton::ToggleButton(void) { SetSize(BUTTON_SIZE, BUTTON_SIZE); } -void ToggleButton::OnMouseDown(MouseButtonEvent* e) { +bool ToggleButton::OnMouseDown(MouseButtonEvent* e) { if(e->button == 1) { onPress.emit(); m_pressed = !m_pressed; @@ -20,6 +20,7 @@ void ToggleButton::OnMouseDown(MouseButtonEvent* e) { onDeselect.emit(this); } } + return false; } void ToggleButton::GetSizeRequested(float& w, float& h) { diff --git a/src/gui_toggle_button.h b/src/gui_toggle_button.h index 7020130..a5ca6e9 100644 --- a/src/gui_toggle_button.h +++ b/src/gui_toggle_button.h @@ -9,7 +9,7 @@ namespace Gui { virtual void Draw(void); virtual ~ToggleButton(void) {} virtual void GetSizeRequested(float& w, float& h); - virtual void OnMouseDown(MouseButtonEvent* e); + virtual bool OnMouseDown(MouseButtonEvent* e); void SetPressed(bool s) { m_pressed = s; } bool GetPressed(void) { return m_pressed; } diff --git a/src/gui_widget.h b/src/gui_widget.h index 71448fa..7be0b0d 100644 --- a/src/gui_widget.h +++ b/src/gui_widget.h @@ -20,8 +20,9 @@ namespace Gui { Container* GetParent(void) { return m_parent; } void SetParent(Container* p) { m_parent = p; } - virtual void OnMouseDown(MouseButtonEvent* e) {} - virtual void OnMouseUp(MouseButtonEvent* e) {} + /* Event handlers should return false to stop propagating event. */ + virtual bool OnMouseDown(MouseButtonEvent* e) { return false; } + virtual bool OnMouseUp(MouseButtonEvent* e) { return false; } virtual void OnActivate(void) {} /* Only to be called by Screen::OnKeyDown. */ void OnPreShortcut(const SDL_keysym* sym); diff --git a/src/main.cpp b/src/main.cpp index 1be50c3..15fd495 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -192,7 +192,7 @@ void L3D::MainLoop(void) { StarSystem s(0, 0, 0); HyperspaceTo(&s); - const float zpos = EARTH_RADIUS * 7; + const float zpos = EARTH_RADIUS * 1; Frame* pframe = *(Space::rootFrame->m_children.begin()); player->SetFrame(pframe); player->SetPosition(vector3d(0, zpos*0.1, zpos)); @@ -207,13 +207,11 @@ void L3D::MainLoop(void) { Space::AddBody(body); } - { - SpaceStation* body = new SpaceStation(); - body->SetLabel("Poemi-chan's Folly"); - body->SetFrame(pframe); - body->SetPosition(vector3d(5000, zpos*0.1, zpos-10000)); - Space::AddBody(body); - } + SpaceStation* station = new SpaceStation(); + station->SetLabel("Poemi-chan's Folly"); + station->SetFrame(pframe); + station->SetPosition(vector3d(5000, zpos*0.1, zpos-10000)); + Space::AddBody(station); Gui::Init(scrWidth, scrHeight, 640, 480); @@ -229,6 +227,7 @@ void L3D::MainLoop(void) { infoView = new InfoView(); SetView(world_view); + player->SetDockedWith(station); Uint32 last_stats = SDL_GetTicks(); int frame_stat = 0; diff --git a/src/object_viewer_view.h b/src/object_viewer_view.h index c2dfae7..f2dbfbb 100644 --- a/src/object_viewer_view.h +++ b/src/object_viewer_view.h @@ -11,7 +11,6 @@ public: virtual void Update(void); virtual void Draw3D(void); private: - virtual void OnMouseDown(Gui::MouseButtonEvent* e) { } matrix4x4d viewingRotation; float viewingDist; Gui::Label* m_infoLabel; diff --git a/src/ship.cpp b/src/ship.cpp index cc7a654..6a16b47 100644 --- a/src/ship.cpp +++ b/src/ship.cpp @@ -27,6 +27,7 @@ Ship::Ship(ShipType::Type shipType) : DynamicBody() { m_wheelTransition = 0; m_wheelState = 0; m_dockedWith = 0; + dockingTimer = 0; m_navTarget = 0; m_combatTarget = 0; m_shipType = shipType; @@ -83,6 +84,7 @@ void Ship::CalcStats(shipstats_t* stats) { } void Ship::TimeStepUpdate(const float timeStep) { + dockingTimer = (dockingTimer-timeStep > 0 ? dockingTimer-timeStep : 0); /* ODE tri mesh likes to know our old position. */ TriMeshUpdateLastPos(); const ShipType& stype = GetShipType(); @@ -163,6 +165,7 @@ void Ship::SetDockedWith(SpaceStation* s) { } else { m_dockedWith = s; + dockingTimer = 0.0f; SetVelocity(vector3d(0, 0, 0)); SetAngVelocity(vector3d(0, 0, 0)); } @@ -177,6 +180,16 @@ void Ship::SetWheelState(bool down) { else m_wheelTransition = -1; } +void Ship::SetNavTarget(Body* const target) { + m_navTarget = target; + L3D::world_view->UpdateCommsOptions(); +} + +void Ship::SetCombatTarget(Body* const target) { + m_combatTarget = target; + L3D::world_view->UpdateCommsOptions(); +} + /* Assumed to be at model coords. */ void Ship::RenderLaserfire(void) { const ShipType& stype = GetShipType(); diff --git a/src/ship.h b/src/ship.h index e38a6f8..5ffa422 100644 --- a/src/ship.h +++ b/src/ship.h @@ -20,9 +20,9 @@ public: virtual Object::Type GetType(void) { return Object::SHIP; } virtual void SetDockedWith(SpaceStation*); SpaceStation* GetDockedWith(void) { return m_dockedWith; } - void SetNavTarget(Body* const target) { m_navTarget = target; } + void SetNavTarget(Body* const target); Body* GetNavTarget(void) const { return m_navTarget; } - void SetCombatTarget(Body* const target) { m_combatTarget = target; } + void SetCombatTarget(Body* const target); Body* GetCombatTarget(void) const { return m_combatTarget; } virtual void Render(const Frame* camFrame); void SetThrusterState(enum ShipType::Thruster t, float level); @@ -33,6 +33,8 @@ public: void CalcStats(shipstats_t* stats); void UpdateMass(void); void SetWheelState(bool down); + float GetDockingTimer(void) { return dockingTimer; } + void SetDockingTimer(float t) { dockingTimer = t; } virtual void TimeStepUpdate(const float timeStep); virtual void NotifyDeath(const Body* const dyingBody); @@ -55,6 +57,7 @@ private: float m_thrusters[ShipType::THRUSTER_MAX]; float m_angThrusters[3]; + float dockingTimer; dGeomID m_tempLaserGeom[ShipType::GUNMOUNT_MAX]; LaserObj m_laserCollisionObj; diff --git a/src/ship_cpanel.cpp b/src/ship_cpanel.cpp index ee06ec5..d4fa6cf 100644 --- a/src/ship_cpanel.cpp +++ b/src/ship_cpanel.cpp @@ -5,8 +5,8 @@ #include "player.h" #include "info_view.h" -ShipCpanel::ShipCpanel(void) : Gui::Fixed(0, 0, 640, 64) { - //SetBgColor(1, 0, 0); +ShipCpanel::ShipCpanel(void) : Gui::Fixed(640, 64) { + Gui::Screen::AddBaseWidget(this, 0, 0); SetTransparency(true); Gui::Image* img = new Gui::Image("icons/cpanel.png"); @@ -77,12 +77,31 @@ ShipCpanel::ShipCpanel(void) : Gui::Fixed(0, 0, 640, 64) { m_clock = new Gui::Label(""); m_clock->SetColor(1, 0.7, 0); Add(m_clock, 2, 48); + + tempMsg = new Gui::Label(""); + Add(tempMsg, 170, 44); +} + +void ShipCpanel::SetTemporaryMessage(Body* const sender, std::string msg) { + std::string str = "#0f0"+msg; + if(sender) { + str = std::string("'ca0")+"Message from "+sender->GetLabel()+":\n"+str; + } + tempMsg->SetText(str); + tempMsgAge = L3D::GetGameTime(); } void ShipCpanel::Draw(void) { std::string time = date_format(L3D::GetGameTime()); m_clock->SetText(time); + if(tempMsgAge) { + if(L3D::GetGameTime() - tempMsgAge > 5.0) { + tempMsg->SetText(""); + tempMsgAge = 0; + } + } + Gui::Fixed::Draw(); Remove(m_scannerWidget); } diff --git a/src/ship_cpanel.h b/src/ship_cpanel.h index f619df9..d87f564 100644 --- a/src/ship_cpanel.h +++ b/src/ship_cpanel.h @@ -2,11 +2,14 @@ #include "libs.h" #include "gui.h" +class Body; + class ShipCpanel : public Gui::Fixed { public: ShipCpanel(void); virtual void Draw(void); void SetScannerWidget(Widget* w); /* Must be done each frame. */ + void SetTemporaryMessage(Body* const sender, std::string msg); private: void OnChangeCamView(Gui::MultiStateImageButton* b); void OnChangeMapView(Gui::MultiStateImageButton* b); @@ -16,5 +19,8 @@ private: Widget* m_scannerWidget; Gui::Label* m_clock; + + Gui::Label* tempMsg; + float tempMsgAge; }; diff --git a/src/space_station.cpp b/src/space_station.cpp index 5b5bb79..ce8d485 100644 --- a/src/space_station.cpp +++ b/src/space_station.cpp @@ -57,7 +57,6 @@ void SpaceStation::GetDockingSurface(CollMeshSet* mset, int midx) { } SpaceStation::SpaceStation(void) : ModelBody() { - allowDocking = true; SetModel(STATION_SBRE_MODEL); matrix4x4d m = matrix4x4d::RotateYMatrix(M_PI-M_PI/6); SetRotation(m); @@ -83,13 +82,17 @@ SpaceStation::~SpaceStation(void) { } +bool SpaceStation::GetDockingClearance(Ship* s) { + s->SetDockingTimer(68*10); + return true; +} + bool SpaceStation::OnCollision(Body* b, Uint32 flags) { if(flags == 1) { /* Hitting docking area of a station. */ if(b->GetType() == Object::SHIP) { Ship* s = static_cast(b); - if(!s->GetDockedWith() && allowDocking) { - allowDocking = false; + if((!s->GetDockedWith()) && (s->GetDockingTimer() != 0.0f)) { s->Disable(); s->SetDockedWith(this); printf("Docking!\n"); diff --git a/src/space_station.h b/src/space_station.h index d839ede..cae27cc 100644 --- a/src/space_station.h +++ b/src/space_station.h @@ -3,6 +3,7 @@ #include "model_body.h" class CollMeshSet; +class Ship; class SpaceStation : public ModelBody { public: @@ -12,13 +13,11 @@ public: virtual Object::Type GetType(void) { return Object::SPACESTATION; } virtual void Render(const Frame* camFrame); void GetDockingSurface(CollMeshSet* mset, int midx); + bool GetDockingClearance(Ship* s); struct dockingport_t { vector3d center; vector3d normal; vector3d horiz; } port; - -private: - bool allowDocking; }; diff --git a/src/view.h b/src/view.h index 281aa6c..3f743a2 100644 --- a/src/view.h +++ b/src/view.h @@ -11,12 +11,16 @@ */ class View : public Gui::Fixed { public: - View(void) : Gui::Fixed(0, 64, 640, 416) { - m_rightButtonBar = new Gui::Fixed(512, 0, 128, 26); - m_rightButtonBar->SetBgColor(.65, .65, .65); + View(void) : Gui::Fixed(640, 416) { + Gui::Screen::AddBaseWidget(this, 0, 64); - m_rightRegion2 = new Gui::Fixed(517, 26, 122, 17); + m_rightButtonBar = new Gui::Fixed(128, 26); + m_rightButtonBar->SetBgColor(.65, .65, .65); + Gui::Screen::AddBaseWidget(m_rightButtonBar, 512, 0); + + m_rightRegion2 = new Gui::Fixed(122, 17); m_rightRegion2->SetTransparency(true); + Gui::Screen::AddBaseWidget(m_rightRegion2, 517, 26); } virtual ~View(void) { delete m_rightButtonBar; delete m_rightRegion2; } virtual void ShowAll(void) { diff --git a/src/world_view.cpp b/src/world_view.cpp index 2cf478d..052d464 100644 --- a/src/world_view.cpp +++ b/src/world_view.cpp @@ -3,6 +3,8 @@ #include "frame.h" #include "player.h" #include "space.h" +#include "space_station.h" +#include "ship_cpanel.h" static const float lightCol[] = { 1, 1, .9, 0 }; const float WorldView::PICK_OBJECT_RECT_SIZE = 20.0f; @@ -10,7 +12,14 @@ const float WorldView::PICK_OBJECT_RECT_SIZE = 20.0f; #define BG_STAR_MAX 5000 WorldView::WorldView(void): View() { + float size[2]; + GetSize(size); + SetTransparency(true); + + commsOptions = new Fixed(size[0], size[1]/2); + commsOptions->SetTransparency(true); + Add(commsOptions, 10, 20); Gui::MultiStateImageButton* wheels_button = new Gui::MultiStateImageButton(); wheels_button->SetShortcut(SDLK_F7, KMOD_NONE); @@ -114,24 +123,68 @@ void WorldView::Update(void) { /* Player control inputs. */ if(L3D::player) L3D::player->PollControls(); + + Body* target = L3D::player->GetNavTarget(); + if(target) { + commsOptions->ShowAll(); + } else { + //commsOptions->HideAll(); + } } -void WorldView::OnMouseDown(Gui::MouseButtonEvent* e) { - if(1 == e->button && !L3D::MouseButtonState(3)) { - /* Left click in view when RMB not pressed => Select target. */ - float screenPos[2]; - GetPosition(screenPos); - /* Put mouse coords into screen space. */ - screenPos[0] += e->x; - screenPos[1] += e->y; - Body* const target = PickBody(screenPos[0], screenPos[1]); - if(L3D::player) { - /* TODO: If in nav mode, SetNavTarget(), else SetCombatTarget(). */ - L3D::player->SetNavTarget(target); +Gui::Button* WorldView::AddCommsOption(std::string msg, int ypos) { + Gui::Label* l = new Gui::Label(msg); + commsOptions->Add(l, 50, ypos); + + Gui::TransparentButton* b = new Gui::TransparentButton(); + commsOptions->Add(b, 16, ypos); + return b; +} + +static void PlayerRequestDockingClearance(SpaceStation* s) { + s->GetDockingClearance(L3D::player); + L3D::cpan->SetTemporaryMessage(s, "Docking clearance granted."); +} + +void WorldView::UpdateCommsOptions(void) { + Body* const navtarget = L3D::player->GetNavTarget(); + commsOptions->DeleteAllChildren(); + + float size[2]; + commsOptions->GetSize(size); + int ypos = size[1]-16; + if(navtarget) { + if(navtarget->GetType() == Object::SPACESTATION) { + commsOptions->Add(new Gui::Label(navtarget->GetLabel()), 16, ypos); + ypos -= 32; + Gui::Button* b = AddCommsOption("Request docking clearance", ypos); + b->onClick.connect(sigc::bind(sigc::ptr_fun(&PlayerRequestDockingClearance), (SpaceStation*)navtarget)); + ypos -= 32; + } else { + commsOptions->Add(new Gui::Label(navtarget->GetLabel()), 16, ypos); + ypos -= 32; + std::string msg = "Do something to "+navtarget->GetLabel(); + Gui::Button* b = AddCommsOption(msg, ypos); + ypos -= 32; } } } +bool WorldView::OnMouseDown(Gui::MouseButtonEvent* e) { + /* If continuing to propagate mouse event, see if target is clicked on. */ + if(Container::OnMouseDown(e)) { + if(1 == e->button && !L3D::MouseButtonState(3)) { + /* Left click in view when RMB not pressed => Select target. */ + Body* const target = PickBody(e->screenX, e->screenY); + if(L3D::player) { + /* TODO: If in nav mode, SetNavTarget(), else SetCombatTarget(). */ + L3D::player->SetNavTarget(target); + } + } + } + return true; +} + Body* WorldView::PickBody(const float screenX, const float screenY) const { Body* selected = 0; diff --git a/src/world_view.h b/src/world_view.h index 5d0e54a..31552e0 100644 --- a/src/world_view.h +++ b/src/world_view.h @@ -12,12 +12,15 @@ public: virtual void Draw3D(void); matrix4x4d viewingRotation; static const float PICK_OBJECT_RECT_SIZE; + void UpdateCommsOptions(void); private: + Gui::Button* AddCommsOption(const std::string msg, int ypos); void OnClickHyperspace(void); void OnChangeWheelsState(Gui::MultiStateImageButton* b); - virtual void OnMouseDown(Gui::MouseButtonEvent* e); + virtual bool OnMouseDown(Gui::MouseButtonEvent* e); Body* PickBody(const float screenX, const float screenY) const; Gui::ImageButton* m_hyperspaceButton; GLuint m_bgstarsDlist; + Gui::Fixed* commsOptions; };