1 /*
2    Copyright (C) 2008 - 2018 by Mark de Wever <koraq@xs4all.nl>
3    Part of the Battle for Wesnoth Project https://www.wesnoth.org/
4 
5    This program is free software; you can redistribute it and/or modify
6    it under the terms of the GNU General Public License as published by
7    the Free Software Foundation; either version 2 of the License, or
8    (at your option) any later version.
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY.
11 
12    See the COPYING file for more details.
13 */
14 
15 #ifdef DEBUG_WINDOW_LAYOUT_GRAPHS
16 
17 #pragma once
18 
19 #include "gui/widgets/grid.hpp"
20 
21 #include <iosfwd>
22 #include <string>
23 
24 namespace gui2
25 {
26 
27 class widget;
28 class window;
29 
30 /**
31  * Helper class to output the layout to dot files.
32  *
33  * The class will generate .dot files in the location where wesnoth is running
34  * (so needs write access there). These files can be converted to images
35  * containing the graphs. This is used for debugging the widget library and its
36  * sizing algorithm.
37  *
38  * This class needs to be friends with a lot of classes so it can view the
39  * private data in the class. This design is chosen so the debug info can be
40  * put in a separate class instead of adding the info via virtual functions in
41  * the classes themselves. Also adding 'friend class foo' doesn't need to
42  * include the header declaring foo, so it avoids header cluttage.
43  *
44  */
45 class debug_layout_graph
46 {
47 public:
48 	/**
49 	 * Constructor.
50 	 *
51 	 * @param window              The window, whose information will be
52 	 *                            generated.
53 	 */
54 	explicit debug_layout_graph(const window* window);
55 
56 	/***** ***** ***** ***** FLAGS ***** ***** ***** *****/
57 
58 	// domain flags
59 	static const unsigned MANUAL = 0 << 0; /**<
60 											* Shows the info when the F12 is
61 											* pressed. The value 0 makes sure
62 											* the domain is always valid.
63 											*/
64 	static const unsigned SHOW = 1 << 0; /**<
65 										  * Shows the info when the dialog
66 										  * is shown.
67 										  */
68 	static const unsigned LAYOUT = 1 << 1; /**<
69 											* Shows the info in all layout
70 											* phases.
71 											*/
72 	/**
73 	 * Sets the level of wanted information.
74 	 *
75 	 * @param level               A comma separated list of levels which are
76 	 *                            wanted. Possible values: child, size, state
77 	 *                            and all.
78 	 */
79 	static void set_level(const std::string& level);
80 
81 	/**
82 	 * Sets the domain when to show the information.
83 	 *
84 	 * @param domain              A comma separated list for domains which are
85 	 *                            wanted. Possible values: show, layout and all.
86 	 */
87 	static void set_domain(const std::string& domain);
88 
89 	/**
90 	 * Generates a dot file.
91 	 *
92 	 * The file will have a fixed prefix filename but for every file a part of
93 	 * the name will contain where it was generated.
94 	 *
95 	 * @param generator           The location where the name was generated.
96 	 */
97 	void generate_dot_file(const std::string& generator, const unsigned domain);
98 
99 private:
100 	/** The window whose info will be shown. */
101 	const window* window_;
102 
103 	/** The order in which the files are generated. */
104 	unsigned sequence_number_;
105 
106 	/** Basic part of the filename. */
107 	std::string filename_base_;
108 
109 	/***** ***** Widget ***** *****/
110 
111 	/**
112 	 * Generates the info about a widget.
113 	 *
114 	 * @param out                 The stream to write the info to.
115 	 * @param widget              The widget to write the info about.
116 	 * @param id                  The dof-file-id of the widget.
117 	 * @param embedded            Is the grid embedded in a container eg parent
118 	 *                            inherits from container_base.
119 	 */
120 	void widget_generate_info(std::ostream& out,
121 							  const widget* widget,
122 							  const std::string& id,
123 							  const bool embedded = false) const;
124 
125 	/**
126 	 * Generates the basic info about a widget.
127 	 *
128 	 * @param out                 The stream to write the info to.
129 	 * @param widget              The widget to write the info about.
130 	 */
131 	void widget_generate_basic_info(std::ostream& out,
132 									const widget* widget) const;
133 
134 	/**
135 	 * Generates the info about the state of the widget.
136 	 *
137 	 * @param out                 The stream to write the info to.
138 	 * @param widget              The widget to write the info about.
139 	 */
140 	void widget_generate_state_info(std::ostream& out,
141 									const widget* widget) const;
142 
143 	/**
144 	 * Generates the info about the size and layout of the widget.
145 	 *
146 	 * @param out                 The stream to write the info to.
147 	 * @param widget              The widget to write the info about.
148 	 */
149 	void widget_generate_size_info(std::ostream& out,
150 								   const widget* widget) const;
151 
152 	/***** ***** Grid ***** *****/
153 
154 	/**
155 	 * Generates the info about a grid.
156 	 *
157 	 * @param out                 The stream to write the info to.
158 	 * @param grid                The grid to write the info about.
159 	 * @param parent_id           The dot-file-id of the parent of the widget.
160 	 */
161 	void grid_generate_info(std::ostream& out,
162 							const grid* grid,
163 							const std::string& parent_id) const;
164 
165 	/**
166 	 * Generates the info about a grid cell.
167 	 *
168 	 * @param out                 The stream to write the info to.
169 	 * @param child               The grid cell to write the info about.
170 	 * @param id                  The dof-file-id of the child.
171 	 */
172 	void child_generate_info(std::ostream& out,
173 							 const grid::child& child,
174 							 const std::string& id) const;
175 
176 	/***** ***** Helper ***** *****/
177 
178 	/**
179 	 * Returns the control_type of a widget.
180 	 *
181 	 * This is a small wrapper around styled_widget::get_control_type() since a
182 	 * grid is no styled_widget and used rather frequently, so we want to give it a
183 	 * type.
184 	 *
185 	 * @param widget              The widget to get the type of.
186 	 *
187 	 * @returns                   If the widget is a styled_widget it returns its
188 	 *                            type. If the widget is a grid it returns
189 	 *                            'grid', otherwise 'unknown' will be returned.
190 	 */
191 	std::string get_type(const widget* widget) const;
192 };
193 
194 } // namespace gui2
195 
196 #endif
197