mirror of
https://github.com/OpenTTD/OpenTTD.git
synced 2025-03-06 14:27:16 +00:00
(svn r25681) -Change: [Win32] Position the IME composition window at the caret position.
This commit is contained in:
parent
21126aec62
commit
da09fd3077
@ -317,6 +317,14 @@ struct IConsoleWindow : Window
|
||||
}
|
||||
}
|
||||
|
||||
virtual Point GetCaretPosition() const
|
||||
{
|
||||
int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);
|
||||
Point pt = {this->line_offset + delta + _iconsole_cmdline.caretxoffs, this->height - this->line_height};
|
||||
|
||||
return pt;
|
||||
}
|
||||
|
||||
virtual void OnMouseWheel(int wheel)
|
||||
{
|
||||
this->Scroll(-wheel);
|
||||
|
@ -785,6 +785,34 @@ void QueryString::DrawEditBox(const Window *w, int wid) const
|
||||
_cur_dpi = old_dpi;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current caret position.
|
||||
* @param w Window the edit box is in.
|
||||
* @param wid Widget index.
|
||||
* @return Top-left location of the caret, relative to the window.
|
||||
*/
|
||||
Point QueryString::GetCaretPosition(const Window *w, int wid) 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;
|
||||
|
||||
/* Clamp caret position to be inside out current width. */
|
||||
const Textbuf *tb = &this->text;
|
||||
int delta = min(0, (right - left) - tb->pixels - 10);
|
||||
if (tb->caretxoffs + delta < 0) delta = -tb->caretxoffs;
|
||||
|
||||
Point pt = {left + WD_FRAMERECT_LEFT + tb->caretxoffs + delta, wi->pos_y + WD_FRAMERECT_TOP};
|
||||
return pt;
|
||||
}
|
||||
|
||||
void QueryString::ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed)
|
||||
{
|
||||
const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);
|
||||
|
@ -53,6 +53,8 @@ public:
|
||||
void DrawEditBox(const Window *w, int wid) const;
|
||||
void ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed);
|
||||
void HandleEditBox(Window *w, int wid);
|
||||
|
||||
Point GetCaretPosition(const Window *w, int wid) const;
|
||||
};
|
||||
|
||||
void ShowOnScreenKeyboard(Window *parent, int button);
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include "../texteff.hpp"
|
||||
#include "../thread/thread.h"
|
||||
#include "../progress.h"
|
||||
#include "../window_gui.h"
|
||||
#include "../window_func.h"
|
||||
#include "win32_v.h"
|
||||
#include <windows.h>
|
||||
@ -500,6 +501,28 @@ static LRESULT HandleCharMsg(uint keycode, WChar charcode)
|
||||
}
|
||||
|
||||
#if !defined(WINCE) || _WIN32_WCE >= 0x400
|
||||
/** Set position of the composition window to the caret position. */
|
||||
static void SetCompositionPos(HWND hwnd)
|
||||
{
|
||||
HIMC hIMC = ImmGetContext(hwnd);
|
||||
if (hIMC != NULL) {
|
||||
COMPOSITIONFORM cf;
|
||||
cf.dwStyle = CFS_POINT;
|
||||
|
||||
if (EditBoxInGlobalFocus()) {
|
||||
/* Get caret position. */
|
||||
Point pt = _focused_window->GetCaretPosition();
|
||||
cf.ptCurrentPos.x = _focused_window->left + pt.x;
|
||||
cf.ptCurrentPos.y = _focused_window->top + pt.y;
|
||||
} else {
|
||||
cf.ptCurrentPos.x = 0;
|
||||
cf.ptCurrentPos.y = 0;
|
||||
}
|
||||
ImmSetCompositionWindow(hIMC, &cf);
|
||||
}
|
||||
ImmReleaseContext(hwnd, hIMC);
|
||||
}
|
||||
|
||||
/** Handle WM_IME_COMPOSITION messages. */
|
||||
static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
@ -515,6 +538,7 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
||||
|
||||
/* Transmit text to windowing system. */
|
||||
if (len > 0) HandleTextInput(FS2OTTD(str));
|
||||
SetCompositionPos(hwnd);
|
||||
|
||||
/* Don't pass the result string on to the default window proc. */
|
||||
lParam &= ~(GCS_RESULTSTR | GCS_RESULTCLAUSE | GCS_RESULTREADCLAUSE | GCS_RESULTREADSTR);
|
||||
@ -535,6 +559,7 @@ static void CancelIMEComposition(HWND hwnd)
|
||||
|
||||
#else
|
||||
|
||||
static void SetCompositionPos(HWND hwnd) {}
|
||||
static void CancelIMEComposition(HWND hwnd) {}
|
||||
|
||||
#endif /* !defined(WINCE) || _WIN32_WCE >= 0x400 */
|
||||
@ -548,6 +573,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||
switch (msg) {
|
||||
case WM_CREATE:
|
||||
SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
|
||||
SetCompositionPos(hwnd);
|
||||
break;
|
||||
|
||||
case WM_ENTERSIZEMOVE:
|
||||
@ -674,6 +700,10 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||
}
|
||||
|
||||
#if !defined(WINCE) || _WIN32_WCE >= 0x400
|
||||
case WM_IME_STARTCOMPOSITION:
|
||||
SetCompositionPos(hwnd);
|
||||
break;
|
||||
|
||||
case WM_IME_COMPOSITION:
|
||||
return HandleIMEComposition(hwnd, wParam, lParam);
|
||||
|
||||
@ -861,6 +891,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||
|
||||
case WM_SETFOCUS:
|
||||
_wnd.has_focus = true;
|
||||
SetCompositionPos(hwnd);
|
||||
break;
|
||||
|
||||
case WM_KILLFOCUS:
|
||||
@ -1220,4 +1251,5 @@ bool VideoDriver_Win32::AfterBlitterChange()
|
||||
void VideoDriver_Win32::EditBoxLostFocus()
|
||||
{
|
||||
CancelIMEComposition(_wnd.main_wnd);
|
||||
SetCompositionPos(_wnd.main_wnd);
|
||||
}
|
||||
|
@ -323,6 +323,20 @@ QueryString *Window::GetQueryString(uint widnum)
|
||||
return query != this->querystrings.End() ? query->second : NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the current caret position if an edit box has the focus.
|
||||
* @return Top-left location of the caret, relative to the window.
|
||||
*/
|
||||
/* virtual */ Point Window::GetCaretPosition() const
|
||||
{
|
||||
if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) {
|
||||
return this->GetQueryString(this->nested_focus->index)->GetCaretPosition(this, this->nested_focus->index);
|
||||
}
|
||||
|
||||
Point pt = {0, 0};
|
||||
return pt;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Set the window that has the focus
|
||||
|
@ -14,6 +14,7 @@
|
||||
|
||||
#include "window_type.h"
|
||||
#include "company_type.h"
|
||||
#include "core/geometry_type.hpp"
|
||||
|
||||
Window *FindWindowById(WindowClass cls, WindowNumber number);
|
||||
Window *FindWindowByClass(WindowClass cls);
|
||||
@ -53,5 +54,6 @@ void DeleteWindowById(WindowClass cls, WindowNumber number, bool force = true);
|
||||
void DeleteWindowByClass(WindowClass cls);
|
||||
|
||||
bool EditBoxInGlobalFocus();
|
||||
Point GetCaretPosition();
|
||||
|
||||
#endif /* WINDOW_FUNC_H */
|
||||
|
@ -345,6 +345,8 @@ public:
|
||||
const QueryString *GetQueryString(uint widnum) const;
|
||||
QueryString *GetQueryString(uint widnum);
|
||||
|
||||
virtual Point GetCaretPosition() const;
|
||||
|
||||
void InitNested(WindowNumber number = 0);
|
||||
void CreateNestedTree(bool fill_nested = true);
|
||||
void FinishInitNested(WindowNumber window_number = 0);
|
||||
|
Loading…
Reference in New Issue
Block a user