mirror of https://github.com/OpenTTD/OpenTTD
(svn r25681) -Change: [Win32] Position the IME composition window at the caret position.
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)
|
virtual void OnMouseWheel(int wheel)
|
||||||
{
|
{
|
||||||
this->Scroll(-wheel);
|
this->Scroll(-wheel);
|
||||||
|
|
|
@ -785,6 +785,34 @@ void QueryString::DrawEditBox(const Window *w, int wid) const
|
||||||
_cur_dpi = old_dpi;
|
_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)
|
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);
|
||||||
|
|
|
@ -53,6 +53,8 @@ public:
|
||||||
void DrawEditBox(const Window *w, int wid) const;
|
void DrawEditBox(const Window *w, int wid) const;
|
||||||
void ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed);
|
void ClickEditBox(Window *w, Point pt, int wid, int click_count, bool focus_changed);
|
||||||
void HandleEditBox(Window *w, int wid);
|
void HandleEditBox(Window *w, int wid);
|
||||||
|
|
||||||
|
Point GetCaretPosition(const Window *w, int wid) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
void ShowOnScreenKeyboard(Window *parent, int button);
|
void ShowOnScreenKeyboard(Window *parent, int button);
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "../texteff.hpp"
|
#include "../texteff.hpp"
|
||||||
#include "../thread/thread.h"
|
#include "../thread/thread.h"
|
||||||
#include "../progress.h"
|
#include "../progress.h"
|
||||||
|
#include "../window_gui.h"
|
||||||
#include "../window_func.h"
|
#include "../window_func.h"
|
||||||
#include "win32_v.h"
|
#include "win32_v.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
|
@ -500,6 +501,28 @@ static LRESULT HandleCharMsg(uint keycode, WChar charcode)
|
||||||
}
|
}
|
||||||
|
|
||||||
#if !defined(WINCE) || _WIN32_WCE >= 0x400
|
#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. */
|
/** Handle WM_IME_COMPOSITION messages. */
|
||||||
static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam)
|
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. */
|
/* Transmit text to windowing system. */
|
||||||
if (len > 0) HandleTextInput(FS2OTTD(str));
|
if (len > 0) HandleTextInput(FS2OTTD(str));
|
||||||
|
SetCompositionPos(hwnd);
|
||||||
|
|
||||||
/* Don't pass the result string on to the default window proc. */
|
/* Don't pass the result string on to the default window proc. */
|
||||||
lParam &= ~(GCS_RESULTSTR | GCS_RESULTCLAUSE | GCS_RESULTREADCLAUSE | GCS_RESULTREADSTR);
|
lParam &= ~(GCS_RESULTSTR | GCS_RESULTCLAUSE | GCS_RESULTREADCLAUSE | GCS_RESULTREADSTR);
|
||||||
|
@ -535,6 +559,7 @@ static void CancelIMEComposition(HWND hwnd)
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
|
static void SetCompositionPos(HWND hwnd) {}
|
||||||
static void CancelIMEComposition(HWND hwnd) {}
|
static void CancelIMEComposition(HWND hwnd) {}
|
||||||
|
|
||||||
#endif /* !defined(WINCE) || _WIN32_WCE >= 0x400 */
|
#endif /* !defined(WINCE) || _WIN32_WCE >= 0x400 */
|
||||||
|
@ -548,6 +573,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||||
switch (msg) {
|
switch (msg) {
|
||||||
case WM_CREATE:
|
case WM_CREATE:
|
||||||
SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
|
SetTimer(hwnd, TID_POLLMOUSE, MOUSE_POLL_DELAY, (TIMERPROC)TrackMouseTimerProc);
|
||||||
|
SetCompositionPos(hwnd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_ENTERSIZEMOVE:
|
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
|
#if !defined(WINCE) || _WIN32_WCE >= 0x400
|
||||||
|
case WM_IME_STARTCOMPOSITION:
|
||||||
|
SetCompositionPos(hwnd);
|
||||||
|
break;
|
||||||
|
|
||||||
case WM_IME_COMPOSITION:
|
case WM_IME_COMPOSITION:
|
||||||
return HandleIMEComposition(hwnd, wParam, lParam);
|
return HandleIMEComposition(hwnd, wParam, lParam);
|
||||||
|
|
||||||
|
@ -861,6 +891,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP
|
||||||
|
|
||||||
case WM_SETFOCUS:
|
case WM_SETFOCUS:
|
||||||
_wnd.has_focus = true;
|
_wnd.has_focus = true;
|
||||||
|
SetCompositionPos(hwnd);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case WM_KILLFOCUS:
|
case WM_KILLFOCUS:
|
||||||
|
@ -1220,4 +1251,5 @@ bool VideoDriver_Win32::AfterBlitterChange()
|
||||||
void VideoDriver_Win32::EditBoxLostFocus()
|
void VideoDriver_Win32::EditBoxLostFocus()
|
||||||
{
|
{
|
||||||
CancelIMEComposition(_wnd.main_wnd);
|
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;
|
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
|
* Set the window that has the focus
|
||||||
|
|
|
@ -14,6 +14,7 @@
|
||||||
|
|
||||||
#include "window_type.h"
|
#include "window_type.h"
|
||||||
#include "company_type.h"
|
#include "company_type.h"
|
||||||
|
#include "core/geometry_type.hpp"
|
||||||
|
|
||||||
Window *FindWindowById(WindowClass cls, WindowNumber number);
|
Window *FindWindowById(WindowClass cls, WindowNumber number);
|
||||||
Window *FindWindowByClass(WindowClass cls);
|
Window *FindWindowByClass(WindowClass cls);
|
||||||
|
@ -53,5 +54,6 @@ void DeleteWindowById(WindowClass cls, WindowNumber number, bool force = true);
|
||||||
void DeleteWindowByClass(WindowClass cls);
|
void DeleteWindowByClass(WindowClass cls);
|
||||||
|
|
||||||
bool EditBoxInGlobalFocus();
|
bool EditBoxInGlobalFocus();
|
||||||
|
Point GetCaretPosition();
|
||||||
|
|
||||||
#endif /* WINDOW_FUNC_H */
|
#endif /* WINDOW_FUNC_H */
|
||||||
|
|
|
@ -345,6 +345,8 @@ public:
|
||||||
const QueryString *GetQueryString(uint widnum) const;
|
const QueryString *GetQueryString(uint widnum) const;
|
||||||
QueryString *GetQueryString(uint widnum);
|
QueryString *GetQueryString(uint widnum);
|
||||||
|
|
||||||
|
virtual Point GetCaretPosition() const;
|
||||||
|
|
||||||
void InitNested(WindowNumber number = 0);
|
void InitNested(WindowNumber number = 0);
|
||||||
void CreateNestedTree(bool fill_nested = true);
|
void CreateNestedTree(bool fill_nested = true);
|
||||||
void FinishInitNested(WindowNumber window_number = 0);
|
void FinishInitNested(WindowNumber window_number = 0);
|
||||||
|
|
Loading…
Reference in New Issue