1 /**************************************************************************/ 2 /* Copyright 2012 Tim Day */ 3 /* */ 4 /* This file is part of Evolvotron */ 5 /* */ 6 /* Evolvotron is free software: you can redistribute it and/or modify */ 7 /* it under the terms of the GNU General Public License as published by */ 8 /* the Free Software Foundation, either version 3 of the License, or */ 9 /* (at your option) any later version. */ 10 /* */ 11 /* Evolvotron is distributed in the hope that it will be useful, */ 12 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 13 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the */ 14 /* GNU General Public License for more details. */ 15 /* */ 16 /* You should have received a copy of the GNU General Public License */ 17 /* along with Evolvotron. If not, see <http://www.gnu.org/licenses/>. */ 18 /**************************************************************************/ 19 20 /*! \file 21 \brief Interface for class MutatableImageDisplay 22 */ 23 24 #ifndef _mutatable_image_display_h_ 25 #define _mutatable_image_display_h_ 26 27 #include "common.h" 28 29 #include "mutatable_image.h" 30 #include "mutatable_image_computer.h" 31 #include "dialog_mutatable_image_display.h" 32 33 class EvolvotronMain; 34 class MutatableImageComputerTask; 35 36 //! Widget responsible for displaying a MutatableImage. 37 /*! A MutatableImageDisplay is responsible for displaying the image computed from the MutatableImage it owns. 38 Computations are split off into separate threads to take advantage of multiprocessor machines. 39 */ 40 class MutatableImageDisplay : public QWidget 41 { 42 Q_OBJECT 43 44 protected: 45 //! Pointer back to the application object to access services. 46 EvolvotronMain* _main; 47 48 //! Flag for whether context menu should display all options. 49 /*! false also implies a standalone window 50 */ 51 const bool _full_functionality; 52 53 //! Flag for whether the offscreen buffer has fixed size 54 const bool _fixed_size; 55 56 //! Size of offscreen buffer 57 QSize _image_size; 58 59 //! Number of frames in image 60 uint _frames; 61 62 //! Framerate for animation. 63 uint _framerate; 64 65 //! Currently displaying frame. 66 uint _current_frame; 67 68 //! Direction to play 69 bool _animate_reverse; 70 71 //! Timer for animating frames 72 QTimer* _timer; 73 74 //! Flag indicating resize is in progress (between resizeEvent and subsequent paintEvent). 75 /*! Used to supress unnecessary task spawning. 76 */ 77 bool _resize_in_progress; 78 79 //! The resolution level currently displaying (0=1-for-1 pixels, 1=half resolution etc). 80 /*! Needed to handle possible out of order task returns from multiple compute threads. 81 */ 82 uint _current_display_level; 83 84 //! Similar to _current_display_level, but for tracking multisample grids within a resolution level. 85 uint _current_display_multisample_grid; 86 87 //! An image suitable for setting as an icon. 88 std::unique_ptr<QPixmap> _icon; 89 90 //! Track which image the icon is actually of. 91 unsigned long long int _icon_serial; 92 93 //! Offscreen image buffer. 94 std::vector<QPixmap> _offscreen_pixmaps; 95 96 //! Offscreen image buffer in sensible image format (used for save, as pixmap is in display format which might be less bits). 97 std::vector<QImage> _offscreen_images; 98 99 //! Type for staging area for incoming fragments. 100 /*! Key is level and multisampling, mapped type is also itself a map from fragment number to tasks. 101 */ 102 typedef std::map<std::pair<uint,uint>,std::map<uint,boost::shared_ptr<const MutatableImageComputerTask> > > OffscreenImageInbox; 103 104 //! Staging area for incoming fragments. 105 /*! Fragments are accumulated for each (level,multisample) key, and completed levels passed on for display 106 */ 107 OffscreenImageInbox _offscreen_images_inbox; 108 109 //! The image function being displayed (its root node). 110 /*! The held image is const because references to it could be held by history archive, compute tasks etc, 111 so it should be completely replaced rather than manipulated. 112 */ 113 boost::shared_ptr<const MutatableImage> _image_function; 114 115 //! Properties dialog. 116 DialogMutatableImageDisplay* _properties; 117 118 //! Context (right-click) menu. 119 QMenu* _menu; 120 121 //! Submenu for spawn warped options. 122 QMenu* _menu_warped; 123 124 //! Submenu for Big image options. 125 QMenu* _menu_big; 126 127 //! Position of item in menu. 128 /*! This is the only menu item we need to retain this information for becuase we need it to set the lock check-mark. 129 */ 130 QAction* _menu_item_action_lock; 131 132 //! Coordinate of mouse event which started mid-button adjustment 133 QPoint _mid_button_adjust_start_pos; 134 135 //! Coordinate of last mouse event when mid-button adjusting 136 QPoint _mid_button_adjust_last_pos; 137 138 //! Serial number to kill some rare problems with out-of-order tasks being returned 139 unsigned long long int _serial; 140 141 public: 142 //! Constructor. 143 MutatableImageDisplay(EvolvotronMain* mn,bool full_functionality,bool fixed_size,const QSize& image_size,uint f,uint fr); 144 145 //! Destructor. 146 virtual ~MutatableImageDisplay(); 147 148 //! Accessor. image_function()149 const boost::shared_ptr<const MutatableImage>& image_function() 150 { 151 return _image_function; 152 } 153 154 //! Accessor. locked()155 bool locked() const 156 { 157 return (_image_function.get()!=0 ? _image_function->locked() : false); 158 } 159 160 //! Accessor. main()161 EvolvotronMain& main() const 162 { 163 assert(_main!=0); 164 return *_main; 165 } 166 167 //! Accessor. main(EvolvotronMain * m)168 void main(EvolvotronMain* m) 169 { 170 _main=m; 171 } 172 173 //! Accessor. image_size()174 const QSize& image_size() const 175 { 176 return _image_size; 177 } 178 179 //! Load a new image (clears up old image, starts new compute tasks). 180 /*! When the one_of_many parameter is true, it implies many other images are also being updated 181 (affects fragmentation strategy for multithreading). 182 */ 183 void image_function(const boost::shared_ptr<const MutatableImage>& image_fn,bool one_of_many); 184 185 //! Evolvotron main calls this with completed (but possibly aborted) tasks. 186 void deliver(const boost::shared_ptr<const MutatableImageComputerTask>& task); 187 188 //! Set the lock state. 189 void lock(bool l,bool record_in_history); 190 191 protected: 192 193 //! Which farm this display should use. 194 MutatableImageComputerFarm& farm() const; 195 196 //! Usual handler for repaint events. 197 virtual void paintEvent(QPaintEvent* event); 198 199 //! Usual handler for resize events. 200 virtual void resizeEvent(QResizeEvent* event); 201 202 //! Handler for mouse events. 203 virtual void mousePressEvent(QMouseEvent* event); 204 205 //! Handler for mouse events. 206 virtual void mouseMoveEvent(QMouseEvent* event); 207 208 public slots: 209 210 //! Simplify the held image, return the number of nodes eliminated 211 uint simplify_constants(bool single); 212 213 //! Load a function from the given filename. 214 void load_function_file(const QString&); 215 216 protected slots: 217 218 //! Called by timer 219 void frame_advance(); 220 221 //! Called from context menu. 222 void menupick_respawn(); 223 224 //! Called from context menu and also by click event. 225 void menupick_spawn(); 226 227 //! Called from context menu. 228 void menupick_spawn_recoloured(); 229 230 //! Called from context menu. 231 void menupick_spawn_warped_random(); 232 233 //! Called from context menu. 234 void menupick_spawn_warped_zoom_in(); 235 236 //! Called from context menu. 237 void menupick_spawn_warped_zoom_out(); 238 239 //! Called from context menu. 240 void menupick_spawn_warped_rotate(); 241 242 //! Called from context menu. 243 void menupick_spawn_warped_pan_xy(); 244 245 //! Called from context menu. 246 void menupick_spawn_warped_pan_x(); 247 248 //! Called from context menu. 249 void menupick_spawn_warped_pan_y(); 250 251 //! Called from context menu. 252 void menupick_spawn_warped_pan_z(); 253 254 //! Called from context menu. 255 void menupick_lock(); 256 257 //! Trivial wrapper for simplify_constants 258 void menupick_simplify(); 259 260 //! Called from context menu. 261 void menupick_save_image(); 262 263 //! Called from context menu. 264 void menupick_save_function(); 265 266 //! Called from context menu. 267 void menupick_load_function(); 268 269 //! Called from "Big" submenu of context menu. 270 void menupick_big_resizable(); 271 272 //! Called from "Big" submenu of context menu. 273 void menupick_big_256x256(); 274 275 //! Called from "Big" submenu of context menu. 276 void menupick_big_512x512(); 277 278 //! Called from "Big" submenu of context menu. 279 void menupick_big_768x768(); 280 281 //! Called from "Big" submenu of context menu. 282 void menupick_big_1024x1024(); 283 284 //! Called from "Big" submenu of context menu. 285 void menupick_big_640x480(); 286 287 //! Called from "Big" submenu of context menu. 288 void menupick_big_1024x768(); 289 290 //! Called from "Big" submenu of context menu. 291 void menupick_big_1280x960(); 292 293 //! Called from "Big" submenu of context menu. 294 void menupick_big_1600x1200(); 295 296 //! Called from "Big" submenu of context menu. 297 void menupick_big_2048x2048(); 298 299 //! Called from "Big" submenu of context menu. 300 void menupick_big_4096x4096(); 301 302 //! Called from "Properties" on context menu 303 void menupick_properties(); 304 305 protected: 306 //! Common code for big slots. 307 void spawn_big(bool scrollable,const QSize& sz); 308 }; 309 310 #endif 311