Followup to previous commit: fix same wrong numinput handling in other modal ops.

Also stumbled uppon 'move marker' code, was needing a bunch of fixes, cleanup and simplification,
and added a candy feature - now you will enter numinput values in seconds when editor is
in 'time' mode, instead of frames!
This commit is contained in:
Bastien Montagne 2014-08-25 20:18:43 +02:00
parent b638696ca6
commit 66b84ad159
Notes: blender-bot 2023-02-13 19:45:33 +01:00
Referenced by commit 37e60289c2, Fix T85110: moving markers num input confuses time vs frames
Referenced by issue #85110, Moving markers in Graph editor
4 changed files with 225 additions and 226 deletions

View File

@ -604,24 +604,88 @@ typedef struct MarkerMove {
NumInput num;
} MarkerMove;
static bool ed_marker_move_use_time(MarkerMove *mm)
{
if (((mm->slink->spacetype == SPACE_TIME) && !(((SpaceTime *)mm->slink)->flag & TIME_DRAWFRAMES)) ||
((mm->slink->spacetype == SPACE_SEQ) && !(((SpaceSeq *)mm->slink)->flag & SEQ_DRAWFRAMES)) ||
((mm->slink->spacetype == SPACE_ACTION) && (((SpaceAction *)mm->slink)->flag & SACTION_DRAWTIME)) ||
((mm->slink->spacetype == SPACE_IPO) && !(((SpaceIpo *)mm->slink)->flag & SIPO_DRAWTIME)) ||
((mm->slink->spacetype == SPACE_NLA) && !(((SpaceNla *)mm->slink)->flag & SNLA_DRAWTIME)))
{
return true;
}
return false;
}
static void ed_marker_move_update_header(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
MarkerMove *mm = op->customdata;
TimeMarker *marker, *selmarker = NULL;
const int offs = RNA_int_get(op->ptr, "frames");
char str[256];
char str_offs[NUM_STR_REP_LEN];
int totmark;
const bool use_time = ed_marker_move_use_time(mm);
for (totmark = 0, marker = mm->markers->first; marker; marker = marker->next) {
if (marker->flag & SELECT) {
selmarker = marker;
totmark++;
}
}
if (hasNumInput(&mm->num)) {
outputNumInput(&mm->num, str_offs, scene->unit.scale_length);
}
else if (use_time) {
BLI_snprintf(str_offs, sizeof(str_offs), "%.2f", FRA2TIME(offs));
}
else {
BLI_snprintf(str_offs, sizeof(str_offs), "%d", offs);
}
if (totmark == 1 && selmarker) {
/* we print current marker value */
if (use_time) {
BLI_snprintf(str, sizeof(str), "Marker %.2f offset %s", FRA2TIME(selmarker->frame), str_offs);
}
else {
BLI_snprintf(str, sizeof(str), "Marker %d offset %s", selmarker->frame, str_offs);
}
}
else {
BLI_snprintf(str, sizeof(str), "Marker offset %s", str_offs);
}
ED_area_headerprint(CTX_wm_area(C), str);
}
/* copy selection to temp buffer */
/* return 0 if not OK */
static int ed_marker_move_init(bContext *C, wmOperator *op)
static bool ed_marker_move_init(bContext *C, wmOperator *op)
{
Scene *scene = CTX_data_scene(C);
ListBase *markers = ED_context_get_markers(C);
MarkerMove *mm;
TimeMarker *marker;
int totmark = 0;
int a;
int a, totmark;
if (markers == NULL) {
return false;
}
for (totmark = 0, marker = markers->first; marker; marker = marker->next) {
if (marker->flag & SELECT) {
totmark++;
}
}
if (totmark == 0) {
return false;
}
if (markers == NULL) return 0;
for (marker = markers->first; marker; marker = marker->next)
if (marker->flag & SELECT) totmark++;
if (totmark == 0) return 0;
op->customdata = mm = MEM_callocN(sizeof(MarkerMove), "Markermove");
mm->slink = CTX_wm_space_data(C);
mm->markers = markers;
@ -632,16 +696,16 @@ static int ed_marker_move_init(bContext *C, wmOperator *op)
mm->num.val_flag[0] |= NUM_NO_FRACTION;
mm->num.unit_sys = scene->unit.system;
/* No time unit supporting frames currently... */
mm->num.unit_type[0] = B_UNIT_NONE;
mm->num.unit_type[0] = ed_marker_move_use_time(mm) ? B_UNIT_TIME : B_UNIT_NONE;
for (a = 0, marker = markers->first; marker; marker = marker->next) {
if (marker->flag & SELECT) {
mm->oldframe[a] = marker->frame;
a++;
}
}
return 1;
return true;
}
/* free stuff */
@ -672,7 +736,9 @@ static int ed_marker_move_invoke(bContext *C, wmOperator *op, const wmEvent *eve
/* reset frs delta */
RNA_int_set(op->ptr, "frames", 0);
ed_marker_move_update_header(C, op);
return OPERATOR_RUNNING_MODAL;
}
@ -726,138 +792,88 @@ static void ed_marker_move_cancel(bContext *C, wmOperator *op)
ed_marker_move_exit(C, op);
}
static int ed_marker_move_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
Scene *scene = CTX_data_scene(C);
MarkerMove *mm = op->customdata;
View2D *v2d = UI_view2d_fromcontext(C);
TimeMarker *marker, *selmarker = NULL;
char str[256];
switch (event->type) {
case ESCKEY:
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
case RIGHTMOUSE:
/* press = user manually demands transform to be canceled */
if (event->val == KM_PRESS) {
const bool has_numinput = hasNumInput(&mm->num);
const bool use_time = ed_marker_move_use_time(mm);
/* Modal numinput active, try to handle numeric inputs first... */
if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &mm->num, event)) {
float value = (float)RNA_int_get(op->ptr, "frames");
applyNumInput(&mm->num, &value);
if (use_time) {
value = TIME2FRA(value);
}
RNA_int_set(op->ptr, "frames", (int)value);
ed_marker_move_apply(C, op);
ed_marker_move_update_header(C, op);
}
else {
bool handled = false;
switch (event->type) {
case ESCKEY:
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
}
/* else continue; <--- see if release event should be caught for tweak-end */
case RETKEY:
case PADENTER:
case LEFTMOUSE:
case MIDDLEMOUSE:
if (WM_modal_tweak_exit(event, mm->event_type)) {
ed_marker_move_exit(C, op);
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
return OPERATOR_FINISHED;
}
break;
case MOUSEMOVE:
{
float dx, fac;
case RIGHTMOUSE:
/* press = user manually demands transform to be canceled */
if (event->val == KM_PRESS) {
ed_marker_move_cancel(C, op);
return OPERATOR_CANCELLED;
}
/* else continue; <--- see if release event should be caught for tweak-end */
if (hasNumInput(&mm->num))
case RETKEY:
case PADENTER:
case LEFTMOUSE:
case MIDDLEMOUSE:
if (WM_modal_tweak_exit(event, mm->event_type)) {
ed_marker_move_exit(C, op);
WM_event_add_notifier(C, NC_SCENE | ND_MARKERS, NULL);
WM_event_add_notifier(C, NC_ANIMATION | ND_MARKERS, NULL);
return OPERATOR_FINISHED;
}
break;
dx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
if (event->x != mm->evtx) { /* XXX maybe init for first time */
int a, offs, totmark = 0;
mm->evtx = event->x;
fac = ((float)(event->x - mm->firstx) * dx);
if (mm->slink->spacetype == SPACE_TIME)
apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, FPS, 0.1 * FPS, 0);
else
apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/);
offs = (int)fac;
RNA_int_set(op->ptr, "frames", offs);
ed_marker_move_apply(C, op);
/* cruft below is for header print */
for (a = 0, marker = mm->markers->first; marker; marker = marker->next) {
if (marker->flag & SELECT) {
selmarker = marker;
a++; totmark++;
}
}
if (totmark == 1) {
/* we print current marker value */
if (mm->slink->spacetype == SPACE_TIME) {
SpaceTime *stime = (SpaceTime *)mm->slink;
if (stime->flag & TIME_DRAWFRAMES)
BLI_snprintf(str, sizeof(str), "Marker %d offset %d", selmarker->frame, offs);
else
BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
}
else if (mm->slink->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)mm->slink;
if (saction->flag & SACTION_DRAWTIME)
BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", FRA2TIME(selmarker->frame), FRA2TIME(offs));
case MOUSEMOVE:
if (!has_numinput) {
float dx;
dx = BLI_rctf_size_x(&v2d->cur) / BLI_rcti_size_x(&v2d->mask);
if (event->x != mm->evtx) { /* XXX maybe init for first time */
float fac;
mm->evtx = event->x;
fac = ((float)(event->x - mm->firstx) * dx);
if (mm->slink->spacetype == SPACE_TIME)
apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, FPS, 0.1 * FPS, 0);
else
BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
}
else {
BLI_snprintf(str, sizeof(str), "Marker %.2f offset %.2f", (double)(selmarker->frame), (double)(offs));
apply_keyb_grid(event->shift, event->ctrl, &fac, 0.0, 1.0, 0.1, 0 /*was: U.flag & USER_AUTOGRABGRID*/);
RNA_int_set(op->ptr, "frames", (int)fac);
ed_marker_move_apply(C, op);
ed_marker_move_update_header(C, op);
}
}
else {
/* we only print the offset */
if (mm->slink->spacetype == SPACE_TIME) {
SpaceTime *stime = (SpaceTime *)mm->slink;
if (stime->flag & TIME_DRAWFRAMES)
BLI_snprintf(str, sizeof(str), "Marker offset %d ", offs);
else
BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", FRA2TIME(offs));
}
else if (mm->slink->spacetype == SPACE_ACTION) {
SpaceAction *saction = (SpaceAction *)mm->slink;
if (saction->flag & SACTION_DRAWTIME)
BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", FRA2TIME(offs));
else
BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", (double)(offs));
}
else {
BLI_snprintf(str, sizeof(str), "Marker offset %.2f ", (double)(offs));
}
}
ED_area_headerprint(CTX_wm_area(C), str);
}
break;
break;
}
}
if (event->val == KM_PRESS) {
if (handleNumInput(C, &mm->num, event)) {
char str_tx[NUM_STR_REP_LEN];
float value = RNA_int_get(op->ptr, "frames");
if (!handled && event->val == KM_PRESS && handleNumInput(C, &mm->num, event)) {
float value = (float)RNA_int_get(op->ptr, "frames");
applyNumInput(&mm->num, &value);
if (hasNumInput(&mm->num)) {
outputNumInput(&mm->num, str_tx, scene->unit.scale_length);
}
else {
BLI_snprintf(str_tx, sizeof(str_tx), "%d", (int)value);
if (use_time) {
value = TIME2FRA(value);
}
RNA_int_set(op->ptr, "frames", value);
RNA_int_set(op->ptr, "frames", (int)value);
ed_marker_move_apply(C, op);
// ed_marker_header_update(C, op, str, (int)value);
// strcat(str, str_tx);
BLI_snprintf(str, sizeof(str), "Marker offset %s", str_tx);
ED_area_headerprint(CTX_wm_area(C), str);
ed_marker_move_update_header(C, op);
}
}

View File

@ -73,7 +73,7 @@ typedef struct {
#define HEADER_LENGTH 180
static void edbm_bevel_update_header(wmOperator *op, bContext *C)
static void edbm_bevel_update_header(bContext *C, wmOperator *op)
{
const char *str = IFACE_("Confirm: (Enter/LMB), Cancel: (Esc/RMB), Mode: %s (M), Offset: %s, Segments: %d");
@ -262,7 +262,7 @@ static int edbm_bevel_invoke(bContext *C, wmOperator *op, const wmEvent *event)
opdata->initial_length = len_v2(mlen);
opdata->pixel_size = rv3d ? ED_view3d_pixel_size(rv3d, center_3d) : 1.0f;
edbm_bevel_update_header(op, C);
edbm_bevel_update_header(C, op);
if (!edbm_bevel_calc(op)) {
edbm_bevel_cancel(C, op);
@ -329,7 +329,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
applyNumInput(&opdata->num_input, &value);
RNA_float_set(op->ptr, "offset", value);
edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
edbm_bevel_update_header(C, op);
return OPERATOR_RUNNING_MODAL;
}
else {
@ -346,7 +346,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
RNA_float_set(op->ptr, "offset", factor);
edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
edbm_bevel_update_header(C, op);
handled = true;
}
break;
@ -371,7 +371,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
segments++;
RNA_int_set(op->ptr, "segments", segments);
edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
edbm_bevel_update_header(C, op);
handled = true;
break;
@ -383,7 +383,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
segments = max_ii(segments - 1, 1);
RNA_int_set(op->ptr, "segments", segments);
edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
edbm_bevel_update_header(C, op);
handled = true;
break;
@ -405,7 +405,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
RNA_float_set(op->ptr, "offset", edbm_bevel_mval_factor(op, event));
}
edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
edbm_bevel_update_header(C, op);
handled = true;
break;
}
@ -416,7 +416,7 @@ static int edbm_bevel_modal(bContext *C, wmOperator *op, const wmEvent *event)
applyNumInput(&opdata->num_input, &value);
RNA_float_set(op->ptr, "offset", value);
edbm_bevel_calc(op);
edbm_bevel_update_header(op, C);
edbm_bevel_update_header(C, op);
return OPERATOR_RUNNING_MODAL;
}
}

View File

@ -297,25 +297,24 @@ static int edbm_inset_invoke(bContext *C, wmOperator *op, const wmEvent *event)
static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event)
{
InsetData *opdata = op->customdata;
const bool has_numinput = hasNumInput(&opdata->num_input);
if (event->val == KM_PRESS && hasNumInput(&opdata->num_input)) {
/* Modal numinput active, try to handle numeric inputs first... */
if (handleNumInput(C, &opdata->num_input, event)) {
float amounts[2] = {RNA_float_get(op->ptr, "thickness"),
RNA_float_get(op->ptr, "depth")};
applyNumInput(&opdata->num_input, amounts);
amounts[0] = max_ff(amounts[0], 0.0f);
RNA_float_set(op->ptr, "thickness", amounts[0]);
RNA_float_set(op->ptr, "depth", amounts[1]);
/* Modal numinput active, try to handle numeric inputs first... */
if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &opdata->num_input, event)) {
float amounts[2] = {RNA_float_get(op->ptr, "thickness"),
RNA_float_get(op->ptr, "depth")};
applyNumInput(&opdata->num_input, amounts);
amounts[0] = max_ff(amounts[0], 0.0f);
RNA_float_set(op->ptr, "thickness", amounts[0]);
RNA_float_set(op->ptr, "depth", amounts[1]);
if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
else {
edbm_inset_cancel(C, op);
return OPERATOR_CANCELLED;
}
if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
else {
edbm_inset_cancel(C, op);
return OPERATOR_CANCELLED;
}
}
else {
@ -327,7 +326,7 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event)
return OPERATOR_CANCELLED;
case MOUSEMOVE:
if (!hasNumInput(&opdata->num_input)) {
if (!has_numinput) {
float mdiff[2];
float amount;
@ -455,24 +454,22 @@ static int edbm_inset_modal(bContext *C, wmOperator *op, const wmEvent *event)
break;
}
if (!handled && event->val == KM_PRESS) {
/* Modal numinput inactive, try to handle numeric inputs last... */
if (handleNumInput(C, &opdata->num_input, event)) {
float amounts[2] = {RNA_float_get(op->ptr, "thickness"),
RNA_float_get(op->ptr, "depth")};
applyNumInput(&opdata->num_input, amounts);
amounts[0] = max_ff(amounts[0], 0.0f);
RNA_float_set(op->ptr, "thickness", amounts[0]);
RNA_float_set(op->ptr, "depth", amounts[1]);
/* Modal numinput inactive, try to handle numeric inputs last... */
if (!handled && event->val == KM_PRESS && handleNumInput(C, &opdata->num_input, event)) {
float amounts[2] = {RNA_float_get(op->ptr, "thickness"),
RNA_float_get(op->ptr, "depth")};
applyNumInput(&opdata->num_input, amounts);
amounts[0] = max_ff(amounts[0], 0.0f);
RNA_float_set(op->ptr, "thickness", amounts[0]);
RNA_float_set(op->ptr, "depth", amounts[1]);
if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
else {
edbm_inset_cancel(C, op);
return OPERATOR_CANCELLED;
}
if (edbm_inset_calc(op)) {
edbm_inset_update_header(op, C);
return OPERATOR_RUNNING_MODAL;
}
else {
edbm_inset_cancel(C, op);
return OPERATOR_CANCELLED;
}
}
}

View File

@ -555,39 +555,27 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
int cuts = RNA_int_get(op->ptr, "number_cuts");
RingSelOpData *lcd = op->customdata;
bool show_cuts = false;
const bool has_numinput = hasNumInput(&lcd->num);
view3d_operator_needs_opengl(C);
/* using the keyboard to input the number of cuts */
if (event->val == KM_PRESS && hasNumInput(&lcd->num)) {
/* Modal numinput active, try to handle numeric inputs first... */
if (handleNumInput(C, &lcd->num, event)) {
float values[2] = {(float)cuts, smoothness};
applyNumInput(&lcd->num, values);
/* allow zero so you can backspace and type in a value
* otherwise 1 as minimum would make more sense */
cuts = CLAMPIS(values[0], 0, SUBD_CUTS_MAX);
smoothness = CLAMPIS(values[1], -SUBD_SMOOTH_MAX, SUBD_SMOOTH_MAX);
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = true;
RNA_float_set(op->ptr, "smoothness", smoothness);
ED_region_tag_redraw(lcd->ar);
}
else {
switch (event->type) {
case RETKEY:
case PADENTER:
case LEFTMOUSE: /* confirm */ // XXX hardcoded
return loopcut_finish(lcd, C, op);
default:
/* do nothing */;
break;
}
}
/* Modal numinput active, try to handle numeric inputs first... */
if (event->val == KM_PRESS && has_numinput && handleNumInput(C, &lcd->num, event)) {
float values[2] = {(float)cuts, smoothness};
applyNumInput(&lcd->num, values);
/* allow zero so you can backspace and type in a value
* otherwise 1 as minimum would make more sense */
cuts = CLAMPIS(values[0], 0, SUBD_CUTS_MAX);
smoothness = CLAMPIS(values[1], -SUBD_SMOOTH_MAX, SUBD_SMOOTH_MAX);
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = true;
RNA_float_set(op->ptr, "smoothness", smoothness);
ED_region_tag_redraw(lcd->ar);
}
else {
bool handled = false;
@ -663,35 +651,33 @@ static int loopcut_modal(bContext *C, wmOperator *op, const wmEvent *event)
handled = true;
break;
case MOUSEMOVE: /* mouse moved somewhere to select another loop */
{
lcd->vc.mval[0] = event->mval[0];
lcd->vc.mval[1] = event->mval[1];
loopcut_mouse_move(lcd, cuts);
if (!has_numinput) {
lcd->vc.mval[0] = event->mval[0];
lcd->vc.mval[1] = event->mval[1];
loopcut_mouse_move(lcd, cuts);
ED_region_tag_redraw(lcd->ar);
handled = true;
ED_region_tag_redraw(lcd->ar);
handled = true;
}
break;
}
}
if (!handled && event->val == KM_PRESS) {
/* Modal numinput inactive, try to handle numeric inputs last... */
if (handleNumInput(C, &lcd->num, event)) {
float values[2] = {(float)cuts, smoothness};
applyNumInput(&lcd->num, values);
/* allow zero so you can backspace and type in a value
* otherwise 1 as minimum would make more sense */
cuts = CLAMPIS(values[0], 0, SUBD_CUTS_MAX);
smoothness = CLAMPIS(values[1], -SUBD_SMOOTH_MAX, SUBD_SMOOTH_MAX);
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = true;
RNA_float_set(op->ptr, "smoothness", smoothness);
ED_region_tag_redraw(lcd->ar);
}
/* Modal numinput inactive, try to handle numeric inputs last... */
if (!handled && event->val == KM_PRESS && handleNumInput(C, &lcd->num, event)) {
float values[2] = {(float)cuts, smoothness};
applyNumInput(&lcd->num, values);
/* allow zero so you can backspace and type in a value
* otherwise 1 as minimum would make more sense */
cuts = CLAMPIS(values[0], 0, SUBD_CUTS_MAX);
smoothness = CLAMPIS(values[1], -SUBD_SMOOTH_MAX, SUBD_SMOOTH_MAX);
RNA_int_set(op->ptr, "number_cuts", cuts);
ringsel_find_edge(lcd, cuts);
show_cuts = true;
RNA_float_set(op->ptr, "smoothness", smoothness);
ED_region_tag_redraw(lcd->ar);
}
}