CtrlCore: Window Ink support

git-svn-id: svn://ultimatepp.org/upp/trunk@15844 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2021-03-13 14:06:35 +00:00
parent 193d5a44d3
commit 20df534903
4 changed files with 147 additions and 35 deletions

View file

@ -679,6 +679,7 @@ private:
static bool pen_barrel;
static bool pen_inverted;
static bool pen_eraser;
static bool pen_history;
static double pen_pressure;
static double pen_rotation;
static Pointf pen_tilt;
@ -1298,6 +1299,7 @@ public:
static int64 GetEventId() { return eventid; }
static bool IsPointerPen() { return pen; }
static bool IsPenHistoryEvent() { return pen_history; }
static bool IsPenBarrelPressed() { return pen_barrel; }
static bool IsPenInverted() { return pen_inverted; }
static bool IsPenEraserPressed() { return pen_eraser; }

View file

@ -22,6 +22,7 @@ bool Ctrl::pen;
bool Ctrl::pen_barrel;
bool Ctrl::pen_inverted;
bool Ctrl::pen_eraser;
bool Ctrl::pen_history;
double Ctrl::pen_pressure = Null;
double Ctrl::pen_rotation = Null;
Pointf Ctrl::pen_tilt = Null;

View file

@ -63,11 +63,111 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
// LLOG("Ctrl::WindowProc(" << message << ") in " << ::Name(this) << ", focus " << (void *)::GetFocus());
Ptr<Ctrl> _this = this;
HWND hwnd = GetHWND();
auto DoMouseMove = [&](POINT p) {
if(ignoreclick)
EndIgnore();
else {
if(_this) DoMouse(MOUSEMOVE, Point(p));
DoCursorShape();
}
};
switch(message) {
case WM_POINTERDOWN:
case WM_POINTERUPDATE:
case WM_POINTERUP: {
POINT p = Point((LONG)lParam);
ScreenToClient(hwnd, &p);
pen = false;
pen_pressure = pen_rotation = Null;
pen_tilt = Null;
pen_eraser = false;
pen_barrel = false;
pen_inverted = false;
pen_history = false;
static BOOL (WINAPI *EnableMouseInPointer)(BOOL fEnable);
static BOOL (WINAPI *GetPointerType)(UINT32 pointerId, POINTER_INPUT_TYPE *pointerType);
static BOOL (WINAPI *GetPointerInfo)(UINT32 pointerId, POINTER_INFO *pointerInfo);
static BOOL (WINAPI *GetPointerPenInfo)(UINT32 pointerId, POINTER_PEN_INFO *penInfo);
static BOOL (WINAPI *GetPointerPenInfoHistory)(UINT32 pointerId, UINT32 *entriesCount, POINTER_PEN_INFO *penInfo);
ONCELOCK {
DllFn(GetPointerType, "User32.dll", "GetPointerType");
DllFn(GetPointerInfo, "User32.dll", "GetPointerInfo");
DllFn(GetPointerPenInfo, "User32.dll", "GetPointerPenInfo");
DllFn(GetPointerPenInfoHistory, "User32.dll", "GetPointerPenInfoHistory");
};
if(!(GetPointerType && GetPointerInfo && GetPointerPenInfo && GetPointerPenInfoHistory))
break;
POINTER_INPUT_TYPE pointerType;
auto ProcessPenInfo = [&] (POINTER_PEN_INFO& ppi) {
pen = true;
if(ppi.penFlags & PEN_FLAG_BARREL)
pen_barrel = true;
if(ppi.penFlags & PEN_FLAG_INVERTED)
pen_inverted = true;
if(ppi.penFlags & PEN_FLAG_ERASER)
pen_eraser = true;
if(ppi.penMask & PEN_MASK_PRESSURE)
pen_pressure = ppi.pressure / 1024.0;
if(ppi.penMask & PEN_MASK_ROTATION)
pen_rotation = ppi.rotation * M_2PI / 360;
if(ppi.penMask & PEN_MASK_TILT_X)
pen_tilt.x = ppi.tiltX * M_2PI / 360;
if(ppi.penMask & PEN_MASK_TILT_Y)
pen_tilt.y = ppi.tiltY * M_2PI / 360;
};
UINT32 pointerId = GET_POINTERID_WPARAM(wParam);
if(GetPointerType(pointerId, &pointerType) && pointerType == PT_PEN) {
UINT32 hc = 256;
Buffer<POINTER_PEN_INFO> ppit(hc);
if(message == WM_POINTERUPDATE && GetPointerPenInfoHistory(pointerId, &hc, ppit)) {
for(int i = hc - 1; i >= 0; i--) {
ProcessPenInfo(ppit[i]);
POINT hp = ppit[i].pointerInfo.ptPixelLocation;
ScreenToClient(hwnd, &hp);
DoMouseMove(hp);
pen_history = true; // first one is the current event
}
pen_history = false;
return 0L;
}
POINTER_PEN_INFO ppi;
if(GetPointerPenInfo(pointerId, &ppi))
ProcessPenInfo(ppi);
switch(message) {
case WM_POINTERDOWN:
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(LEFTDOWN, Point(p), 0);
if(_this) PostInput();
break;
case WM_POINTERUP:
if(ignoreclick) EndIgnore();
else DoMouse(LEFTUP, Point(p), 0);
if(_this) PostInput();
break;
case WM_POINTERUPDATE:
DoMouseMove(p);
break;
}
return 0L;
}
}
break;
case WM_POINTERLEAVE:
pen = false;
break;
case WM_PALETTECHANGED:
if((HWND)wParam == hwnd)
break;
#ifndef PLATFORM_WINCE
case WM_QUERYNEWPALETTE:
if(!SystemDraw::AutoPalette()) break;
{
@ -81,7 +181,6 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
if(i) InvalidateRect(hwnd, NULL, TRUE);
return i;
}
#endif
case WM_PAINT:
ASSERT_(!painting || IsPanicMode(), "WM_PAINT invoked for " + Name() + " while in Paint routine");
ASSERT(hwnd);
@ -93,37 +192,28 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
fullrefresh = false;
if(IsVisible()) {
SystemDraw draw(dc);
#ifndef PLATFORM_WINCE
HPALETTE hOldPal;
if(draw.PaletteMode() && SystemDraw::AutoPalette()) {
hOldPal = SelectPalette(dc, GetQlibPalette(), TRUE);
int n = RealizePalette(dc);
LLOG("In paint realized " << n << " colors");
}
#endif
painting = true;
UpdateArea(draw, Rect(ps.rcPaint));
painting = false;
#ifndef PLATFORM_WINCE
if(draw.PaletteMode() && SystemDraw::AutoPalette())
SelectPalette(dc, hOldPal, TRUE);
#endif
}
EndPaint(hwnd, &ps);
UpdateDHCtrls(); // so that they are displayed withing the same WM_PAINT - looks better
}
return 0L;
#ifndef PLATFORM_WINCE
case WM_NCHITTEST:
CheckMouseCtrl();
if(ignoremouse) return HTTRANSPARENT;
break;
#endif
case WM_LBUTTONDOWN:
#ifdef PLARFORM_WINCE
wince_mouseleft = true;
#endif
ClickActivateWnd();
if(ignoreclick) return 0L;
DoMouse(LEFTDOWN, Point((dword)lParam), 0);
@ -134,14 +224,6 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
EndIgnore();
else
DoMouse(LEFTUP, Point((dword)lParam), 0);
#ifdef PLATFORM_WINCE
wince_mouseleft = false;
#endif
#ifdef PLATFORM_WINCE
wince_mousepos = Point(-99999, -99999);
if(!ignoreclick)
if(_this) DoMouse(MOUSEMOVE, Point(-99999, -99999));
#endif
if(_this) PostInput();
return 0L;
case WM_LBUTTONDBLCLK:
@ -188,23 +270,15 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
DoMouse(MIDDLEDOUBLE, Point((dword)lParam));
if(_this) PostInput();
return 0L;
#ifndef PLATFORM_WINCE
case WM_NCLBUTTONDOWN:
case WM_NCRBUTTONDOWN:
case WM_NCMBUTTONDOWN:
ClickActivateWnd();
IgnoreMouseUp();
break;
#endif
case WM_MOUSEMOVE:
LLOG("WM_MOUSEMOVE: ignoreclick = " << ignoreclick);
if(ignoreclick) {
EndIgnore();
return 0L;
}
if(_this)
DoMouse(MOUSEMOVE, Point((dword)lParam));
DoCursorShape();
DoMouseMove(Point((dword)lParam));
return 0L;
case 0x20a: // WM_MOUSEWHEEL:
if(ignoreclick) {
@ -265,9 +339,6 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
keycode = KEYtoK((dword)wParam) | K_KEYUP;
else
if(message == WM_CHAR && wParam != 127 && wParam > 32 || wParam == 32 && KEYtoK(VK_SPACE) == K_SPACE) {
#ifdef PLATFORM_WINCE
keycode = wParam;
#else
if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX Unicode patch
keycode = (dword)wParam;
else {
@ -280,7 +351,6 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
else
keycode = (dword)wParam;
}
#endif
}
bool b = false;
if(keycode) {
@ -482,14 +552,11 @@ LRESULT Ctrl::WindowProc(UINT message, WPARAM wParam, LPARAM lParam) {
*/
}
if(hwnd) {
#ifdef PLATFORM_WINCE
return DefWindowProc(hwnd, message, wParam, lParam);
#else
if(IsWindowUnicode(hwnd)) // TRC 04/10/17: ActiveX unicode patch
return DefWindowProcW(hwnd, message, wParam, lParam);
else
return DefWindowProc(hwnd, message, wParam, lParam);
#endif
}
return 0L;
}

View file

@ -2753,6 +2753,48 @@ This is helpful in certain caching situations `- e.g. if you
want to lazy fetch some data, but only once per input event.&]
[s3;%- &]
[s4;%- &]
[s5;:Upp`:`:Ctrl`:`:IsPointerPen`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPointerP
en]()&]
[s2; Current mouse event is in fact not a mouse event, but was caused
by interaction of graphical pen with tablet.&]
[s3;%- &]
[s4;%- &]
[s5;:Upp`:`:Ctrl`:`:IsPenHistoryEvent`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPen
HistoryEvent]()&]
[s2; The current event is from coalesced pen history (that could
happen if your software is unable to process all events in time).&]
[s3;%- &]
[s4;%- &]
[s5;:Upp`:`:Ctrl`:`:IsPenBarrelPressed`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPe
nBarrelPressed]()&]
[s2; Barell is pressed.&]
[s3;%- &]
[s4;%- &]
[s5;:Upp`:`:Ctrl`:`:IsPenInverted`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPenInve
rted]()&]
[s2; Pen is inverted.&]
[s3;%- &]
[s4;%- &]
[s5;:Upp`:`:Ctrl`:`:IsPenEraserPressed`(`):%- [@(0.0.255) static] [@(0.0.255) bool]_[* IsPe
nEraserPressed]()&]
[s2; Pen is in eraser mode&]
[s3;%- &]
[s4;%- &]
[s5;:Upp`:`:Ctrl`:`:GetPenPressure`(`):%- [@(0.0.255) static] [@(0.0.255) double]_[* GetPen
Pressure]()&]
[s2; Returns pen pressure as number 0...1.&]
[s3;%- &]
[s4;%- &]
[s5;:Upp`:`:Ctrl`:`:GetPenRotation`(`):%- [@(0.0.255) static] [@(0.0.255) double]_[* GetPen
Rotation]()&]
[s2; Returns pen rotation in radians.&]
[s3;%- &]
[s4;%- &]
[s5;:Upp`:`:Ctrl`:`:GetPenTilt`(`):%- [@(0.0.255) static] [_^Upp`:`:Pointf^ Pointf]_[* GetP
enTilt]()&]
[s2; Returns pen tilt in radians.&]
[s3;%- &]
[s4;%- &]
[s5;:Upp`:`:Ctrl`:`:begin`(`)const:%- [_^Upp`:`:Ctrl`:`:CtrlConstIterator^ CtrlConstIte
rator]_[* begin]()_[@(0.0.255) const]&]
[s5;:Upp`:`:Ctrl`:`:begin`(`):%- [_^Upp`:`:Ctrl`:`:CtrlIterator^ CtrlIterator]_[* begin](