mirror of https://github.com/OpenTTD/OpenTTD.git
(svn r25691) -Add: [OSX] Support for mouse selection in the IME composition string.
This commit is contained in:
parent
e2ec0ddb03
commit
30867c487f
|
@ -351,12 +351,21 @@ struct IConsoleWindow : Window
|
||||||
int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
|
int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
|
||||||
|
|
||||||
Point p1 = GetCharPosInString(_iconsole_cmdline.buf, from, FS_NORMAL);
|
Point p1 = GetCharPosInString(_iconsole_cmdline.buf, from, FS_NORMAL);
|
||||||
Point p2 = from != to ? GetCharPosInString(_iconsole_cmdline.buf, from, FS_NORMAL) : p1;
|
Point p2 = from != to ? GetCharPosInString(_iconsole_cmdline.buf, from) : p1;
|
||||||
|
|
||||||
Rect r = {this->line_offset + delta + p1.x, this->height - this->line_height, this->line_offset + delta + p2.x, this->height};
|
Rect r = {this->line_offset + delta + p1.x, this->height - this->line_height, this->line_offset + delta + p2.x, this->height};
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
virtual const char *GetTextCharacterAtPosition(const Point &pt) const
|
||||||
|
{
|
||||||
|
int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
|
||||||
|
|
||||||
|
if (!IsInsideMM(pt.y, this->height - this->line_height, this->height)) return NULL;
|
||||||
|
|
||||||
|
return GetCharAtPosition(_iconsole_cmdline.buf, pt.x - delta);
|
||||||
|
}
|
||||||
|
|
||||||
virtual void OnMouseWheel(int wheel)
|
virtual void OnMouseWheel(int wheel)
|
||||||
{
|
{
|
||||||
this->Scroll(-wheel);
|
this->Scroll(-wheel);
|
||||||
|
|
15
src/gfx.cpp
15
src/gfx.cpp
|
@ -721,6 +721,21 @@ Point GetCharPosInString(const char *str, const char *ch, FontSize start_fontsiz
|
||||||
return layout.GetCharPosition(ch);
|
return layout.GetCharPosition(ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the character from a string that is drawn at a specific position.
|
||||||
|
* @param str String to test.
|
||||||
|
* @param x Position relative to the start of the string.
|
||||||
|
* @param start_fontsize Font size to start the text with.
|
||||||
|
* @return Pointer to the character at the position or NULL if there is no character at the position.
|
||||||
|
*/
|
||||||
|
const char *GetCharAtPosition(const char *str, int x, FontSize start_fontsize)
|
||||||
|
{
|
||||||
|
if (x < 0) return NULL;
|
||||||
|
|
||||||
|
Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize);
|
||||||
|
return layout.GetCharAtPosition(x);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Draw single character horizontally centered around (x,y)
|
* Draw single character horizontally centered around (x,y)
|
||||||
* @param c Character (glyph) to draw
|
* @param c Character (glyph) to draw
|
||||||
|
|
|
@ -129,6 +129,7 @@ Dimension GetStringMultiLineBoundingBox(StringID str, const Dimension &suggestio
|
||||||
Dimension GetStringMultiLineBoundingBox(const char *str, const Dimension &suggestion);
|
Dimension GetStringMultiLineBoundingBox(const char *str, const Dimension &suggestion);
|
||||||
void LoadStringWidthTable(bool monospace = false);
|
void LoadStringWidthTable(bool monospace = false);
|
||||||
Point GetCharPosInString(const char *str, const char *ch, FontSize start_fontsize = FS_NORMAL);
|
Point GetCharPosInString(const char *str, const char *ch, FontSize start_fontsize = FS_NORMAL);
|
||||||
|
const char *GetCharAtPosition(const char *str, int x, FontSize start_fontsize = FS_NORMAL);
|
||||||
|
|
||||||
void DrawDirtyBlocks();
|
void DrawDirtyBlocks();
|
||||||
void SetDirtyBlocks(int left, int top, int right, int bottom);
|
void SetDirtyBlocks(int left, int top, int right, int bottom);
|
||||||
|
|
|
@ -565,6 +565,50 @@ Point Layouter::GetCharPosition(const char *ch) const
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the character that is at a position.
|
||||||
|
* @param x Position in the string.
|
||||||
|
* @return Pointer to the character at the position or NULL if no character is at the position.
|
||||||
|
*/
|
||||||
|
const char *Layouter::GetCharAtPosition(int x) const
|
||||||
|
{
|
||||||
|
const ParagraphLayout::Line *line = *this->Begin();;
|
||||||
|
|
||||||
|
for (int run_index = 0; run_index < line->countRuns(); run_index++) {
|
||||||
|
const ParagraphLayout::VisualRun *run = line->getVisualRun(run_index);
|
||||||
|
|
||||||
|
for (int i = 0; i < run->getGlyphCount(); i++) {
|
||||||
|
/* Not a valid glyph (empty). */
|
||||||
|
if (run->getGlyphs()[i] == 0xFFFF) continue;
|
||||||
|
|
||||||
|
int begin_x = run->getPositions()[i * 2];
|
||||||
|
int end_x = run->getPositions()[i * 2 + 2];
|
||||||
|
|
||||||
|
if (IsInsideMM(x, begin_x, end_x)) {
|
||||||
|
/* Found our glyph, now convert to UTF-8 string index. */
|
||||||
|
size_t index = run->getGlyphToCharMap()[i];
|
||||||
|
|
||||||
|
size_t cur_idx = 0;
|
||||||
|
for (const char *str = this->string; *str != '\0'; ) {
|
||||||
|
if (cur_idx == index) return str;
|
||||||
|
|
||||||
|
WChar c;
|
||||||
|
size_t len = Utf8Decode(&c, str);
|
||||||
|
#ifdef WITH_ICU
|
||||||
|
/* ICU uses UTF-16 internally which means we need to account for surrogate pairs. */
|
||||||
|
cur_idx += len < 4 ? 1 : 2;
|
||||||
|
#else
|
||||||
|
cur_idx++;
|
||||||
|
#endif
|
||||||
|
str += len;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a static font instance.
|
* Get a static font instance.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -212,6 +212,7 @@ public:
|
||||||
Layouter(const char *str, int maxw = INT32_MAX, TextColour colour = TC_FROMSTRING, FontSize fontsize = FS_NORMAL);
|
Layouter(const char *str, int maxw = INT32_MAX, TextColour colour = TC_FROMSTRING, FontSize fontsize = FS_NORMAL);
|
||||||
Dimension GetBounds();
|
Dimension GetBounds();
|
||||||
Point GetCharPosition(const char *ch) const;
|
Point GetCharPosition(const char *ch) const;
|
||||||
|
const char *GetCharAtPosition(int x) const;
|
||||||
|
|
||||||
static void ResetFontCache(FontSize size);
|
static void ResetFontCache(FontSize size);
|
||||||
static void ResetLineCache();
|
static void ResetLineCache();
|
||||||
|
|
|
@ -854,6 +854,39 @@ Rect QueryString::GetBoundingRect(const Window *w, int wid, const char *from, co
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the character that is rendered at a position.
|
||||||
|
* @param w Window the edit box is in.
|
||||||
|
* @param wid Widget index.
|
||||||
|
* @param pt Position to test.
|
||||||
|
* @return Pointer to the character at the position or NULL if no character is at the position.
|
||||||
|
*/
|
||||||
|
const char *QueryString::GetCharAtPosition(const Window *w, int wid, const Point &pt) const
|
||||||
|
{
|
||||||
|
const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
|
||||||
|
|
||||||
|
assert((wi->type & WWT_MASK) == WWT_EDITBOX);
|
||||||
|
|
||||||
|
bool rtl = _current_text_dir == TD_RTL;
|
||||||
|
Dimension sprite_size = GetSpriteSize(rtl ? SPR_IMG_DELETE_RIGHT : SPR_IMG_DELETE_LEFT);
|
||||||
|
int clearbtn_width = sprite_size.width + WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT;
|
||||||
|
|
||||||
|
int left = wi->pos_x + (rtl ? clearbtn_width : 0);
|
||||||
|
int right = wi->pos_x + (rtl ? wi->current_x : wi->current_x - clearbtn_width) - 1;
|
||||||
|
|
||||||
|
int top = wi->pos_y + WD_FRAMERECT_TOP;
|
||||||
|
int bottom = wi->pos_y + wi->current_y - 1 - WD_FRAMERECT_BOTTOM;
|
||||||
|
|
||||||
|
if (!IsInsideMM(pt.y, top, bottom)) return NULL;
|
||||||
|
|
||||||
|
/* Clamp caret position to be inside our current width. */
|
||||||
|
const Textbuf *tb = &this->text;
|
||||||
|
int delta = min(0, (right - left) - tb->pixels - 10);
|
||||||
|
if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs;
|
||||||
|
|
||||||
|
return ::GetCharAtPosition(tb->buf, pt.x - delta - left);
|
||||||
|
}
|
||||||
|
|
||||||
void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed)
|
void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed)
|
||||||
{
|
{
|
||||||
const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
|
const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
|
||||||
|
|
|
@ -56,6 +56,7 @@ public:
|
||||||
|
|
||||||
Point GetCaretPosition(const Window *w, int wid) const;
|
Point GetCaretPosition(const Window *w, int wid) const;
|
||||||
Rect GetBoundingRect(const Window *w, int wid, const char *from, const char *to) const;
|
Rect GetBoundingRect(const Window *w, int wid, const char *from, const char *to) const;
|
||||||
|
const char *GetCharAtPosition(const Window *w, int wid, const Point &pt) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the current text.
|
* Get the current text.
|
||||||
|
|
|
@ -909,7 +909,16 @@ static const char *Utf8AdvanceByUtf16Units(const char *str, NSUInteger count)
|
||||||
/** Get the character that is rendered at the given point. */
|
/** Get the character that is rendered at the given point. */
|
||||||
- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
|
- (NSUInteger)characterIndexForPoint:(NSPoint)thePoint
|
||||||
{
|
{
|
||||||
return NSNotFound;
|
if (!EditBoxInGlobalFocus()) return NSNotFound;
|
||||||
|
|
||||||
|
NSPoint view_pt = [ self convertPoint:[ [ self window ] convertScreenToBase:thePoint ] fromView:nil ];
|
||||||
|
|
||||||
|
Point pt = { view_pt.x, [ self frame ].size.height - view_pt.y };
|
||||||
|
|
||||||
|
const char *ch = _focused_window->GetTextCharacterAtPosition(pt);
|
||||||
|
if (ch == NULL) return NSNotFound;
|
||||||
|
|
||||||
|
return CountUtf16Units(_focused_window->GetFocusedText(), ch);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Get the bounding rect for the given range. */
|
/** Get the bounding rect for the given range. */
|
||||||
|
|
|
@ -393,6 +393,19 @@ QueryString *Window::GetQueryString(uint widnum)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the character that is rendered at a position by the focused edit box.
|
||||||
|
* @param pt The position to test.
|
||||||
|
* @return Pointer to the character at the position or NULL if no character is at the position.
|
||||||
|
*/
|
||||||
|
/* virtual */ const char *Window::GetTextCharacterAtPosition(const Point &pt) const
|
||||||
|
{
|
||||||
|
if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) {
|
||||||
|
return this->GetQueryString(this->nested_focus->index)->GetCharAtPosition(this, this->nested_focus->index, pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the window that has the focus
|
* Set the window that has the focus
|
||||||
|
|
|
@ -350,6 +350,7 @@ public:
|
||||||
virtual const char *GetMarkedText(size_t *length) const;
|
virtual const char *GetMarkedText(size_t *length) const;
|
||||||
virtual Point GetCaretPosition() const;
|
virtual Point GetCaretPosition() const;
|
||||||
virtual Rect GetTextBoundingRect(const char *from, const char *to) const;
|
virtual Rect GetTextBoundingRect(const char *from, const char *to) const;
|
||||||
|
virtual const char *GetTextCharacterAtPosition(const Point &pt) const;
|
||||||
|
|
||||||
void InitNested(WindowNumber number = 0);
|
void InitNested(WindowNumber number = 0);
|
||||||
void CreateNestedTree(bool fill_nested = true);
|
void CreateNestedTree(bool fill_nested = true);
|
||||||
|
|
Loading…
Reference in New Issue