Spreadsheet: make column widths editable
Currently, there are two main annoying problems with columns widths in the spreadsheet: * The initial column width is often too small. This is especially noticeable with the ID integer attribute. * There is no way to change the column width. This patch improves both of these aspects. The initial column width will now be derived from the content of the spreadsheet. This initial width is then stored in DNA to make it editable and to avoid having to recompute it on each redraw. Furthermore, there is a new modal operator to change the width of a column. Pull Request: https://projects.blender.org/blender/blender/pulls/138657
This commit is contained in:
@@ -3604,6 +3604,7 @@ def km_spreadsheet_generic(params):
|
||||
sidebar_key={"type": 'N', "value": 'PRESS'},
|
||||
channels_key={"type": 'T', "value": 'PRESS'},
|
||||
),
|
||||
("spreadsheet.resize_column", {"type": 'LEFTMOUSE', "value": 'PRESS'}, None),
|
||||
])
|
||||
|
||||
return keymap
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <cstring>
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_string.h"
|
||||
@@ -341,58 +342,27 @@ static std::unique_ptr<DataSource> get_data_source(const bContext *C)
|
||||
return {};
|
||||
}
|
||||
|
||||
static float get_default_column_width(const ColumnValues &values)
|
||||
static float get_initial_column_width(const ColumnValues &values)
|
||||
{
|
||||
if (values.default_width > 0.0f) {
|
||||
return values.default_width;
|
||||
}
|
||||
static const float float_width = 3;
|
||||
switch (values.type()) {
|
||||
case SPREADSHEET_VALUE_TYPE_BOOL:
|
||||
case SPREADSHEET_VALUE_TYPE_FLOAT4X4:
|
||||
return 2.0f;
|
||||
case SPREADSHEET_VALUE_TYPE_INT8:
|
||||
case SPREADSHEET_VALUE_TYPE_INT32:
|
||||
return float_width;
|
||||
case SPREADSHEET_VALUE_TYPE_FLOAT:
|
||||
return float_width;
|
||||
case SPREADSHEET_VALUE_TYPE_INT32_2D:
|
||||
case SPREADSHEET_VALUE_TYPE_FLOAT2:
|
||||
return 2.0f * float_width;
|
||||
case SPREADSHEET_VALUE_TYPE_FLOAT3:
|
||||
return 3.0f * float_width;
|
||||
case SPREADSHEET_VALUE_TYPE_COLOR:
|
||||
case SPREADSHEET_VALUE_TYPE_BYTE_COLOR:
|
||||
case SPREADSHEET_VALUE_TYPE_QUATERNION:
|
||||
return 4.0f * float_width;
|
||||
case SPREADSHEET_VALUE_TYPE_INSTANCES:
|
||||
return 8.0f;
|
||||
case SPREADSHEET_VALUE_TYPE_STRING:
|
||||
return 5.0f;
|
||||
case SPREADSHEET_VALUE_TYPE_UNKNOWN:
|
||||
return 2.0f;
|
||||
}
|
||||
return float_width;
|
||||
}
|
||||
const float padding_px = 0.5 * SPREADSHEET_WIDTH_UNIT;
|
||||
const float min_width_px = SPREADSHEET_WIDTH_UNIT;
|
||||
|
||||
static float get_column_width(const ColumnValues &values)
|
||||
{
|
||||
float data_width = get_default_column_width(values);
|
||||
const int fontid = UI_style_get()->widget.uifont_id;
|
||||
const float data_width_px = values.initial_width_px();
|
||||
|
||||
const int fontid = BLF_default();
|
||||
BLF_size(fontid, UI_DEFAULT_TEXT_POINTS * UI_SCALE_FAC);
|
||||
const StringRefNull name = values.name();
|
||||
const float name_width = BLF_width(fontid, name.data(), name.size());
|
||||
return std::max<float>(name_width / UI_UNIT_X + 1.0f, data_width);
|
||||
}
|
||||
const float name_width_px = BLF_width(fontid, name.data(), name.size());
|
||||
|
||||
static float get_column_width_in_pixels(const ColumnValues &values)
|
||||
{
|
||||
return get_column_width(values) * SPREADSHEET_WIDTH_UNIT;
|
||||
const float width_px = std::max(min_width_px,
|
||||
padding_px + std::max(data_width_px, name_width_px));
|
||||
const float width = width_px / SPREADSHEET_WIDTH_UNIT;
|
||||
return width;
|
||||
}
|
||||
|
||||
static int get_index_column_width(const int tot_rows)
|
||||
{
|
||||
const int fontid = UI_style_get()->widget.uifont_id;
|
||||
const int fontid = BLF_default();
|
||||
BLF_size(fontid, UI_style_get_dpi()->widget.points * UI_SCALE_FAC);
|
||||
return std::to_string(std::max(0, tot_rows - 1)).size() * BLF_width(fontid, "0", 1) +
|
||||
UI_UNIT_X * 0.75;
|
||||
@@ -452,22 +422,32 @@ static void spreadsheet_main_region_draw(const bContext *C, ARegion *region)
|
||||
SpreadsheetLayout spreadsheet_layout;
|
||||
ResourceScope scope;
|
||||
|
||||
const int tot_rows = data_source->tot_rows();
|
||||
spreadsheet_layout.index_column_width = get_index_column_width(tot_rows);
|
||||
spreadsheet_layout.row_indices = spreadsheet_filter_rows(
|
||||
*sspreadsheet, spreadsheet_layout, *data_source, scope);
|
||||
|
||||
int x = spreadsheet_layout.index_column_width;
|
||||
|
||||
LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet->columns) {
|
||||
std::unique_ptr<ColumnValues> values_ptr = data_source->get_column_values(*column->id);
|
||||
/* Should have been removed before if it does not exist anymore. */
|
||||
BLI_assert(values_ptr);
|
||||
const ColumnValues *values = scope.add(std::move(values_ptr));
|
||||
const int width = get_column_width_in_pixels(*values);
|
||||
spreadsheet_layout.columns.append({values, width});
|
||||
|
||||
if (column->width <= 0.0f) {
|
||||
column->width = get_initial_column_width(*values);
|
||||
}
|
||||
const int width_in_pixels = column->width * SPREADSHEET_WIDTH_UNIT;
|
||||
spreadsheet_layout.columns.append({values, width_in_pixels});
|
||||
|
||||
column->runtime->left_x = x;
|
||||
x += width_in_pixels;
|
||||
column->runtime->right_x = x;
|
||||
|
||||
spreadsheet_column_assign_runtime_data(column, values->type(), values->name());
|
||||
}
|
||||
|
||||
const int tot_rows = data_source->tot_rows();
|
||||
spreadsheet_layout.index_column_width = get_index_column_width(tot_rows);
|
||||
spreadsheet_layout.row_indices = spreadsheet_filter_rows(
|
||||
*sspreadsheet, spreadsheet_layout, *data_source, scope);
|
||||
|
||||
sspreadsheet->runtime->tot_columns = spreadsheet_layout.columns.size();
|
||||
sspreadsheet->runtime->tot_rows = tot_rows;
|
||||
sspreadsheet->runtime->visible_rows = spreadsheet_layout.row_indices.size();
|
||||
@@ -475,6 +455,8 @@ static void spreadsheet_main_region_draw(const bContext *C, ARegion *region)
|
||||
std::unique_ptr<SpreadsheetDrawer> drawer = spreadsheet_drawer_from_layout(spreadsheet_layout);
|
||||
draw_spreadsheet_in_region(C, region, *drawer);
|
||||
|
||||
sspreadsheet->runtime->top_row_height = drawer->top_row_height;
|
||||
|
||||
/* Tag other regions for redraw, because the main region updates data for them. */
|
||||
ARegion *footer = BKE_area_find_region_type(CTX_wm_area(C), RGN_TYPE_FOOTER);
|
||||
ED_region_tag_redraw(footer);
|
||||
@@ -688,6 +670,7 @@ static void spreadsheet_blend_read_data(BlendDataReader *reader, SpaceLink *sl)
|
||||
}
|
||||
BLO_read_struct_list(reader, SpreadsheetColumn, &sspreadsheet->columns);
|
||||
LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet->columns) {
|
||||
column->runtime = MEM_new<SpreadsheetColumnRuntime>(__func__);
|
||||
BLO_read_struct(reader, SpreadsheetColumnID, &column->id);
|
||||
BLO_read_string(reader, &column->id->name);
|
||||
/* While the display name is technically runtime data, it is loaded here, otherwise the row
|
||||
@@ -727,6 +710,19 @@ static void spreadsheet_blend_write(BlendWriter *writer, SpaceLink *sl)
|
||||
BKE_viewer_path_blend_write(writer, &sspreadsheet->viewer_path);
|
||||
}
|
||||
|
||||
static void spreadsheet_cursor(wmWindow *win, ScrArea *area, ARegion *region)
|
||||
{
|
||||
SpaceSpreadsheet &sspreadsheet = *static_cast<SpaceSpreadsheet *>(area->spacedata.first);
|
||||
|
||||
const int2 cursor_re{win->eventstate->xy[0] - region->winrct.xmin,
|
||||
win->eventstate->xy[1] - region->winrct.ymin};
|
||||
if (find_column_to_resize(sspreadsheet, *region, cursor_re)) {
|
||||
WM_cursor_set(win, WM_CURSOR_X_MOVE);
|
||||
return;
|
||||
}
|
||||
WM_cursor_set(win, WM_CURSOR_DEFAULT);
|
||||
}
|
||||
|
||||
void register_spacetype()
|
||||
{
|
||||
std::unique_ptr<SpaceType> st = std::make_unique<SpaceType>();
|
||||
@@ -756,6 +752,8 @@ void register_spacetype()
|
||||
art->init = spreadsheet_main_region_init;
|
||||
art->draw = spreadsheet_main_region_draw;
|
||||
art->listener = spreadsheet_main_region_listener;
|
||||
art->cursor = spreadsheet_cursor;
|
||||
art->event_cursor = true;
|
||||
BLI_addhead(&st->regiontypes, art);
|
||||
|
||||
/* regions: header */
|
||||
|
||||
@@ -92,6 +92,7 @@ SpreadsheetColumn *spreadsheet_column_new(SpreadsheetColumnID *column_id)
|
||||
{
|
||||
SpreadsheetColumn *column = MEM_callocN<SpreadsheetColumn>(__func__);
|
||||
column->id = column_id;
|
||||
column->runtime = MEM_new<SpreadsheetColumnRuntime>(__func__);
|
||||
return column;
|
||||
}
|
||||
|
||||
@@ -111,6 +112,7 @@ SpreadsheetColumn *spreadsheet_column_copy(const SpreadsheetColumn *src_column)
|
||||
if (src_column->display_name != nullptr) {
|
||||
new_column->display_name = BLI_strdup(src_column->display_name);
|
||||
}
|
||||
new_column->width = src_column->width;
|
||||
return new_column;
|
||||
}
|
||||
|
||||
@@ -118,6 +120,7 @@ void spreadsheet_column_free(SpreadsheetColumn *column)
|
||||
{
|
||||
spreadsheet_column_id_free(column->id);
|
||||
MEM_SAFE_FREE(column->display_name);
|
||||
MEM_delete(column->runtime);
|
||||
MEM_freeN(column);
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,12 @@ inline bool operator==(const SpreadsheetColumnID &a, const SpreadsheetColumnID &
|
||||
|
||||
namespace blender::ed::spreadsheet {
|
||||
|
||||
struct SpreadsheetColumnRuntime {
|
||||
/** Coordinates of the left and right edges of the column in view space. */
|
||||
int left_x = 0;
|
||||
int right_x = 0;
|
||||
};
|
||||
|
||||
SpreadsheetColumnID *spreadsheet_column_id_new();
|
||||
SpreadsheetColumnID *spreadsheet_column_id_copy(const SpreadsheetColumnID *src_column_id);
|
||||
void spreadsheet_column_id_free(SpreadsheetColumnID *column_id);
|
||||
|
||||
@@ -52,8 +52,7 @@ class ColumnValues final {
|
||||
return data_;
|
||||
}
|
||||
|
||||
/* The default width of newly created columns, in UI units. */
|
||||
float default_width = 0.0f;
|
||||
float initial_width_px() const;
|
||||
};
|
||||
|
||||
} // namespace blender::ed::spreadsheet
|
||||
|
||||
@@ -5,12 +5,17 @@
|
||||
#pragma once
|
||||
|
||||
#include "BKE_geometry_set.hh"
|
||||
|
||||
#include "spreadsheet_cache.hh"
|
||||
|
||||
struct ARegionType;
|
||||
struct Depsgraph;
|
||||
struct Object;
|
||||
struct SpaceSpreadsheet;
|
||||
struct ARegion;
|
||||
struct SpreadsheetColumn;
|
||||
|
||||
#define SPREADSHEET_EDGE_ACTION_ZONE (UI_UNIT_X * 0.3f)
|
||||
|
||||
namespace blender::ed::spreadsheet {
|
||||
|
||||
@@ -19,6 +24,7 @@ struct SpaceSpreadsheet_Runtime {
|
||||
int visible_rows = 0;
|
||||
int tot_rows = 0;
|
||||
int tot_columns = 0;
|
||||
int top_row_height = 0;
|
||||
|
||||
SpreadsheetCache cache;
|
||||
|
||||
@@ -40,4 +46,8 @@ bke::GeometrySet spreadsheet_get_display_geometry_set(const SpaceSpreadsheet *ss
|
||||
|
||||
void spreadsheet_data_set_region_panels_register(ARegionType ®ion_type);
|
||||
|
||||
SpreadsheetColumn *find_column_to_resize(SpaceSpreadsheet &sspreadsheet,
|
||||
ARegion ®ion,
|
||||
const int2 &cursor_re);
|
||||
|
||||
} // namespace blender::ed::spreadsheet
|
||||
|
||||
@@ -7,6 +7,8 @@
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "BLF_api.hh"
|
||||
|
||||
#include "BLI_math_matrix.hh"
|
||||
#include "BLI_math_quaternion_types.hh"
|
||||
#include "BLI_math_vector_types.hh"
|
||||
@@ -432,6 +434,127 @@ class SpreadsheetLayoutDrawer : public SpreadsheetDrawer {
|
||||
}
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
static float estimate_max_column_width(const float min_width,
|
||||
const int fontid,
|
||||
const VArray<T> &data,
|
||||
FunctionRef<std::string(const T &)> to_string)
|
||||
{
|
||||
if (const std::optional<T> value = data.get_if_single()) {
|
||||
const std::string str = to_string(*value);
|
||||
return std::max(min_width, BLF_width(fontid, str.c_str(), str.size()));
|
||||
}
|
||||
const int max_sample_size = 100;
|
||||
float width = min_width;
|
||||
for (const int i : data.index_range().take_front(max_sample_size)) {
|
||||
const std::string str = to_string(data[i]);
|
||||
const float value_width = BLF_width(fontid, str.c_str(), str.size());
|
||||
width = std::max(width, value_width);
|
||||
}
|
||||
return width;
|
||||
}
|
||||
|
||||
float ColumnValues::initial_width_px() const
|
||||
{
|
||||
const int fontid = BLF_default();
|
||||
BLF_size(fontid, UI_DEFAULT_TEXT_POINTS * UI_SCALE_FAC);
|
||||
|
||||
const eSpreadsheetColumnValueType column_type = this->type();
|
||||
switch (column_type) {
|
||||
case SPREADSHEET_VALUE_TYPE_BOOL: {
|
||||
return 2.0f * SPREADSHEET_WIDTH_UNIT;
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_FLOAT4X4: {
|
||||
return 2.0f * SPREADSHEET_WIDTH_UNIT;
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_INT8: {
|
||||
return 3.0f * SPREADSHEET_WIDTH_UNIT;
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_INT32: {
|
||||
return estimate_max_column_width<int>(
|
||||
3 * SPREADSHEET_WIDTH_UNIT, fontid, data_.typed<int>(), [](const int value) {
|
||||
return fmt::format("{}", value);
|
||||
});
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_FLOAT: {
|
||||
return estimate_max_column_width<float>(
|
||||
3 * SPREADSHEET_WIDTH_UNIT, fontid, data_.typed<float>(), [](const float value) {
|
||||
return fmt::format("{:.3f}", value);
|
||||
});
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_INT32_2D: {
|
||||
return estimate_max_column_width<int2>(
|
||||
3 * SPREADSHEET_WIDTH_UNIT, fontid, data_.typed<int2>(), [](const int2 value) {
|
||||
return fmt::format("{} {}", value.x, value.y);
|
||||
});
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_FLOAT2: {
|
||||
return estimate_max_column_width<float2>(
|
||||
6 * SPREADSHEET_WIDTH_UNIT, fontid, data_.typed<float2>(), [](const float2 value) {
|
||||
return fmt::format("{:.3f} {:.3f}", value.x, value.y);
|
||||
});
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_FLOAT3: {
|
||||
return estimate_max_column_width<float3>(
|
||||
9 * SPREADSHEET_WIDTH_UNIT, fontid, data_.typed<float3>(), [](const float3 value) {
|
||||
return fmt::format("{:.3f} {:.3f} {:.3f}", value.x, value.y, value.z);
|
||||
});
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_COLOR: {
|
||||
return estimate_max_column_width<ColorGeometry4f>(
|
||||
12 * SPREADSHEET_WIDTH_UNIT,
|
||||
fontid,
|
||||
data_.typed<ColorGeometry4f>(),
|
||||
[](const ColorGeometry4f value) {
|
||||
return fmt::format(
|
||||
"{:.3f} {:.3f} {:.3f} {:.3f}", value.r, value.g, value.b, value.a);
|
||||
});
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_BYTE_COLOR: {
|
||||
return estimate_max_column_width<ColorGeometry4b>(
|
||||
12 * SPREADSHEET_WIDTH_UNIT,
|
||||
fontid,
|
||||
data_.typed<ColorGeometry4b>(),
|
||||
[](const ColorGeometry4b value) {
|
||||
return fmt::format("{} {} {} {}", value.r, value.g, value.b, value.a);
|
||||
});
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_QUATERNION: {
|
||||
return estimate_max_column_width<math::Quaternion>(
|
||||
12 * SPREADSHEET_WIDTH_UNIT,
|
||||
fontid,
|
||||
data_.typed<math::Quaternion>(),
|
||||
[](const math::Quaternion value) {
|
||||
return fmt::format(
|
||||
"{:.3f} {:.3f} {:.3f} {:.3f}", value.x, value.y, value.z, value.w);
|
||||
});
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_INSTANCES: {
|
||||
return 24 * SPREADSHEET_WIDTH_UNIT;
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_STRING: {
|
||||
if (data_.type().is<std::string>()) {
|
||||
return estimate_max_column_width<std::string>(SPREADSHEET_WIDTH_UNIT,
|
||||
fontid,
|
||||
data_.typed<std::string>(),
|
||||
[](const StringRef value) { return value; });
|
||||
}
|
||||
if (data_.type().is<MStringProperty>()) {
|
||||
return estimate_max_column_width<MStringProperty>(
|
||||
SPREADSHEET_WIDTH_UNIT,
|
||||
fontid,
|
||||
data_.typed<MStringProperty>(),
|
||||
[](const MStringProperty &value) { return StringRef(value.s, value.s_len); });
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SPREADSHEET_VALUE_TYPE_UNKNOWN: {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 2.0f * SPREADSHEET_WIDTH_UNIT;
|
||||
}
|
||||
|
||||
std::unique_ptr<SpreadsheetDrawer> spreadsheet_drawer_from_layout(
|
||||
const SpreadsheetLayout &spreadsheet_layout)
|
||||
{
|
||||
|
||||
@@ -2,20 +2,27 @@
|
||||
*
|
||||
* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||
|
||||
#include <fmt/format.h>
|
||||
|
||||
#include "DNA_space_types.h"
|
||||
|
||||
#include "ED_screen.hh"
|
||||
|
||||
#include "BLI_listbase.h"
|
||||
#include "BLI_rect.h"
|
||||
|
||||
#include "BKE_context.hh"
|
||||
|
||||
#include "RNA_access.hh"
|
||||
#include "RNA_define.hh"
|
||||
|
||||
#include "UI_interface_c.hh"
|
||||
#include "UI_view2d.hh"
|
||||
|
||||
#include "WM_api.hh"
|
||||
#include "WM_types.hh"
|
||||
|
||||
#include "spreadsheet_column.hh"
|
||||
#include "spreadsheet_intern.hh"
|
||||
#include "spreadsheet_row_filter.hh"
|
||||
|
||||
@@ -117,11 +124,110 @@ static void SPREADSHEET_OT_change_spreadsheet_data_source(wmOperatorType *ot)
|
||||
ot->flag = OPTYPE_INTERNAL;
|
||||
}
|
||||
|
||||
struct ResizeColumnData {
|
||||
SpreadsheetColumn *column = nullptr;
|
||||
int2 initial_cursor_re;
|
||||
int initial_width_px;
|
||||
};
|
||||
|
||||
static wmOperatorStatus resize_column_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
ARegion ®ion = *CTX_wm_region(C);
|
||||
|
||||
ResizeColumnData &data = *static_cast<ResizeColumnData *>(op->customdata);
|
||||
|
||||
auto cancel = [&]() {
|
||||
data.column->width = data.initial_width_px / SPREADSHEET_WIDTH_UNIT;
|
||||
MEM_delete(&data);
|
||||
ED_region_tag_redraw(®ion);
|
||||
return OPERATOR_CANCELLED;
|
||||
};
|
||||
auto finish = [&]() {
|
||||
MEM_delete(&data);
|
||||
ED_region_tag_redraw(®ion);
|
||||
return OPERATOR_FINISHED;
|
||||
};
|
||||
|
||||
const int2 cursor_re{event->mval[0], event->mval[1]};
|
||||
|
||||
switch (event->type) {
|
||||
case RIGHTMOUSE:
|
||||
case EVT_ESCKEY: {
|
||||
return cancel();
|
||||
}
|
||||
case LEFTMOUSE: {
|
||||
return finish();
|
||||
}
|
||||
case MOUSEMOVE: {
|
||||
const int offset = cursor_re.x - data.initial_cursor_re.x;
|
||||
const float new_width_px = std::max<float>(SPREADSHEET_WIDTH_UNIT,
|
||||
data.initial_width_px + offset);
|
||||
data.column->width = new_width_px / SPREADSHEET_WIDTH_UNIT;
|
||||
ED_region_tag_redraw(®ion);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
default: {
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
SpreadsheetColumn *find_column_to_resize(SpaceSpreadsheet &sspreadsheet,
|
||||
ARegion ®ion,
|
||||
const int2 &cursor_re)
|
||||
{
|
||||
const int region_height = BLI_rcti_size_y(®ion.winrct);
|
||||
if (cursor_re.y < region_height - sspreadsheet.runtime->top_row_height) {
|
||||
return nullptr;
|
||||
}
|
||||
const float cursor_x_view = UI_view2d_region_to_view_x(®ion.v2d, cursor_re.x);
|
||||
LISTBASE_FOREACH (SpreadsheetColumn *, column, &sspreadsheet.columns) {
|
||||
if (std::abs(cursor_x_view - column->runtime->right_x) < SPREADSHEET_EDGE_ACTION_ZONE) {
|
||||
return column;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static wmOperatorStatus resize_column_invoke(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
{
|
||||
ARegion ®ion = *CTX_wm_region(C);
|
||||
SpaceSpreadsheet &sspreadsheet = *CTX_wm_space_spreadsheet(C);
|
||||
|
||||
const int2 cursor_re{event->mval[0], event->mval[1]};
|
||||
SpreadsheetColumn *column_to_resize = find_column_to_resize(sspreadsheet, region, cursor_re);
|
||||
if (!column_to_resize) {
|
||||
return OPERATOR_PASS_THROUGH;
|
||||
}
|
||||
|
||||
ResizeColumnData *data = MEM_new<ResizeColumnData>(__func__);
|
||||
data->column = column_to_resize;
|
||||
data->initial_cursor_re = cursor_re;
|
||||
data->initial_width_px = column_to_resize->width * SPREADSHEET_WIDTH_UNIT;
|
||||
op->customdata = data;
|
||||
|
||||
WM_event_add_modal_handler(C, op);
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static void SPREADSHEET_OT_resize_column(wmOperatorType *ot)
|
||||
{
|
||||
ot->name = "Resize Column";
|
||||
ot->description = "Resize a spreadsheet column";
|
||||
ot->idname = "SPREADSHEET_OT_resize_column";
|
||||
|
||||
ot->invoke = resize_column_invoke;
|
||||
ot->modal = resize_column_modal;
|
||||
ot->poll = ED_operator_spreadsheet_active;
|
||||
ot->flag = OPTYPE_INTERNAL;
|
||||
}
|
||||
|
||||
void spreadsheet_operatortypes()
|
||||
{
|
||||
WM_operatortype_append(SPREADSHEET_OT_add_row_filter_rule);
|
||||
WM_operatortype_append(SPREADSHEET_OT_remove_row_filter_rule);
|
||||
WM_operatortype_append(SPREADSHEET_OT_change_spreadsheet_data_source);
|
||||
WM_operatortype_append(SPREADSHEET_OT_resize_column);
|
||||
}
|
||||
|
||||
} // namespace blender::ed::spreadsheet
|
||||
|
||||
@@ -79,14 +79,17 @@ using SpaceText_Runtime = blender::ed::text::SpaceText_Runtime;
|
||||
|
||||
namespace blender::ed::spreadsheet {
|
||||
struct SpaceSpreadsheet_Runtime;
|
||||
struct SpreadsheetColumnRuntime;
|
||||
} // namespace blender::ed::spreadsheet
|
||||
using SpaceSpreadsheet_Runtime = blender::ed::spreadsheet::SpaceSpreadsheet_Runtime;
|
||||
using SpreadsheetColumnRuntime = blender::ed::spreadsheet::SpreadsheetColumnRuntime;
|
||||
#else
|
||||
typedef struct SpaceNode_Runtime SpaceNode_Runtime;
|
||||
typedef struct SpaceOutliner_Runtime SpaceOutliner_Runtime;
|
||||
typedef struct SpaceSeq_Runtime SpaceSeq_Runtime;
|
||||
typedef struct SpaceText_Runtime SpaceText_Runtime;
|
||||
typedef struct SpaceSpreadsheet_Runtime SpaceSpreadsheet_Runtime;
|
||||
typedef struct SpreadsheetColumnRuntime SpreadsheetColumnRuntime;
|
||||
#endif
|
||||
|
||||
/** Defined in `file_intern.hh`. */
|
||||
@@ -1958,13 +1961,17 @@ typedef struct SpreadsheetColumn {
|
||||
* #eSpreadsheetColumnValueType.
|
||||
*/
|
||||
uint8_t data_type;
|
||||
char _pad0[7];
|
||||
char _pad0[3];
|
||||
/** Width in SPREADSHEET_WIDTH_UNIT. */
|
||||
float width;
|
||||
|
||||
/**
|
||||
* The final column name generated by the data source, also just
|
||||
* cached at runtime when the data source columns are generated.
|
||||
*/
|
||||
char *display_name;
|
||||
|
||||
SpreadsheetColumnRuntime *runtime;
|
||||
} SpreadsheetColumn;
|
||||
|
||||
typedef struct SpreadsheetInstanceID {
|
||||
|
||||
Reference in New Issue
Block a user