UI: Select regions of text and toggle its style
1. Text can be selected along the mouse pointer by dragging the cursor . 2. After the selection we can toggle the style of the selected region. 3. Word can be selected using double click.
This commit is contained in:
@@ -364,10 +364,11 @@ class DATA_PT_font(CurveButtonsPanelText, Panel):
|
||||
row.prop(char, "use_underline", toggle=True)
|
||||
row.prop(char, "use_small_caps", toggle=True)
|
||||
else:
|
||||
layout.operator("font.style_toggle", text="Bold", icon='BOLD' , depress = text.select_is_bold).style = 'BOLD'
|
||||
layout.operator("font.style_toggle", text="Italic", icon='ITALIC' , depress = text.select_is_italics).style = 'ITALIC'
|
||||
layout.operator("font.style_toggle", text="Underline", icon='UNDERLINE' , depress = text.select_is_underline).style = 'UNDERLINE'
|
||||
layout.operator("font.style_toggle", text="Small Caps", icon='SMALL_CAPS' , depress = text.select_is_smallcaps).style = 'SMALL_CAPS'
|
||||
row = layout.row(align=True)
|
||||
row.operator("font.style_toggle", text="Bold", icon='BOLD' , depress = text.select_is_bold).style = 'BOLD'
|
||||
row.operator("font.style_toggle", text="Italic", icon='ITALIC' , depress = text.select_is_italics).style = 'ITALIC'
|
||||
row.operator("font.style_toggle", text="Underline", icon='UNDERLINE' , depress = text.select_is_underline).style = 'UNDERLINE'
|
||||
row.operator("font.style_toggle", text="Small Caps", icon='SMALL_CAPS' , depress = text.select_is_smallcaps).style = 'SMALL_CAPS'
|
||||
|
||||
|
||||
class DATA_PT_font_transform(CurveButtonsPanelText, Panel):
|
||||
|
@@ -82,6 +82,19 @@ bool BKE_vfont_to_curve_ex(struct Object *ob,
|
||||
bool *r_text_free,
|
||||
struct CharTrans **r_chartransdata);
|
||||
bool BKE_vfont_to_curve_nubase(struct Object *ob, int mode, struct ListBase *r_nubase);
|
||||
|
||||
bool BKE_vfont_to_curve_ex2(struct Object *ob,
|
||||
struct Curve *cu,
|
||||
int mode,
|
||||
struct ListBase *r_nubase,
|
||||
const char32_t **r_text,
|
||||
int *r_text_len,
|
||||
bool *r_text_free,
|
||||
struct CharTrans **r_chartransdata,
|
||||
float cursor_location[2], int *r_cursor_locaiton_pos);
|
||||
|
||||
bool BKE_vfont_to_curve_curloc(struct Object *ob, int mode,float cursor_location[2], int *r_cursor_locaiton_pos);
|
||||
|
||||
/**
|
||||
* \warning Expects to have access to evaluated data (i.e. passed object should be evaluated one).
|
||||
*/
|
||||
|
@@ -765,7 +765,7 @@ static float vfont_descent(const VFontData *vfd)
|
||||
return vfd->em_height - vfont_ascent(vfd);
|
||||
}
|
||||
|
||||
static bool vfont_to_curve(Object *ob,
|
||||
static bool vfont_to_curve_ex(Object *ob,
|
||||
Curve *cu,
|
||||
int mode,
|
||||
VFontToCurveIter *iter_data,
|
||||
@@ -773,7 +773,8 @@ static bool vfont_to_curve(Object *ob,
|
||||
const char32_t **r_text,
|
||||
int *r_text_len,
|
||||
bool *r_text_free,
|
||||
struct CharTrans **r_chartransdata)
|
||||
struct CharTrans **r_chartransdata,
|
||||
float cursor_location[2], int *r_cursor_locaiton_pos)
|
||||
{
|
||||
EditFont *ef = cu->editfont;
|
||||
EditFontSelBox *selboxes = NULL;
|
||||
@@ -826,6 +827,14 @@ static bool vfont_to_curve(Object *ob,
|
||||
return ok;
|
||||
}
|
||||
|
||||
if(cursor_location==NULL)
|
||||
{
|
||||
float cur_loc_temp[2];
|
||||
cur_loc_temp[0]=0.0;
|
||||
cur_loc_temp[1]=0.0;
|
||||
cursor_location=cur_loc_temp;
|
||||
}
|
||||
|
||||
vfd = vfont_get_data(vfont);
|
||||
|
||||
/* The VFont Data can not be found */
|
||||
@@ -908,8 +917,13 @@ static bool vfont_to_curve(Object *ob,
|
||||
}
|
||||
|
||||
i = 0;
|
||||
int ret=0;
|
||||
float min_dist=0.0f;
|
||||
int ret=-1;
|
||||
float min_dist;
|
||||
if(ef!=NULL && ob!=NULL)
|
||||
{ float ffx=cursor_location[0];
|
||||
float ffy=cursor_location[1];
|
||||
min_dist=ffx*ffx+ffy*ffy;
|
||||
}
|
||||
while (i <= slen) {
|
||||
/* Characters in the list */
|
||||
info = &custrinfo[i];
|
||||
@@ -1125,33 +1139,39 @@ static bool vfont_to_curve(Object *ob,
|
||||
}
|
||||
ct++;
|
||||
if (ef != NULL && ob != NULL){
|
||||
float fx=ef->m_loc[0];
|
||||
float fy=ef->m_loc[1];
|
||||
float fx=cursor_location[0];
|
||||
float fy=cursor_location[1];
|
||||
float di= (fx-xof)*(fx-xof)+(fy-yof)*(fy-yof);
|
||||
if(i==0)
|
||||
float di2=fx*fx+fy*fy;
|
||||
|
||||
if(di2<=min_dist && di2<di)
|
||||
{
|
||||
min_dist=di;
|
||||
ret=i;
|
||||
min_dist=di2;
|
||||
ret=-1;
|
||||
}
|
||||
if(di<min_dist)
|
||||
else if(di<min_dist)
|
||||
{
|
||||
min_dist=di;
|
||||
ret=i;
|
||||
}
|
||||
|
||||
}
|
||||
i++;
|
||||
}
|
||||
if (ef != NULL && ob != NULL)
|
||||
{
|
||||
if(ret==0)
|
||||
|
||||
if(ret==-1)
|
||||
{
|
||||
ret++;
|
||||
ef->m_pos=ret;
|
||||
if(r_cursor_locaiton_pos)
|
||||
*r_cursor_locaiton_pos=ret;
|
||||
}
|
||||
else if(ret>0 && ret<=ef->len-1)
|
||||
else if(ret>=0 && ret<=ef->len-1)
|
||||
{
|
||||
ret++;
|
||||
ef->m_pos=ret;
|
||||
if(r_cursor_locaiton_pos)
|
||||
*r_cursor_locaiton_pos=ret;
|
||||
}
|
||||
}
|
||||
current_line_length += xof + twidth - MARGIN_X_MIN;
|
||||
@@ -1754,6 +1774,20 @@ finally:
|
||||
#undef MARGIN_Y_MIN
|
||||
}
|
||||
|
||||
|
||||
static bool vfont_to_curve(Object *ob,
|
||||
Curve *cu,
|
||||
int mode,
|
||||
VFontToCurveIter *iter_data,
|
||||
ListBase *r_nubase,
|
||||
const char32_t **r_text,
|
||||
int *r_text_len,
|
||||
bool *r_text_free,
|
||||
struct CharTrans **r_chartransdata)
|
||||
{
|
||||
return vfont_to_curve_ex(ob,cu,mode,iter_data,r_nubase,r_text,r_text_len,r_text_free,r_chartransdata,NULL,NULL);
|
||||
|
||||
}
|
||||
#undef DESCENT
|
||||
#undef ASCENT
|
||||
|
||||
@@ -1775,8 +1809,34 @@ bool BKE_vfont_to_curve_ex(Object *ob,
|
||||
};
|
||||
|
||||
do {
|
||||
data.ok &= vfont_to_curve(
|
||||
ob, cu, mode, &data, r_nubase, r_text, r_text_len, r_text_free, r_chartransdata);
|
||||
data.ok &= vfont_to_curve_ex(
|
||||
ob, cu, mode, &data, r_nubase, r_text, r_text_len, r_text_free, r_chartransdata,NULL,NULL);
|
||||
} while (data.ok && ELEM(data.status, VFONT_TO_CURVE_SCALE_ONCE, VFONT_TO_CURVE_BISECT));
|
||||
|
||||
return data.ok;
|
||||
}
|
||||
|
||||
bool BKE_vfont_to_curve_ex2(Object *ob,
|
||||
Curve *cu,
|
||||
int mode,
|
||||
ListBase *r_nubase,
|
||||
const char32_t **r_text,
|
||||
int *r_text_len,
|
||||
bool *r_text_free,
|
||||
struct CharTrans **r_chartransdata,
|
||||
float cursor_location[2], int *r_cursor_locaiton_pos)
|
||||
{
|
||||
VFontToCurveIter data = {
|
||||
.iteraction = cu->totbox * FONT_TO_CURVE_SCALE_ITERATIONS,
|
||||
.scale_to_fit = 1.0f,
|
||||
.word_wrap = true,
|
||||
.ok = true,
|
||||
.status = VFONT_TO_CURVE_INIT,
|
||||
};
|
||||
|
||||
do {
|
||||
data.ok &= vfont_to_curve_ex(
|
||||
ob, cu, mode, &data, r_nubase, r_text, r_text_len, r_text_free, r_chartransdata,cursor_location,r_cursor_locaiton_pos);
|
||||
} while (data.ok && ELEM(data.status, VFONT_TO_CURVE_SCALE_ONCE, VFONT_TO_CURVE_BISECT));
|
||||
|
||||
return data.ok;
|
||||
@@ -1799,6 +1859,13 @@ bool BKE_vfont_to_curve(Object *ob, int mode)
|
||||
return BKE_vfont_to_curve_ex(ob, ob->data, mode, &cu->nurb, NULL, NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
bool BKE_vfont_to_curve_curloc(Object *ob, int mode,float cursor_location[2], int *r_cursor_locaiton_pos)
|
||||
{
|
||||
Curve *cu = ob->data;
|
||||
|
||||
return BKE_vfont_to_curve_ex2(ob,ob->data,mode,&cu->nurb,NULL,NULL,NULL,NULL,cursor_location,r_cursor_locaiton_pos);
|
||||
}
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name VFont Clipboard
|
||||
* \{ */
|
||||
|
@@ -423,6 +423,29 @@ static void text_update_edited(bContext *C, Object *obedit, int mode)
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||
}
|
||||
|
||||
static void text_update_edited_ex(bContext *C, Object *obedit, int mode,float cursor_location[2], int *r_cursor_locaiton_pos)
|
||||
{
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
|
||||
BLI_assert(ef->len >= 0);
|
||||
Depsgraph *depsgraph = CTX_data_ensure_evaluated_depsgraph(C);
|
||||
BKE_vfont_to_curve_curloc(DEG_get_evaluated_object(depsgraph, obedit), mode,cursor_location,r_cursor_locaiton_pos);
|
||||
|
||||
cu->curinfo = ef->textbufinfo[ef->pos ? ef->pos - 1 : 0];
|
||||
|
||||
if (obedit->totcol > 0) {
|
||||
obedit->actcol = cu->curinfo.mat_nr;
|
||||
if (obedit->actcol < 1) {
|
||||
obedit->actcol = 1;
|
||||
}
|
||||
}
|
||||
|
||||
DEG_id_tag_update(obedit->data, ID_RECALC_SELECT);
|
||||
WM_event_add_notifier(C, NC_GEOM | ND_DATA, obedit->data);
|
||||
}
|
||||
|
||||
|
||||
static int kill_selection(Object *obedit, int ins) /* ins == new character len */
|
||||
{
|
||||
Curve *cu = obedit->data;
|
||||
@@ -1759,33 +1782,39 @@ void FONT_OT_text_insert(wmOperatorType *ot)
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Font Select Operator
|
||||
* \{ */
|
||||
static void font_cursor_set_apply(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
static void font_cursor_set_apply(bContext *C, const wmEvent *event)
|
||||
{
|
||||
Object *obedit = CTX_data_active_object(C);
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
ARegion *region = CTX_wm_region(C);
|
||||
int cur_loc_pos;
|
||||
float rout[3];
|
||||
float mal[2];
|
||||
mal[0]=event->mval[0];
|
||||
mal[1]=event->mval[1];
|
||||
const float *co = obedit->obmat[3];
|
||||
const float *no = obedit->obmat[2]; /* Z axis. */
|
||||
const float *no = obedit->obmat[2];
|
||||
float plane[4];
|
||||
plane_from_point_normal_v3(plane, co, no);
|
||||
ED_view3d_win_to_3d_on_plane(region,plane,mal,true,rout);
|
||||
mul_m4_v3(obedit->imat, rout);
|
||||
ef->m_loc[0]=rout[0];
|
||||
ef->m_loc[1]=rout[1];
|
||||
ef->pos=ef->m_pos;
|
||||
if ((select) && (ef->selstart==0)) {
|
||||
if(ef->pos==0)
|
||||
ef->selstart = ef->selend =1;
|
||||
else
|
||||
ef->selstart = ef->selend = ef->pos+1;
|
||||
float curs_loc[2];
|
||||
curs_loc[0]=rout[0];
|
||||
curs_loc[1]=rout[1];
|
||||
|
||||
text_update_edited_ex(C, obedit, FO_CURS,curs_loc,&cur_loc_pos);
|
||||
if(cur_loc_pos<=ef->len)
|
||||
{
|
||||
if ((!ef->is_selected) && (ef->selstart==0)) {
|
||||
if(ef->pos==0)
|
||||
ef->selstart = ef->selend =1;
|
||||
else
|
||||
ef->selstart = ef->selend = cur_loc_pos+1;
|
||||
}
|
||||
ef->selend=cur_loc_pos;
|
||||
ef->pos=cur_loc_pos;
|
||||
}
|
||||
ef->selend=ef->pos;
|
||||
text_update_edited(C, obedit, true);
|
||||
|
||||
}
|
||||
|
||||
@@ -1795,32 +1824,26 @@ static int font_selection_set_invoke(bContext *C, wmOperator *op, const wmEvent
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
font_cursor_set_apply(C, op, event);
|
||||
font_cursor_set_apply(C, event);
|
||||
ef->selstart=0;
|
||||
ef->selend=0;
|
||||
|
||||
text_update_edited(C, obedit, true);
|
||||
WM_event_add_modal_handler(C, op);
|
||||
|
||||
return OPERATOR_RUNNING_MODAL;
|
||||
}
|
||||
|
||||
static int font_selection_set_modal(bContext *C, wmOperator *op, const wmEvent *event)
|
||||
static int font_selection_set_modal(bContext *C, wmOperator *UNUSED(op), const wmEvent *event)
|
||||
{
|
||||
Object *obedit = CTX_data_active_object(C);
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
|
||||
switch (event->type) {
|
||||
case LEFTMOUSE:
|
||||
font_cursor_set_apply(C, op, event);
|
||||
font_cursor_set_apply(C, event);
|
||||
return OPERATOR_FINISHED;
|
||||
case MIDDLEMOUSE:
|
||||
case RIGHTMOUSE:
|
||||
return OPERATOR_FINISHED;
|
||||
case TIMER:
|
||||
case MOUSEMOVE:
|
||||
font_cursor_set_apply(C, op, event);
|
||||
font_cursor_set_apply(C, event);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1843,13 +1866,10 @@ void FONT_OT_selection_set(struct wmOperatorType *ot)
|
||||
/* -------------------------------------------------------------------- */
|
||||
/** \name Select Word Operator
|
||||
* \{ */
|
||||
static font_select_word_exec(bContext *C, wmOperator *op)
|
||||
static int font_select_word_exec(bContext *C, wmOperator *UNUSED(op))
|
||||
{
|
||||
Object *obedit = CTX_data_active_object(C);
|
||||
Curve *cu = obedit->data;
|
||||
EditFont *ef = cu->editfont;
|
||||
|
||||
move_cursor(C,PREV_WORD,false)+move_cursor(C,NEXT_WORD,true);
|
||||
move_cursor(C,PREV_WORD,false);
|
||||
move_cursor(C,NEXT_WORD,true);
|
||||
return OPERATOR_FINISHED;
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user