diff --git a/source/blender/blenkernel/BKE_screen.h b/source/blender/blenkernel/BKE_screen.h index 188b8e22815..4c11ec9923d 100644 --- a/source/blender/blenkernel/BKE_screen.h +++ b/source/blender/blenkernel/BKE_screen.h @@ -280,6 +280,7 @@ void BKE_screen_area_free(struct ScrArea *sa); struct ARegion *BKE_area_find_region_type(struct ScrArea *sa, int type); struct ARegion *BKE_area_find_region_active_win(struct ScrArea *sa); +struct ScrArea *BKE_screen_find_area_from_space(struct bScreen *sc, struct SpaceLink *sl) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2); struct ScrArea *BKE_screen_find_big_area(struct bScreen *sc, const int spacetype, const short min); unsigned int BKE_screen_view3d_layer_active_ex( diff --git a/source/blender/blenkernel/intern/screen.c b/source/blender/blenkernel/intern/screen.c index b2296151cf7..ad4ed5a0b99 100644 --- a/source/blender/blenkernel/intern/screen.c +++ b/source/blender/blenkernel/intern/screen.c @@ -402,6 +402,23 @@ ARegion *BKE_area_find_region_active_win(ScrArea *sa) return NULL; } +/** + * \note, ideally we can get the area from the context, + * there are a few places however where this isn't practical. + */ +ScrArea *BKE_screen_find_area_from_space(struct bScreen *sc, SpaceLink *sl) +{ + ScrArea *sa; + + for (sa = sc->areabase.first; sa; sa = sa->next) { + if (BLI_findindex(&sa->spacedata, sl) != -1) { + break; + } + } + + return sa; +} + /* note, using this function is generally a last resort, you really want to be * using the context when you can - campbell * -1 for any type */ diff --git a/source/blender/editors/include/ED_text.h b/source/blender/editors/include/ED_text.h index 9a36cb3d6ab..5df7d9cfaef 100644 --- a/source/blender/editors/include/ED_text.h +++ b/source/blender/editors/include/ED_text.h @@ -31,8 +31,11 @@ #define __ED_TEXT_H__ struct bContext; +struct SpaceText; +struct ARegion; void ED_text_undo_step(struct bContext *C, int step); +bool ED_text_region_location_from_cursor(struct SpaceText *st, struct ARegion *ar, const int cursor_co[2], int r_pixel_co[2]); #endif /* __ED_TEXT_H__ */ diff --git a/source/blender/editors/space_text/text_draw.c b/source/blender/editors/space_text/text_draw.c index a43d430045e..ed1cbec8fbf 100644 --- a/source/blender/editors/space_text/text_draw.c +++ b/source/blender/editors/space_text/text_draw.c @@ -44,6 +44,8 @@ #include "BKE_text.h" #include "BKE_screen.h" +#include "ED_text.h" + #include "BIF_gl.h" #include "UI_interface.h" @@ -1547,3 +1549,37 @@ void text_update_cursor_moved(bContext *C) text_scroll_to_cursor__area(st, sa, true); } + +/** + * Takes a cursor (row, character) and returns x,y pixel coords. + */ +bool ED_text_region_location_from_cursor(SpaceText *st, ARegion* ar, const int cursor_co[2], int r_pixel_co[2]) +{ + TextLine *line = NULL; + + if (!st->text) { + goto error; + } + + line = BLI_findlink(&st->text->lines, cursor_co[0]); + if (!line || (cursor_co[1] < 0) || (cursor_co[1] > line->len)) { + goto error; + } + else { + int offl, offc; + int linenr_offset = st->showlinenrs ? TXT_OFFSET + TEXTXLOC : TXT_OFFSET; + /* handle tabs as well! */ + int char_pos = text_get_char_pos(st, line->line, cursor_co[1]); + + wrap_offset(st, ar, line, cursor_co[1], &offl, &offc); + r_pixel_co[0] = (char_pos + offc - st->left) * st->cwidth + linenr_offset; + r_pixel_co[1] = (cursor_co[0] + offl - st->top) * (st->lheight_dpi + TXT_LINE_SPACING); + r_pixel_co[1] = (ar->winy - (r_pixel_co[1] + TXT_OFFSET)) - st->lheight_dpi; + } + return true; + + +error: + r_pixel_co[0] = r_pixel_co[1] = -1; + return false; +} diff --git a/source/blender/makesrna/intern/rna_internal.h b/source/blender/makesrna/intern/rna_internal.h index 051e7277425..64a50d42144 100644 --- a/source/blender/makesrna/intern/rna_internal.h +++ b/source/blender/makesrna/intern/rna_internal.h @@ -287,6 +287,7 @@ void RNA_api_ui_layout(struct StructRNA *srna); void RNA_api_window(struct StructRNA *srna); void RNA_api_wm(struct StructRNA *srna); void RNA_api_space_node(struct StructRNA *srna); +void RNA_api_space_text(struct StructRNA *srna); void RNA_api_region_view3d(struct StructRNA *srna); void RNA_api_sensor(struct StructRNA *srna); void RNA_api_controller(struct StructRNA *srna); diff --git a/source/blender/makesrna/intern/rna_space.c b/source/blender/makesrna/intern/rna_space.c index cda6a779421..7ad7f129218 100644 --- a/source/blender/makesrna/intern/rna_space.c +++ b/source/blender/makesrna/intern/rna_space.c @@ -266,13 +266,7 @@ static ScrArea *rna_area_from_space(PointerRNA *ptr) { bScreen *sc = (bScreen *)ptr->id.data; SpaceLink *link = (SpaceLink *)ptr->data; - ScrArea *sa; - - for (sa = sc->areabase.first; sa; sa = sa->next) - if (BLI_findindex(&sa->spacedata, link) != -1) - return sa; - - return NULL; + return BKE_screen_find_area_from_space(sc, link); } static void area_region_from_regiondata(bScreen *sc, void *regiondata, ScrArea **r_sa, ARegion **r_ar) @@ -856,7 +850,6 @@ static void rna_SpaceTextEditor_updateEdited(Main *UNUSED(bmain), Scene *UNUSED( WM_main_add_notifier(NC_TEXT | NA_EDITED, st->text); } - /* Space Properties */ /* note: this function exists only to avoid id refcounting */ @@ -2748,6 +2741,8 @@ static void rna_def_space_text(BlenderRNA *brna) RNA_def_property_string_sdna(prop, NULL, "replacestr"); RNA_def_property_ui_text(prop, "Replace Text", "Text to replace selected text with using the replace tool"); RNA_def_property_update(prop, NC_SPACE | ND_SPACE_TEXT, NULL); + + RNA_api_space_text(srna); } static void rna_def_space_dopesheet(BlenderRNA *brna) diff --git a/source/blender/makesrna/intern/rna_space_api.c b/source/blender/makesrna/intern/rna_space_api.c index aed77378241..4114ee8a289 100644 --- a/source/blender/makesrna/intern/rna_space_api.c +++ b/source/blender/makesrna/intern/rna_space_api.c @@ -31,6 +31,8 @@ #ifdef RNA_RUNTIME +#include "ED_text.h" + static void rna_RegionView3D_update(ID *id, RegionView3D *rv3d) { bScreen *sc = (bScreen *)id; @@ -49,6 +51,19 @@ static void rna_RegionView3D_update(ID *id, RegionView3D *rv3d) } } +static void rna_SpaceTextEditor_region_location_from_cursor( + ID *id, SpaceText *st, + int line, int column, int r_pixel_pos[2]) +{ + bScreen *sc = (bScreen *)id; + ScrArea *sa = BKE_screen_find_area_from_space(sc, (SpaceLink *)st); + if (sa) { + ARegion *ar = BKE_area_find_region_type(sa, RGN_TYPE_WINDOW); + const int cursor_co[2] = {line, column}; + ED_text_region_location_from_cursor(st, ar, cursor_co, r_pixel_pos); + } +} + #else void RNA_api_region_view3d(StructRNA *srna) @@ -74,4 +89,20 @@ void RNA_api_space_node(StructRNA *srna) RNA_def_property_flag(parm, PROP_REQUIRED); } +void RNA_api_space_text(StructRNA *srna) +{ + FunctionRNA *func; + PropertyRNA *parm; + + func = RNA_def_function(srna, "region_location_from_cursor", "rna_SpaceTextEditor_region_location_from_cursor"); + RNA_def_function_ui_description(func, "Retrieve the region position from the given line and character position"); + RNA_def_function_flag(func, FUNC_USE_SELF_ID); + parm = RNA_def_int(func, "line", 0, INT_MIN, INT_MAX, "Line", "Line index", 0, INT_MAX); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int(func, "column", 0, INT_MIN, INT_MAX, "Column", "Column index", 0, INT_MAX); + RNA_def_property_flag(parm, PROP_REQUIRED); + parm = RNA_def_int_array(func, "result", 2, 0, -1, INT_MAX, "", "Region coordinates", -1, INT_MAX); + RNA_def_function_output(func, parm); +} + #endif diff --git a/source/blenderplayer/bad_level_call_stubs/stubs.c b/source/blenderplayer/bad_level_call_stubs/stubs.c index 954e431dbd2..8a7c761915f 100644 --- a/source/blenderplayer/bad_level_call_stubs/stubs.c +++ b/source/blenderplayer/bad_level_call_stubs/stubs.c @@ -163,6 +163,7 @@ struct wmWindowManager; #include "../blender/editors/include/ED_render.h" #include "../blender/editors/include/ED_screen.h" #include "../blender/editors/include/ED_space_api.h" +#include "../blender/editors/include/ED_text.h" #include "../blender/editors/include/ED_transform.h" #include "../blender/editors/include/ED_uvedit.h" #include "../blender/editors/include/ED_view3d.h" @@ -482,6 +483,8 @@ bool ED_texture_context_check_lamp(const struct bContext *C) RET_ZERO bool ED_texture_context_check_particles(const struct bContext *C) RET_ZERO bool ED_texture_context_check_others(const struct bContext *C) RET_ZERO +bool ED_text_region_location_from_cursor(SpaceText *st, ARegion *ar, const int cursor_co[2], int r_pixel_co[2]) RET_ZERO + bool snapObjectsRayEx(struct Scene *scene, struct Base *base_act, struct View3D *v3d, struct ARegion *ar, struct Object *obedit, short snap_mode, struct Object **r_ob, float r_obmat[4][4], const float ray_start[3], const float ray_normal[3], float *r_ray_dist,