layout editor: column drag follows the pointer through the cell floor
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
1 parent
2183317953
commit
4fab14949c
5 files changed
+127
-52
No files matched your search
+24
-10
@@ -758,30 +758,37 @@ void layout_col_apply(App& app, int plot, double offset_px) {
|
||||
const int fr = rs.figure_row_of(plot);
|
||||
const int k = rs.cell_of(plot);
|
||||
if (fr < 0 || k < 1) return;
|
||||
// The weights the drag began with: a drag is relative to its start, so reading the live weights here
|
||||
// would compound with every update.
|
||||
if (app.layout_col_drag_start.size() != static_cast<std::size_t>(rs.cells_in_row(fr))) return;
|
||||
const double scale =
|
||||
app.area != nullptr && app.area->device_scale() > 0.0f ? app.area->device_scale() : 1.0;
|
||||
const double pair = app.layout_col_drag_left0 + app.layout_col_drag_right0;
|
||||
const double floor = std::min(kMinCellPx, pair * 0.5);
|
||||
const double want_left = std::clamp(app.layout_col_drag_left0 + offset_px / scale,
|
||||
floor, pair - floor);
|
||||
std::vector<float> w = rs.cell_weights(fr);
|
||||
w.resize(static_cast<std::size_t>(rs.cells_in_row(fr)), 1.0f);
|
||||
// The plotter lays a cell out as `floor + extra * weight / total`, so a width is *not* proportional to
|
||||
// its weight: the pair's `pair` px are `2 * floor` plus `(pair - 2 * floor)` shared by the two weights.
|
||||
// Solve for the share that puts the left cell at `want_left`; the pair's weight sum stays what it was,
|
||||
// which keeps the pair's total width (and every other cell) where it was.
|
||||
const double spare = pair - 2.0 * kPlotterMinCellPx;
|
||||
const double frac = spare > 0.0
|
||||
? std::clamp((want_left - kPlotterMinCellPx) / spare, 0.001, 0.999)
|
||||
: 0.5;
|
||||
std::vector<float> w = app.layout_col_drag_start;
|
||||
const float sum = w[static_cast<std::size_t>(k - 1)] + w[static_cast<std::size_t>(k)];
|
||||
w[static_cast<std::size_t>(k - 1)] = static_cast<float>(sum * want_left / pair);
|
||||
w[static_cast<std::size_t>(k - 1)] = static_cast<float>(sum * frac);
|
||||
w[static_cast<std::size_t>(k)] = sum - w[static_cast<std::size_t>(k - 1)];
|
||||
rs.set_cell_weights(fr, w);
|
||||
if (app.area_widget != nullptr) gtk_gl_area_queue_render(GTK_GL_AREA(app.area_widget));
|
||||
}
|
||||
|
||||
void on_layout_col_begin(GtkGestureDrag* gesture, double, double, gpointer user) {
|
||||
App& app = *static_cast<App*>(user);
|
||||
app.layout_col_drag_plot =
|
||||
GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gesture), "udpscope-layout-col-drag"));
|
||||
const int plot = app.layout_col_drag_plot;
|
||||
if (plot < 0 || plot >= app.rows->row_count()) return;
|
||||
bool layout_col_drag_begin(App& app, int plot) {
|
||||
app.layout_col_drag_plot = plot;
|
||||
if (app.rows == nullptr || plot < 1 || plot >= app.rows->row_count()) return false;
|
||||
const int fr = app.rows->figure_row_of(plot);
|
||||
const int k = app.rows->cell_of(plot);
|
||||
if (fr < 0 || k < 1) return;
|
||||
if (fr < 0 || k < 1) return false;
|
||||
const plot::FigureLayout& fl = app.rows->figure().layout();
|
||||
const double scale =
|
||||
app.area != nullptr && app.area->device_scale() > 0.0f ? app.area->device_scale() : 1.0;
|
||||
@@ -789,6 +796,13 @@ void on_layout_col_begin(GtkGestureDrag* gesture, double, double, gpointer user)
|
||||
app.layout_col_drag_right0 = static_cast<double>(fl.cells[static_cast<std::size_t>(plot)].w) / scale;
|
||||
app.layout_col_drag_start = app.rows->cell_weights(fr);
|
||||
app.layout_col_drag_start.resize(static_cast<std::size_t>(app.rows->cells_in_row(fr)), 1.0f);
|
||||
return true;
|
||||
}
|
||||
|
||||
void on_layout_col_begin(GtkGestureDrag* gesture, double, double, gpointer user) {
|
||||
App& app = *static_cast<App*>(user);
|
||||
layout_col_drag_begin(
|
||||
app, GPOINTER_TO_INT(g_object_get_data(G_OBJECT(gesture), "udpscope-layout-col-drag")));
|
||||
}
|
||||
|
||||
void on_layout_col_update(GtkGestureDrag*, double offset_x, double, gpointer user) {
|
||||
|
||||
Reference in new issue
Block a user