1 /* 2 * Copyright (C) 2014-2018 Christopho, Solarus - http://www.solarus-games.org 3 * 4 * Solarus Quest Editor is free software; you can redistribute it and/or modify 5 * it under the terms of the GNU General Public License as published by 6 * the Free Software Foundation, either version 3 of the License, or 7 * (at your option) any later version. 8 * 9 * Solarus Quest Editor is distributed in the hope that it will be useful, 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 * GNU General Public License for more details. 13 * 14 * You should have received a copy of the GNU General Public License along 15 * with this program. If not, see <http://www.gnu.org/licenses/>. 16 */ 17 #ifndef SOLARUSEDITOR_ENTITY_MODEL_H 18 #define SOLARUSEDITOR_ENTITY_MODEL_H 19 20 #include "entity_traits.h" 21 #include "resize_mode.h" 22 #include "sprite_model.h" 23 #include <QPointer> 24 25 namespace SolarusEditor { 26 27 class MapModel; 28 class Quest; 29 class QuestDatabase; 30 class TilesetModel; 31 32 using SubtypeList = QList<QPair<QString, QString>>; 33 34 /** 35 * @brief Model of a map entity. 36 * 37 * This class wraps an entity from the Solarus library and 38 * adds all useful information about how to represent and modify it in the 39 * editor. 40 * An EntityModel can represent an entity on the map or an entity that is not 41 * on the map yet. 42 * 43 * Each type of entity is a subclass of EntityModel. 44 */ 45 class EntityModel { 46 47 public: 48 49 virtual ~EntityModel() = default; 50 51 static EntityModelPtr create( 52 MapModel& map, EntityType type); 53 static EntityModelPtr create( 54 MapModel& map, const QString& entity_string); 55 static EntityModelPtr create( 56 MapModel& map, const EntityIndex& index); 57 static EntityModelPtr clone( 58 MapModel& map, const EntityIndex& index); 59 EntityModelPtr clone() const; 60 61 const MapModel& get_map() const; 62 MapModel& get_map(); 63 QString get_map_tileset_id() const; 64 const TilesetModel* get_map_tileset() const; 65 TilesetModel* get_map_tileset(); 66 const Quest& get_quest() const; 67 const QuestDatabase& get_database() const; 68 69 // Index on the map. 70 EntityIndex get_index() const; 71 bool is_on_map() const; 72 void added_to_map(const EntityIndex& index); 73 void about_to_be_removed_from_map(); 74 void index_changed(const EntityIndex& index); 75 76 EntityType get_type() const; 77 QString get_type_name() const; 78 bool is_dynamic() const; 79 80 const Solarus::EntityData& get_entity() const; 81 Solarus::EntityData& get_entity(); 82 83 // Access data. 84 bool has_name() const; 85 QString get_name() const; 86 void set_name(const QString& name); 87 void ensure_valid_on_map(); 88 void ensure_name_unique(); 89 void ensure_default_destination_unique(); 90 int get_layer() const; 91 void set_layer(int layer); 92 QPoint get_xy() const; 93 void set_xy(const QPoint& xy); 94 QPoint get_top_left() const; 95 void set_top_left(const QPoint& top_left); 96 QPoint get_bottom_right() const; 97 void set_bottom_right(const QPoint& bottom_right); 98 QPoint get_center() const; 99 void set_center(const QPoint& center); 100 bool has_origin_fields() const; 101 QPoint get_origin() const; 102 void set_origin(const QPoint& origin); 103 bool has_size_fields() const; 104 int get_width() const; 105 void set_width(int width); 106 int get_height() const; 107 void set_height(int height); 108 QSize get_size() const; 109 void set_size(const QSize& size); 110 QRect get_bounding_box() const; 111 bool get_has_preferred_layer() const; 112 int get_preferred_layer() const; 113 bool has_direction_field() const; 114 bool is_no_direction_allowed() const; 115 QString get_no_direction_text() const; 116 int get_num_directions() const; 117 int get_direction() const; 118 void set_direction(int direction); 119 bool is_enabled_at_start() const; 120 void set_enabled_at_start(bool enabled_at_start); 121 bool has_subtype_field() const; 122 SubtypeList get_existing_subtypes() const; 123 QString get_subtype() const; 124 void set_subtype(const QString& subtype); 125 bool has_field(const QString& key) const; 126 bool is_field_optional(const QString& key) const; 127 bool is_field_unset(const QString& key) const; 128 QVariant get_field(const QString& key) const; 129 void set_field(const QString& key, const QVariant& value); 130 int get_user_property_count() const; 131 QPair<QString, QString> get_user_property(int index) const; 132 bool set_user_property(int index, const QPair<QString, QString>& property); 133 bool add_user_property(const QPair<QString, QString>& property); 134 bool remove_user_property(int index); 135 static bool is_valid_user_property_key(const QString &key); 136 bool is_traversable() const; 137 QString to_string() const; 138 139 // Resizing from the editor. 140 bool is_resizable() const; 141 ResizeMode get_resize_mode() const; 142 QSize get_base_size() const; 143 bool is_size_valid() const; 144 virtual bool is_size_valid(const QSize& size) const; 145 QSize get_closest_valid_size(const QSize& size) const; 146 virtual QSize get_valid_size() const; 147 148 // Displaying in the editor. 149 virtual void draw(QPainter& painter) const; 150 virtual void notify_tileset_changed(const QString& tileset_id); 151 152 void reload_sprite(); 153 154 protected: 155 156 /** 157 * @brief Describes how to draw an entity as a sprite. 158 */ 159 struct DrawSpriteInfo { 160 161 bool enabled = true; // false means not drawn as a sprite. 162 QString sprite_id; // Only used if there is no "sprite" field. 163 QString animation; // Animation for sprite_id (empty means default). 164 int direction = 0; // Direction of the sprite. 165 // Only used if there is no "direction" field. 166 int frame = 0; // Index of the frame to show. If negative, 167 // we count from the end (-1 is the last frame). 168 bool tiled = false; // Tiled or only once at origin point. 169 }; 170 171 /** 172 * @brief Describes how to draw an entity as a shape. 173 * 174 * The shape is filled with a background color or a pixmap, 175 * or both if the pixmap is not tiled but centered, 176 * and may have a border with two black lines and a color between them. 177 * For now the shape is always rectangular. 178 */ 179 struct DrawShapeInfo { 180 181 bool enabled = false; // false means not drawn as a shape. 182 QColor background_color; 183 QColor between_border_color; 184 QPixmap pixmap; 185 bool tiled_pixmap = false; // Tiled or centered. 186 }; 187 188 /** 189 * @brief A rectangle region of an image file. 190 */ 191 struct SubImage { 192 QString file_name; 193 QRect src_rect; // An invalid rect means the whole image. 194 mutable QPixmap pixmap; 195 }; 196 197 /** 198 * @brief Describes how to draw an entity as a fixed image. 199 * 200 * If nothing is specified, the image will be a generic icon for the entity 201 * type. 202 */ 203 struct DrawImageInfo { 204 SubImage image_no_direction; 205 QList<SubImage> images_by_direction; 206 double scale = 1.0; // If 2.0, the image will have a resolution twice better. 207 }; 208 209 EntityModel(MapModel& map, const EntityIndex& index, EntityType type); 210 211 void set_resizable(bool resizable); 212 void set_resize_mode(ResizeMode resize_mode); 213 void set_base_size(const QSize& base_size); 214 215 void set_has_preferred_layer(bool has_preferred_layer); 216 void set_preferred_layer(int preferred_layer); 217 218 void set_num_directions(int num_directions); 219 void set_no_direction_allowed(bool no_direction_allowed); 220 void set_no_direction_text(const QString& no_direction_text); 221 222 void set_traversable(bool traversable); 223 224 void set_existing_subtypes(const SubtypeList& subtypes); 225 226 virtual void notify_name_changed(const QString& name); 227 virtual void notify_field_changed(const QString& key, const QVariant& value); 228 virtual void set_initial_values(); 229 230 const DrawSpriteInfo& get_draw_sprite_info() const; 231 void set_draw_sprite_info(const DrawSpriteInfo& draw_sprite_info); 232 const DrawShapeInfo& get_draw_shape_info() const; 233 void set_draw_shape_info(const DrawShapeInfo& draw_shape_info); 234 const DrawImageInfo& get_draw_image_info() const; 235 void set_draw_image_info(const DrawImageInfo& draw_shape_info); 236 237 bool draw_as_sprite(QPainter& painter) const; 238 bool draw_as_sprite(QPainter& painter, 239 const QString& sprite_id, 240 const QString& animation, 241 int direction, 242 int frame) const; 243 bool draw_as_shape(QPainter& painter) const; 244 bool draw_as_image(QPainter& painter) const; 245 bool draw_as_image(QPainter& painter, const SubImage& image) const; 246 bool draw_as_icon(QPainter& painter) const; 247 248 private: 249 250 static EntityModelPtr create( 251 MapModel& map, const EntityIndex& index, EntityType type); 252 void set_entity(const Solarus::EntityData& entity); 253 254 QPointer<MapModel> map; /**< The map this entity belongs to 255 * (could be a reference but we want operator=). */ 256 EntityIndex index; /**< Index of this entity in the map. 257 * When invalid, the entity is not added to the map yet. */ 258 Solarus::EntityData stub; /**< Stub of entity, used before it gets added to the map. */ 259 QString name; /**< Name of the entity. */ 260 QPoint origin; /**< Origin point of the entity relative to its top-left corner. */ 261 QSize size; /**< Size of the entity for the editor. */ 262 QSize base_size; /**< Reference size when resizing. */ 263 ResizeMode resize_mode; /**< How the entity can be resized. */ 264 bool has_preferred_layer; /**< Whether the entity has a preferred layer when added to the map. */ 265 int preferred_layer; /**< The preferred layer if has_preferred_layer is true. */ 266 int num_directions; /**< Number of possible directions (except the possible special one -1). */ 267 bool no_direction_allowed; /**< Whether the special no-value -1 is an allowed direction. */ 268 QString no_direction_text; /**< The text to show in a GUI for the special no-value -1 (if allowed). */ 269 bool traversable; /**< Whether this entity is assumed to be traversable. */ 270 SubtypeList subtypes; /**< Existing subtypes of this entity type. */ 271 272 // Displaying. 273 DrawSpriteInfo 274 draw_sprite_info; /**< How to draw the entity 275 * when it is drawn as a sprite. */ 276 mutable std::unique_ptr<SpriteModel> 277 sprite_model; /**< Sprite to show when the entity is drawn 278 * as a sprite. */ 279 mutable QPixmap sprite_image; /**< Fixed image from the sprite. */ 280 DrawShapeInfo draw_shape_info; /**< Shape to use when the entity is drawn as 281 * a shape. */ 282 DrawImageInfo draw_image_info; /**< Subimage to use when the entity is 283 * drawn as a fixed image from a file. */ 284 mutable QPixmap icon; /**< Icon to use when the entity is drawn as 285 * an icon. */ 286 }; 287 288 } 289 290 #endif 291