Refactor: Add BLF Function to determine input selection boxes
Add a separate function that calculates text selection box positioning given a string's selection start and end offsets. Moves this to a better place and allows to have more complex boxes in future when we might have multi-line and/or multi-directional text input. Pull Request: https://projects.blender.org/blender/blender/pulls/121448
This commit is contained in:
parent
31560ca26a
commit
ba36c69c9f
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_bounds_types.hh"
|
||||
#include "BLI_compiler_attrs.h"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_sys_types.h"
|
||||
@ -179,6 +180,13 @@ bool BLF_str_offset_to_glyph_bounds(int fontid,
|
||||
int BLF_str_offset_to_cursor(
|
||||
int fontid, const char *str, size_t str_len, size_t str_offset, float cursor_width);
|
||||
|
||||
/**
|
||||
* Return bounds of selection boxes. There is just one normally but there could
|
||||
* be more for multi-line and when containing text of differing directions.
|
||||
*/
|
||||
blender::Vector<blender::Bounds<int>> BLF_str_selection_boxes(
|
||||
int fontid, const char *str, size_t str_len, size_t sel_start, size_t sel_length);
|
||||
|
||||
/**
|
||||
* Get the string byte offset that fits within a given width.
|
||||
*/
|
||||
|
@ -638,6 +638,16 @@ int BLF_str_offset_to_cursor(
|
||||
return 0;
|
||||
}
|
||||
|
||||
blender::Vector<blender::Bounds<int>> BLF_str_selection_boxes(
|
||||
int fontid, const char *str, size_t str_len, size_t sel_start, size_t sel_length)
|
||||
{
|
||||
FontBLF *font = blf_get(fontid);
|
||||
if (font) {
|
||||
return blf_str_selection_boxes(font, str, str_len, sel_start, sel_length);
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
size_t BLF_width_to_strlen(
|
||||
int fontid, const char *str, const size_t str_len, float width, float *r_width)
|
||||
{
|
||||
|
@ -1119,6 +1119,16 @@ int blf_str_offset_to_cursor(
|
||||
return int(blf_font_width(font, str, str_len, nullptr));
|
||||
}
|
||||
|
||||
blender::Vector<blender::Bounds<int>> blf_str_selection_boxes(
|
||||
FontBLF *font, const char *str, size_t str_len, size_t sel_start, size_t sel_length)
|
||||
{
|
||||
blender::Vector<blender::Bounds<int>> boxes;
|
||||
const int start = blf_str_offset_to_cursor(font, str, str_len, sel_start, 0.0f);
|
||||
const int end = blf_str_offset_to_cursor(font, str, str_len, sel_start + sel_length, 0.0f);
|
||||
boxes.append(blender::Bounds(start, end));
|
||||
return boxes;
|
||||
}
|
||||
|
||||
/** \} */
|
||||
|
||||
/* -------------------------------------------------------------------- */
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "BLI_bounds_types.hh"
|
||||
#include "BLI_string_ref.hh"
|
||||
#include "BLI_vector.hh"
|
||||
|
||||
@ -144,6 +145,9 @@ void blf_str_offset_to_glyph_bounds(FontBLF *font,
|
||||
size_t str_offset,
|
||||
rcti *glyph_bounds);
|
||||
|
||||
blender::Vector<blender::Bounds<int>> blf_str_selection_boxes(
|
||||
FontBLF *font, const char *str, size_t str_len, size_t sel_start, size_t sel_length);
|
||||
|
||||
int blf_str_offset_to_cursor(
|
||||
FontBLF *font, const char *str, size_t str_len, size_t str_offset, float cursor_width);
|
||||
|
||||
|
@ -1937,51 +1937,37 @@ static void widget_draw_text(const uiFontStyle *fstyle,
|
||||
#endif
|
||||
|
||||
/* text button selection */
|
||||
if ((but->selend - but->selsta) > 0) {
|
||||
int selsta_draw, selwidth_draw;
|
||||
|
||||
if (drawstr[0] != 0) {
|
||||
/* We are drawing on top of widget bases. Flush cache. */
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
UI_widgetbase_draw_cache_flush();
|
||||
|
||||
if (but->selsta >= but->ofs) {
|
||||
selsta_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selsta - but->ofs);
|
||||
}
|
||||
else {
|
||||
selsta_draw = 0;
|
||||
}
|
||||
|
||||
selwidth_draw = BLF_width(fstyle->uifont_id, drawstr + but->ofs, but->selend - but->ofs);
|
||||
|
||||
uint pos = GPU_vertformat_attr_add(
|
||||
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
|
||||
rcti selection_shape;
|
||||
selection_shape.xmin = rect->xmin + selsta_draw;
|
||||
selection_shape.xmax = min_ii(rect->xmin + selwidth_draw, rect->xmax - 2);
|
||||
selection_shape.ymin = rect->ymin + U.pixelsize;
|
||||
selection_shape.ymax = rect->ymax - U.pixelsize;
|
||||
immUniformColor4ubv(wcol->item);
|
||||
if ((but->selend - but->selsta) != 0 && drawstr[0] != 0) {
|
||||
/* We are drawing on top of widget bases. Flush cache. */
|
||||
GPU_blend(GPU_BLEND_ALPHA);
|
||||
UI_widgetbase_draw_cache_flush();
|
||||
uint pos = GPU_vertformat_attr_add(
|
||||
immVertexFormat(), "pos", GPU_COMP_I32, 2, GPU_FETCH_INT_TO_FLOAT);
|
||||
immBindBuiltinProgram(GPU_SHADER_3D_UNIFORM_COLOR);
|
||||
immUniformColor4ubv(wcol->item);
|
||||
const auto boxes = BLF_str_selection_boxes(fstyle->uifont_id,
|
||||
drawstr,
|
||||
strlen(drawstr),
|
||||
but->ofs + but->selsta,
|
||||
but->selend - but->selsta);
|
||||
for (auto bounds : boxes) {
|
||||
immRecti(pos,
|
||||
selection_shape.xmin,
|
||||
selection_shape.ymin,
|
||||
selection_shape.xmax,
|
||||
selection_shape.ymax);
|
||||
|
||||
immUnbindProgram();
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
rect->xmin + bounds.min,
|
||||
rect->ymin + U.pixelsize,
|
||||
std::min(rect->xmin + bounds.max, rect->xmax - 2),
|
||||
rect->ymax - U.pixelsize);
|
||||
}
|
||||
immUnbindProgram();
|
||||
GPU_blend(GPU_BLEND_NONE);
|
||||
|
||||
#ifdef WITH_INPUT_IME
|
||||
/* IME candidate window uses selection position. */
|
||||
if (!ime_reposition_window) {
|
||||
ime_reposition_window = true;
|
||||
ime_win_x = selection_shape.xmin;
|
||||
ime_win_y = selection_shape.ymin;
|
||||
}
|
||||
#endif
|
||||
/* IME candidate window uses selection position. */
|
||||
if (!ime_reposition_window && boxes.size() > 0) {
|
||||
ime_reposition_window = true;
|
||||
ime_win_x = rect->xmin + boxes[0].min;
|
||||
ime_win_y = rect->ymin + U.pixelsize;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Text cursor position. */
|
||||
|
Loading…
Reference in New Issue
Block a user