KDirStat – a graphical disk usage utility
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

324 lines
8.4KB

  1. /*
  2. * File name: ktreemaptile.h
  3. * Summary: High level classes for KDirStat
  4. * License: LGPL - See file COPYING.LIB for details.
  5. * Author: Stefan Hundhammer <sh@suse.de>
  6. *
  7. * Updated: 2003-01-07
  8. */
  9. #ifndef KTreemapTile_h
  10. #define KTreemapTile_h
  11. #ifdef HAVE_CONFIG_H
  12. # include <config.h>
  13. #endif
  14. #include <tqcanvas.h>
  15. #include <tqrect.h>
  16. #include "kdirtreeiterators.h"
  17. namespace KDirStat
  18. {
  19. class KFileInfo;
  20. class KTreemapView;
  21. enum KOrientation
  22. {
  23. KTreemapHorizontal,
  24. KTreemapVertical,
  25. KTreemapAuto
  26. };
  27. /**
  28. * Helper class for cushioned treemaps: This class holds the polynome
  29. * parameters for the cushion surface. The height of each point of such a
  30. * surface is defined as:
  31. *
  32. * z(x, y) = a*x^2 + b*y^2 + c*x + d*y
  33. * or
  34. * z(x, y) = xx2*x^2 + yy2*y^2 + xx1*x + yy1*y
  35. *
  36. * to better keep track of which coefficient belongs where.
  37. **/
  38. class KCushionSurface
  39. {
  40. public:
  41. /**
  42. * Constructor. All polynome coefficients are set to 0.
  43. **/
  44. KCushionSurface();
  45. /**
  46. * Adds a ridge of the specified height in dimension 'dim' within
  47. * rectangle 'rect' to this surface. It's real voodo magic.
  48. *
  49. * Just kidding - read the paper about "cushion treemaps" by Jarke
  50. * J. van Wiik and Huub van de Wetering from the TU Eindhoven, NL for
  51. * more details.
  52. *
  53. * If you don't want to get all that involved: The coefficients are
  54. * changed in some way.
  55. **/
  56. void addRidge( KOrientation dim, double height, const TQRect & rect );
  57. /**
  58. * Set the cushion's height.
  59. **/
  60. void setHeight( double newHeight ) { _height = newHeight; }
  61. /**
  62. * Returns the cushion's height.
  63. **/
  64. double height() const { return _height; }
  65. /**
  66. * Returns the polynomal coefficient of the second order for X direction.
  67. **/
  68. double xx2() const { return _xx2; }
  69. /**
  70. * Returns the polynomal coefficient of the first order for X direction.
  71. **/
  72. double xx1() const { return _xx1; }
  73. /**
  74. * Returns the polynomal coefficient of the second order for Y direction.
  75. **/
  76. double yy2() const { return _yy2; }
  77. /**
  78. * Returns the polynomal coefficient of the first order for Y direction.
  79. **/
  80. double yy1() const { return _yy1; }
  81. protected:
  82. /**
  83. * Calculate a new square polynomal coefficient for adding a ridge of
  84. * specified height between x1 and x2.
  85. **/
  86. double squareRidge( double squareCoefficient, double height, int x1, int x2 );
  87. /**
  88. * Calculate a new linear polynomal coefficient for adding a ridge of
  89. * specified height between x1 and x2.
  90. **/
  91. double linearRidge( double linearCoefficient, double height, int x1, int x2 );
  92. // Data members
  93. double _xx2, _xx1;
  94. double _yy2, _yy1;
  95. double _height;
  96. }; // class KCushionSurface
  97. /**
  98. * This is the basic building block of a treemap view: One single tile of a
  99. * treemap. If it corresponds to a leaf in the tree, it will be visible as
  100. * one tile (one rectangle) of the treemap. If it has tqchildren, it will be
  101. * subdivided again.
  102. *
  103. * @short Basic building block of a treemap
  104. **/
  105. class KTreemapTile: public TQCanvasRectangle
  106. {
  107. public:
  108. /**
  109. * Constructor: Create a treemap tile from 'fileinfo' that fits into a
  110. * rectangle 'rect' inside 'parent'.
  111. *
  112. * 'orientation' is the direction for further subdivision. 'Auto'
  113. * selects the wider direction inside 'rect'.
  114. **/
  115. KTreemapTile( KTreemapView * parentView,
  116. KTreemapTile * parentTile,
  117. KFileInfo * orig,
  118. const TQRect & rect,
  119. KOrientation orientation = KTreemapAuto );
  120. protected:
  121. /**
  122. * Alternate constructor: Like the above, but explicitly specify a
  123. * cushion surface rather than using the parent's.
  124. **/
  125. KTreemapTile( KTreemapView * parentView,
  126. KTreemapTile * parentTile,
  127. KFileInfo * orig,
  128. const TQRect & rect,
  129. const KCushionSurface & cushionSurface,
  130. KOrientation orientation = KTreemapAuto );
  131. public:
  132. /**
  133. * Destructor.
  134. **/
  135. virtual ~KTreemapTile();
  136. /**
  137. * Returns the original @ref KFileInfo item that corresponds to this
  138. * treemap tile.
  139. **/
  140. KFileInfo * orig() const { return _orig; }
  141. /**
  142. * Returns the parent @ref KTreemapView.
  143. **/
  144. KTreemapView * parentView() const { return _parentView; }
  145. /**
  146. * Returns the parent @ref KTreemapTile or 0 if there is none.
  147. **/
  148. KTreemapTile * parentTile() const { return _parentTile; }
  149. /**
  150. * Returns this tile's cushion surface parameters.
  151. **/
  152. KCushionSurface & cushionSurface() { return _cushionSurface; }
  153. protected:
  154. /**
  155. * Create tqchildren (sub-tiles) of this tile.
  156. **/
  157. void createChildren ( const TQRect & rect,
  158. KOrientation orientation );
  159. /**
  160. * Create tqchildren (sub-tiles) using the simple treemap algorithm:
  161. * Alternate between horizontal and vertical subdivision in each
  162. * level. Each child will get the entire height or width, respectively,
  163. * of the specified rectangle. This algorithm is very fast, but often
  164. * results in very thin, elongated tiles.
  165. **/
  166. void createChildrenSimple( const TQRect & rect,
  167. KOrientation orientation );
  168. /**
  169. * Create tqchildren using the "squarified treemaps" algorithm as
  170. * described by Mark Bruls, Kees Huizing, and Jarke J. van Wijk of the
  171. * TU Eindhoven, NL.
  172. *
  173. * This algorithm is not quite so simple and involves more expensive
  174. * operations, e.g., sorting the tqchildren of each node by size first,
  175. * try some variations of the tqlayout and maybe backtrack to the
  176. * previous attempt. But it results in tiles that are much more
  177. * square-like, i.e. have more reasonable width-to-height ratios. It is
  178. * very much less likely to get thin, elongated tiles that are hard to
  179. * point at and even harder to compare visually against each other.
  180. *
  181. * This implementation includes some improvements to that basic
  182. * algorithm. For example, tqchildren below a certain size are
  183. * disregarded completely since they will not get an adequate visual
  184. * representation anyway (it would be way too small). They are
  185. * summarized in some kind of 'misc stuff' area in the parent treemap
  186. * tile - in fact, part of the parent directory's tile can be "seen
  187. * through".
  188. *
  189. * In short, a lot of small tqchildren that don't have any useful effect
  190. * for the user in finding wasted disk space are omitted from handling
  191. * and, most important, don't need to be sorted by size (which has a
  192. * cost of O(n*ln(n)) in the best case, so reducing n helps a lot).
  193. **/
  194. void createSquarifiedChildren( const TQRect & rect );
  195. /**
  196. * Squarify as many tqchildren as possible: Try to squeeze members
  197. * referred to by 'it' into 'rect' until the aspect ratio doesn't get
  198. * better any more. Returns a list of tqchildren that should be laid out
  199. * in 'rect'. Moves 'it' until there is no more improvement or 'it'
  200. * runs out of items.
  201. *
  202. * 'scale' is the scaling factor between file sizes and pixels.
  203. **/
  204. KFileInfoList squarify( const TQRect & rect,
  205. double scale,
  206. KFileInfoSortedBySizeIterator & it );
  207. /**
  208. * Lay out all members of 'row' within 'rect' along its longer side.
  209. * Returns the new rectangle with the layouted area subtracted.
  210. **/
  211. TQRect layoutRow( const TQRect & rect,
  212. double scale,
  213. KFileInfoList & row );
  214. /**
  215. * Draw the tile.
  216. *
  217. * Reimplemented from TQCanvasRectangle.
  218. **/
  219. virtual void drawShape( TQPainter & painter );
  220. /**
  221. * Render a cushion as described in "cushioned treemaps" by Jarke
  222. * J. van Wijk and Huub van de Wetering of the TU Eindhoven, NL.
  223. **/
  224. TQPixmap renderCushion();
  225. /**
  226. * Check if the contrast of the specified image is sufficient to
  227. * visually distinguish an outline at the right and bottom borders
  228. * and add a grey line there, if necessary.
  229. **/
  230. void ensureContrast( TQImage & image );
  231. /**
  232. * Returns a color that gives a reasonable contrast to 'col': Lighter
  233. * if 'col' is dark, darker if 'col' is light.
  234. **/
  235. TQRgb contrastingColor( TQRgb col );
  236. private:
  237. /**
  238. * Initialization common to all constructors.
  239. **/
  240. void init();
  241. protected:
  242. // Data members
  243. KTreemapView * _parentView;
  244. KTreemapTile * _parentTile;
  245. KFileInfo * _orig;
  246. KCushionSurface _cushionSurface;
  247. TQPixmap _cushion;
  248. }; // class KTreemapTile
  249. } // namespace KDirStat
  250. inline kdbgstream & operator<< ( kdbgstream & stream, const TQRect & rect )
  251. {
  252. stream << "("
  253. << rect.width() << "x" << rect.height()
  254. << "+" << rect.x() << "+" << rect.y()
  255. << ")";
  256. return stream;
  257. }
  258. #endif // ifndef KTreemapTile_h
  259. // EOF