diff options
Diffstat (limited to 'source/blender/editors/interface/interface_ops.c')
-rw-r--r-- | source/blender/editors/interface/interface_ops.c | 213 |
1 files changed, 167 insertions, 46 deletions
diff --git a/source/blender/editors/interface/interface_ops.c b/source/blender/editors/interface/interface_ops.c index 316a4d34881..817445cc14e 100644 --- a/source/blender/editors/interface/interface_ops.c +++ b/source/blender/editors/interface/interface_ops.c @@ -35,6 +35,7 @@ #include "DNA_text_types.h" /* for UI_OT_reports_to_text */ #include "BLI_blenlib.h" +#include "BLI_math_color.h" #include "BLF_api.h" #include "BLF_translation.h" @@ -44,6 +45,7 @@ #include "BKE_global.h" #include "BKE_text.h" /* for UI_OT_reports_to_text */ #include "BKE_report.h" +#include "BKE_paint.h" #include "RNA_access.h" #include "RNA_define.h" @@ -55,6 +57,8 @@ #include "WM_api.h" #include "WM_types.h" +#include "ED_paint.h" + /* only for UI_OT_editsource */ #include "ED_screen.h" #include "BKE_main.h" @@ -258,28 +262,43 @@ static void UI_OT_unset_property_button(wmOperatorType *ot) /* Copy To Selected Operator ------------------------ */ -static bool copy_to_selected_list(bContext *C, PointerRNA *ptr, ListBase *lb, bool *use_path) +static bool copy_to_selected_list( + bContext *C, PointerRNA *ptr, PropertyRNA *prop, + ListBase *r_lb, bool *r_use_path_from_id, char **r_path) { - *use_path = false; + *r_use_path_from_id = false; + *r_path = NULL; - if (RNA_struct_is_a(ptr->type, &RNA_EditBone)) - *lb = CTX_data_collection_get(C, "selected_editable_bones"); - else if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) - *lb = CTX_data_collection_get(C, "selected_pose_bones"); - else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) - *lb = CTX_data_collection_get(C, "selected_editable_sequences"); - else { + if (RNA_struct_is_a(ptr->type, &RNA_EditBone)) { + *r_lb = CTX_data_collection_get(C, "selected_editable_bones"); + } + else if (RNA_struct_is_a(ptr->type, &RNA_PoseBone)) { + *r_lb = CTX_data_collection_get(C, "selected_pose_bones"); + } + else if (RNA_struct_is_a(ptr->type, &RNA_Sequence)) { + *r_lb = CTX_data_collection_get(C, "selected_editable_sequences"); + } + else if (ptr->id.data) { ID *id = ptr->id.data; - if (id && GS(id->name) == ID_OB) { - *lb = CTX_data_collection_get(C, "selected_editable_objects"); - *use_path = true; + if (GS(id->name) == ID_OB) { + *r_lb = CTX_data_collection_get(C, "selected_editable_objects"); + *r_use_path_from_id = true; + *r_path = RNA_path_from_ID_to_property(ptr, prop); } - else { - return false; + else if (GS(id->name) == ID_SCE) { + /* Sequencer's ID is scene :/ */ + /* Try to recursively find an RNA_Sequence ancestor, to handle situations like T41062... */ + if ((*r_path = RNA_path_resolve_from_type_to_property(ptr, prop, &RNA_Sequence)) != NULL) { + *r_lb = CTX_data_collection_get(C, "selected_editable_sequences"); + } } + return (*r_path != NULL); } - + else { + return false; + } + return true; } @@ -303,47 +322,54 @@ static bool copy_to_selected_button(bContext *C, bool all, bool poll) /* if there is a valid property that is editable... */ if (ptr.data && prop) { char *path = NULL; - bool use_path; + bool use_path_from_id; CollectionPointerLink *link; ListBase lb; - if (!copy_to_selected_list(C, &ptr, &lb, &use_path)) + if (!copy_to_selected_list(C, &ptr, prop, &lb, &use_path_from_id, &path)) return success; - if (!use_path || (path = RNA_path_from_ID_to_property(&ptr, prop))) { - for (link = lb.first; link; link = link->next) { - if (link->ptr.data != ptr.data) { - if (use_path) { - lprop = NULL; - RNA_id_pointer_create(link->ptr.id.data, &idptr); - RNA_path_resolve_property(&idptr, path, &lptr, &lprop); - } - else { - lptr = link->ptr; - lprop = prop; - } + for (link = lb.first; link; link = link->next) { + if (link->ptr.data != ptr.data) { + if (use_path_from_id) { + /* Path relative to ID. */ + lprop = NULL; + RNA_id_pointer_create(link->ptr.id.data, &idptr); + RNA_path_resolve_property(&idptr, path, &lptr, &lprop); + } + else if (path) { + /* Path relative to elements from list. */ + lprop = NULL; + RNA_path_resolve_property(&link->ptr, path, &lptr, &lprop); + } + else { + lptr = link->ptr; + lprop = prop; + } - if (lprop == prop) { - if (RNA_property_editable(&lptr, lprop)) { - if (poll) { + if (lptr.data == ptr.data) { + /* lptr might not be the same as link->ptr! */ + continue; + } + + if (lprop == prop) { + if (RNA_property_editable(&lptr, lprop)) { + if (poll) { + success = true; + break; + } + else { + if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) { + RNA_property_update(C, &lptr, prop); success = true; - break; - } - else { - if (RNA_property_copy(&lptr, &ptr, prop, (all) ? -1 : index)) { - RNA_property_update(C, &lptr, prop); - success = true; - } } } } } } - - if (path) - MEM_freeN(path); } + MEM_SAFE_FREE(path); BLI_freelistN(&lb); } @@ -693,6 +719,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op) int ret = OPERATOR_CANCELLED; if (but) { + wmOperatorType *ot; PointerRNA ptr; char popath[FILE_MAX]; const char *root = U.i18ndir; @@ -714,7 +741,8 @@ static int edittranslation_exec(bContext *C, wmOperator *op) "Directory' path to a valid directory"); return OPERATOR_CANCELLED; } - if (!WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0)) { + ot = WM_operatortype_find(EDTSRC_I18N_OP_NAME, 0); + if (ot == NULL) { BKE_reportf(op->reports, RPT_ERROR, "Could not find operator '%s'! Please enable ui_translate addon " "in the User Preferences", EDTSRC_I18N_OP_NAME); return OPERATOR_CANCELLED; @@ -730,7 +758,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op) uiButGetStrInfo(C, but, &but_label, &rna_label, &enum_label, &but_tip, &rna_tip, &enum_tip, &rna_struct, &rna_prop, &rna_enum, &rna_ctxt, NULL); - WM_operator_properties_create(&ptr, EDTSRC_I18N_OP_NAME); + WM_operator_properties_create_ptr(&ptr, ot); RNA_string_set(&ptr, "lang", uilng); RNA_string_set(&ptr, "po_file", popath); RNA_string_set(&ptr, "but_label", but_label.strinfo); @@ -743,7 +771,7 @@ static int edittranslation_exec(bContext *C, wmOperator *op) RNA_string_set(&ptr, "rna_prop", rna_prop.strinfo); RNA_string_set(&ptr, "rna_enum", rna_enum.strinfo); RNA_string_set(&ptr, "rna_ctxt", rna_ctxt.strinfo); - ret = WM_operator_name_call(C, EDTSRC_I18N_OP_NAME, WM_OP_INVOKE_DEFAULT, &ptr); + ret = WM_operator_name_call_ptr(C, ot, WM_OP_INVOKE_DEFAULT, &ptr); /* Clean up */ if (but_label.strinfo) @@ -808,6 +836,99 @@ static void UI_OT_reloadtranslation(wmOperatorType *ot) ot->exec = reloadtranslation_exec; } +int UI_drop_color_poll(struct bContext *C, wmDrag *drag, const wmEvent *UNUSED(event)) +{ + /* should only return true for regions that include buttons, for now + * return true always */ + if (drag->type == WM_DRAG_COLOR) { + SpaceImage *sima = CTX_wm_space_image(C); + ARegion *ar = CTX_wm_region(C); + + if (UI_but_active_drop_color(C)) + return 1; + + if (sima && (sima->mode == SI_MODE_PAINT) && + sima->image && (ar && ar->regiontype == RGN_TYPE_WINDOW)) + { + return 1; + } + } + + return 0; +} + +void UI_drop_color_copy(wmDrag *drag, wmDropBox *drop) +{ + uiDragColorHandle *drag_info = (uiDragColorHandle *)drag->poin; + + RNA_float_set_array(drop->ptr, "color", drag_info->color); + RNA_boolean_set(drop->ptr, "gamma", drag_info->gamma_corrected); +} + +static int drop_color_invoke(bContext *C, wmOperator *op, const wmEvent *UNUSED(event)) +{ + ARegion *ar = CTX_wm_region(C); + uiBut *but = NULL; + float color[4]; + bool gamma; + + RNA_float_get_array(op->ptr, "color", color); + gamma = RNA_boolean_get(op->ptr, "gamma"); + + /* find button under mouse, check if it has RNA color property and + * if it does copy the data */ + but = ui_but_find_activated(ar); + + if (but && but->type == COLOR && but->rnaprop) { + const int color_len = RNA_property_array_length(&but->rnapoin, but->rnaprop); + BLI_assert(color_len <= 4); + + /* keep alpha channel as-is */ + if (color_len == 4) { + color[3] = RNA_property_float_get_index(&but->rnapoin, but->rnaprop, 3); + } + + if (RNA_property_subtype(but->rnaprop) == PROP_COLOR_GAMMA) { + if (!gamma) + ui_block_to_display_space_v3(but->block, color); + RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color); + RNA_property_update(C, &but->rnapoin, but->rnaprop); + } + else if (RNA_property_subtype(but->rnaprop) == PROP_COLOR) { + if (gamma) + ui_block_to_scene_linear_v3(but->block, color); + RNA_property_float_set_array(&but->rnapoin, but->rnaprop, color); + RNA_property_update(C, &but->rnapoin, but->rnaprop); + } + } + else { + if (gamma) { + srgb_to_linearrgb_v3_v3(color, color); + } + + ED_imapaint_bucket_fill(C, color, op); + } + + ED_region_tag_redraw(ar); + + return OPERATOR_FINISHED; +} + + +static void UI_OT_drop_color(wmOperatorType *ot) +{ + ot->name = "Drop Color"; + ot->idname = "UI_OT_drop_color"; + ot->description = "Drop colors to buttons"; + + ot->invoke = drop_color_invoke; + + RNA_def_float_color(ot->srna, "color", 3, NULL, 0.0, FLT_MAX, "Color", "Source color", 0.0, 1.0); + RNA_def_boolean(ot->srna, "gamma", 0, "Gamma Corrected", "The source color is gamma corrected "); +} + + + /* ********************************************************* */ /* Registration */ @@ -819,7 +940,7 @@ void UI_buttons_operatortypes(void) WM_operatortype_append(UI_OT_unset_property_button); WM_operatortype_append(UI_OT_copy_to_selected_button); WM_operatortype_append(UI_OT_reports_to_textblock); /* XXX: temp? */ - + WM_operatortype_append(UI_OT_drop_color); #ifdef WITH_PYTHON WM_operatortype_append(UI_OT_editsource); WM_operatortype_append(UI_OT_edittranslation_init); |