1 /* ShopPanel.h 2 Copyright (c) 2014 by Michael Zahniser 3 4 Endless Sky is free software: you can redistribute it and/or modify it under the 5 terms of the GNU General Public License as published by the Free Software 6 Foundation, either version 3 of the License, or (at your option) any later version. 7 8 Endless Sky is distributed in the hope that it will be useful, but WITHOUT ANY 9 WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A 10 PARTICULAR PURPOSE. See the GNU General Public License for more details. 11 */ 12 13 #ifndef SHOP_PANEL_H_ 14 #define SHOP_PANEL_H_ 15 16 #include "Panel.h" 17 18 #include "ClickZone.h" 19 #include "OutfitInfoDisplay.h" 20 #include "Point.h" 21 #include "ShipInfoDisplay.h" 22 23 #include <map> 24 #include <set> 25 #include <string> 26 #include <vector> 27 28 class Outfit; 29 class Planet; 30 class PlayerInfo; 31 class Ship; 32 33 34 35 // Class representing the common elements of both the shipyard panel and the 36 // outfitter panel (e.g. the sidebar with the ships you own). 37 class ShopPanel : public Panel { 38 public: 39 explicit ShopPanel(PlayerInfo &player, bool isOutfitter); 40 41 virtual void Step() override; 42 virtual void Draw() override; 43 44 protected: 45 void DrawShipsSidebar(); 46 void DrawDetailsSidebar(); 47 void DrawButtons(); 48 void DrawMain(); 49 50 void DrawShip(const Ship &ship, const Point ¢er, bool isSelected); 51 52 // These are for the individual shop panels to override. 53 virtual int TileSize() const = 0; 54 virtual int DrawPlayerShipInfo(const Point &point) = 0; 55 virtual bool HasItem(const std::string &name) const = 0; 56 virtual void DrawItem(const std::string &name, const Point &point, int scrollY) = 0; 57 virtual int DividerOffset() const = 0; 58 virtual int DetailWidth() const = 0; 59 virtual int DrawDetails(const Point ¢er) = 0; 60 virtual bool CanBuy(bool checkAlreadyOwned = true) const = 0; 61 virtual void Buy(bool alreadyOwned = false) = 0; 62 virtual void FailBuy() const = 0; 63 virtual bool CanSell(bool toStorage = false) const = 0; 64 virtual void Sell(bool toStorage = false) = 0; 65 virtual void FailSell(bool toStorage = false) const; 66 virtual bool CanSellMultiple() const; 67 virtual bool IsAlreadyOwned() const; 68 virtual bool ShouldHighlight(const Ship *ship); 69 virtual void DrawKey(); 70 virtual void ToggleForSale(); 71 virtual void ToggleCargo(); 72 73 // Only override the ones you need; the default action is to return false. 74 virtual bool KeyDown(SDL_Keycode key, Uint16 mod, const Command &command, bool isNewPress) override; 75 virtual bool Click(int x, int y, int clicks) override; 76 virtual bool Hover(int x, int y) override; 77 virtual bool Drag(double dx, double dy) override; 78 virtual bool Release(int x, int y) override; 79 virtual bool Scroll(double dx, double dy) override; 80 81 int64_t LicenseCost(const Outfit *outfit) const; 82 83 84 protected: 85 class Zone : public ClickZone<const Ship *> { 86 public: 87 explicit Zone(Point center, Point size, const Ship *ship, double scrollY = 0.); 88 explicit Zone(Point center, Point size, const Outfit *outfit, double scrollY = 0.); 89 90 const Ship *GetShip() const; 91 const Outfit *GetOutfit() const; 92 93 double ScrollY() const; 94 95 private: 96 double scrollY = 0.; 97 const Outfit *outfit = nullptr; 98 }; 99 100 enum class ShopPane : int { 101 Main, 102 Sidebar, 103 Info 104 }; 105 106 107 protected: 108 static const int SIDEBAR_WIDTH = 250; 109 static const int INFOBAR_WIDTH = 300; 110 static const int SIDE_WIDTH = SIDEBAR_WIDTH + INFOBAR_WIDTH; 111 static const int BUTTON_HEIGHT = 70; 112 static const int SHIP_SIZE = 250; 113 static const int OUTFIT_SIZE = 180; 114 115 116 protected: 117 PlayerInfo &player; 118 // Remember the current day, for calculating depreciation. 119 int day; 120 const Planet *planet = nullptr; 121 122 // The player-owned ship that was first selected in the sidebar (or most recently purchased). 123 Ship *playerShip = nullptr; 124 // The player-owned ship being reordered. 125 Ship *dragShip = nullptr; 126 bool isDraggingShip = false; 127 Point dragPoint; 128 // The group of all selected, player-owned ships. 129 std::set<Ship *> playerShips; 130 131 // The currently selected Ship, for the ShipyardPanel. 132 const Ship *selectedShip = nullptr; 133 // The currently selected Outfit, for the OutfitterPanel. 134 const Outfit *selectedOutfit = nullptr; 135 // (It may be worth moving the above pointers into the derived classes in the future.) 136 137 double mainScroll = 0.; 138 double sidebarScroll = 0.; 139 double infobarScroll = 0.; 140 double maxMainScroll = 0.; 141 double maxSidebarScroll = 0.; 142 double maxInfobarScroll = 0.; 143 ShopPane activePane = ShopPane::Main; 144 int mainDetailHeight = 0; 145 int sideDetailHeight = 0; 146 bool scrollDetailsIntoView = false; 147 double selectedTopY = 0.; 148 bool sameSelectedTopY = false; 149 char hoverButton = '\0'; 150 151 std::vector<Zone> zones; 152 std::vector<ClickZone<std::string>> categoryZones; 153 154 std::map<std::string, std::set<std::string>> catalog; 155 const std::vector<std::string> &categories; 156 std::set<std::string> &collapsed; 157 158 ShipInfoDisplay shipInfo; 159 OutfitInfoDisplay outfitInfo; 160 161 mutable Point warningPoint; 162 mutable std::string warningType; 163 164 165 private: 166 bool DoScroll(double dy); 167 void SideSelect(int count); 168 void SideSelect(Ship *ship); 169 void MainLeft(); 170 void MainRight(); 171 void MainUp(); 172 void MainDown(); 173 std::vector<Zone>::const_iterator Selected() const; 174 std::vector<Zone>::const_iterator MainStart() const; 175 // Check if the given point is within the button zone, and if so return the 176 // letter of the button (or ' ' if it's not on a button). 177 char CheckButton(int x, int y); 178 }; 179 180 181 182 #endif 183