Blender  V2.93
spreadsheet_layout.cc
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
17 #include <iomanip>
18 #include <sstream>
19 
20 #include "spreadsheet_layout.hh"
21 
22 #include "DNA_userdef_types.h"
23 
24 #include "UI_interface.h"
25 #include "UI_resources.h"
26 
27 #include "BLF_api.h"
28 
29 namespace blender::ed::spreadsheet {
30 
32  private:
33  const SpreadsheetLayout &spreadsheet_layout_;
34 
35  public:
36  SpreadsheetLayoutDrawer(const SpreadsheetLayout &spreadsheet_layout)
37  : spreadsheet_layout_(spreadsheet_layout)
38  {
39  tot_columns = spreadsheet_layout.columns.size();
40  tot_rows = spreadsheet_layout.row_indices.size();
41  left_column_width = spreadsheet_layout.index_column_width;
42  }
43 
44  void draw_top_row_cell(int column_index, const CellDrawParams &params) const final
45  {
46  const StringRefNull name = spreadsheet_layout_.columns[column_index].values->name();
47  uiBut *but = uiDefIconTextBut(params.block,
49  0,
50  ICON_NONE,
51  name.c_str(),
52  params.xmin,
53  params.ymin,
54  params.width,
55  params.height,
56  nullptr,
57  0,
58  0,
59  0,
60  0,
61  nullptr);
62  /* Center-align column headers. */
65  }
66 
67  void draw_left_column_cell(int row_index, const CellDrawParams &params) const final
68  {
69  const int real_index = spreadsheet_layout_.row_indices[row_index];
70  std::string index_str = std::to_string(real_index);
71  uiBut *but = uiDefIconTextBut(params.block,
73  0,
74  ICON_NONE,
75  index_str.c_str(),
76  params.xmin,
77  params.ymin,
78  params.width,
79  params.height,
80  nullptr,
81  0,
82  0,
83  0,
84  0,
85  nullptr);
86  /* Right-align indices. */
89  }
90 
91  void draw_content_cell(int row_index, int column_index, const CellDrawParams &params) const final
92  {
93  const int real_index = spreadsheet_layout_.row_indices[row_index];
94  const ColumnValues &column = *spreadsheet_layout_.columns[column_index].values;
95  CellValue cell_value;
96  column.get_value(real_index, cell_value);
97 
98  if (cell_value.value_int.has_value()) {
99  const int value = *cell_value.value_int;
100  const std::string value_str = std::to_string(value);
101  uiBut *but = uiDefIconTextBut(params.block,
103  0,
104  ICON_NONE,
105  value_str.c_str(),
106  params.xmin,
107  params.ymin,
108  params.width,
109  params.height,
110  nullptr,
111  0,
112  0,
113  0,
114  0,
115  nullptr);
116  /* Right-align Integers. */
119  }
120  else if (cell_value.value_float.has_value()) {
121  const float value = *cell_value.value_float;
122  std::stringstream ss;
123  ss << std::fixed << std::setprecision(3) << value;
124  const std::string value_str = ss.str();
125  uiBut *but = uiDefIconTextBut(params.block,
127  0,
128  ICON_NONE,
129  value_str.c_str(),
130  params.xmin,
131  params.ymin,
132  params.width,
133  params.height,
134  nullptr,
135  0,
136  0,
137  0,
138  0,
139  nullptr);
140  /* Right-align Floats. */
143  }
144  else if (cell_value.value_bool.has_value()) {
145  const bool value = *cell_value.value_bool;
146  const int icon = value ? ICON_CHECKBOX_HLT : ICON_CHECKBOX_DEHLT;
147  uiBut *but = uiDefIconTextBut(params.block,
149  0,
150  icon,
151  "",
152  params.xmin,
153  params.ymin,
154  params.width,
155  params.height,
156  nullptr,
157  0,
158  0,
159  0,
160  0,
161  nullptr);
163  }
164  else if (cell_value.value_float2.has_value()) {
165  const float2 value = *cell_value.value_float2;
166  this->draw_float_vector(params, Span(&value.x, 2));
167  }
168  else if (cell_value.value_float3.has_value()) {
169  const float3 value = *cell_value.value_float3;
170  this->draw_float_vector(params, Span(&value.x, 3));
171  }
172  else if (cell_value.value_color.has_value()) {
173  const Color4f value = *cell_value.value_color;
174  this->draw_float_vector(params, Span(&value.r, 4));
175  }
176  else if (cell_value.value_object.has_value()) {
177  const ObjectCellValue value = *cell_value.value_object;
178  uiDefIconTextBut(params.block,
180  0,
181  ICON_OBJECT_DATA,
182  reinterpret_cast<const ID *const>(value.object)->name + 2,
183  params.xmin,
184  params.ymin,
185  params.width,
186  params.height,
187  nullptr,
188  0,
189  0,
190  0,
191  0,
192  nullptr);
193  }
194  else if (cell_value.value_collection.has_value()) {
195  const CollectionCellValue value = *cell_value.value_collection;
196  uiDefIconTextBut(params.block,
198  0,
199  ICON_OUTLINER_COLLECTION,
200  reinterpret_cast<const ID *const>(value.collection)->name + 2,
201  params.xmin,
202  params.ymin,
203  params.width,
204  params.height,
205  nullptr,
206  0,
207  0,
208  0,
209  0,
210  nullptr);
211  }
212  }
213 
214  void draw_float_vector(const CellDrawParams &params, const Span<float> values) const
215  {
216  BLI_assert(!values.is_empty());
217  const float segment_width = (float)params.width / values.size();
218  for (const int i : values.index_range()) {
219  std::stringstream ss;
220  const float value = values[i];
221  ss << std::fixed << std::setprecision(3) << value;
222  const std::string value_str = ss.str();
223  uiBut *but = uiDefIconTextBut(params.block,
225  0,
226  ICON_NONE,
227  value_str.c_str(),
228  params.xmin + i * segment_width,
229  params.ymin,
230  segment_width,
231  params.height,
232  nullptr,
233  0,
234  0,
235  0,
236  0,
237  nullptr);
238  /* Right-align Floats. */
241  }
242  }
243 
244  int column_width(int column_index) const final
245  {
246  return spreadsheet_layout_.columns[column_index].width;
247  }
248 };
249 
250 std::unique_ptr<SpreadsheetDrawer> spreadsheet_drawer_from_layout(
251  const SpreadsheetLayout &spreadsheet_layout)
252 {
253  return std::make_unique<SpreadsheetLayoutDrawer>(spreadsheet_layout);
254 }
255 
256 } // namespace blender::ed::spreadsheet
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:58
uiBut * uiDefIconTextBut(uiBlock *block, int type, int retval, int icon, const char *str, int x, int y, short width, short height, void *poin, float min, float max, float a1, float a2, const char *tip)
Definition: interface.c:5603
@ UI_BUT_TEXT_RIGHT
Definition: UI_interface.h:261
@ UI_BUT_ICON_LEFT
Definition: UI_interface.h:260
@ UI_BUT_TEXT_LEFT
Definition: UI_interface.h:259
void UI_but_drawflag_enable(uiBut *but, int flag)
Definition: interface.c:6092
void UI_but_drawflag_disable(uiBut *but, int flag)
Definition: interface.c:6097
@ UI_BTYPE_LABEL
Definition: UI_interface.h:358
constexpr int64_t size() const
Definition: BLI_span.hh:254
constexpr IndexRange index_range() const
Definition: BLI_span.hh:414
constexpr bool is_empty() const
Definition: BLI_span.hh:262
constexpr const char * c_str() const
std::optional< ObjectCellValue > value_object
std::optional< CollectionCellValue > value_collection
virtual void get_value(int index, CellValue &r_cell_value) const =0
void draw_top_row_cell(int column_index, const CellDrawParams &params) const final
void draw_left_column_cell(int row_index, const CellDrawParams &params) const final
void draw_content_cell(int row_index, int column_index, const CellDrawParams &params) const final
void draw_float_vector(const CellDrawParams &params, const Span< float > values) const
SpreadsheetLayoutDrawer(const SpreadsheetLayout &spreadsheet_layout)
uiWidgetBaseParameters params[MAX_WIDGET_BASE_BATCH]
std::unique_ptr< SpreadsheetDrawer > spreadsheet_drawer_from_layout(const SpreadsheetLayout &spreadsheet_layout)
std::string to_string(const T &n)
Definition: DNA_ID.h:273
char name[66]
Definition: DNA_ID.h:283