17#include "IGraphicsWeb.h"
20EM_JS(
int, createWebGLContextForShadowDOM, (), {
21 var canvas = Module.canvas;
22 if (!canvas)
return 0;
23 var attrs = { stencil:
true, depth:
true, antialias:
true, alpha:
true };
24 var ctx = canvas.getContext(
"webgl", attrs) || canvas.getContext(
"experimental-webgl", attrs);
26 return GL.registerContext(ctx, attrs);
31BEGIN_IGRAPHICS_NAMESPACE
33void GetScreenDimensions(
int& width,
int& height)
35 width = val::global(
"window")[
"innerWidth"].as<
int>();
36 height = val::global(
"window")[
"innerHeight"].as<
int>();
40END_IGRAPHICS_NAMESPACE
43using namespace igraphics;
44using namespace emscripten;
46extern std::vector<IGraphicsWeb*> gGraphicsInstances;
47extern void UnregisterGraphicsInstance(
IGraphicsWeb* pGraphics);
48double gPrevMouseDownTime = 0.;
49bool gFirstClick =
false;
51#pragma mark - Private Classes and Structs
55class IGraphicsWeb::Font :
public PlatformFont
58 Font(
const char* fontName,
const char* fontStyle)
59 : PlatformFont(true), mDescriptor{fontName, fontStyle}
62 FontDescriptor GetDescriptor()
override {
return &mDescriptor; }
65 std::pair<WDL_String, WDL_String> mDescriptor;
71 FileFont(
const char* fontName,
const char* fontStyle,
const char* fontPath)
72 : Font(fontName, fontStyle), mPath(fontPath)
77 IFontDataPtr GetFontData()
override;
83IFontDataPtr IGraphicsWeb::FileFont::GetFontData()
85 IFontDataPtr fontData(
new IFontData());
86 FILE* fp = fopen(mPath.Get(),
"rb");
93 fontData = std::make_unique<IFontData>((
int) ftell(fp));
95 if (!fontData->GetSize())
99 size_t readSize = fread(fontData->Get(), 1, fontData->GetSize(), fp);
102 if (readSize && readSize == fontData->GetSize())
103 fontData->SetFaceIdx(0);
111 MemoryFont(
const char* fontName,
const char* fontStyle,
const void* pData,
int dataSize)
112 : Font(fontName, fontStyle)
115 mData.Set((
const uint8_t*)pData, dataSize);
118 IFontDataPtr GetFontData()
override
120 return IFontDataPtr(
new IFontData(mData.Get(), mData.GetSize(), 0));
124 WDL_TypedBuf<uint8_t> mData;
127#pragma mark - Utilities and Callbacks
129static EM_BOOL key_callback(
int eventType,
const EmscriptenKeyboardEvent* pEvent,
void* pUserData)
137 if ((VK >= kVK_0 && VK <= kVK_Z) || VK == kVK_NONE)
138 keyUTF8.Set(pEvent->key);
144 static_cast<bool>(pEvent->shiftKey),
145 static_cast<bool>(pEvent->ctrlKey || pEvent->metaKey),
146 static_cast<bool>(pEvent->altKey)};
150 case EMSCRIPTEN_EVENT_KEYDOWN:
152 return pGraphicsWeb->OnKeyDown(pGraphicsWeb->mPrevX, pGraphicsWeb->mPrevY, keyPress);
154 case EMSCRIPTEN_EVENT_KEYUP:
156 return pGraphicsWeb->OnKeyUp(pGraphicsWeb->mPrevX, pGraphicsWeb->mPrevY, keyPress);
165static EM_BOOL outside_mouse_callback(
int eventType,
const EmscriptenMouseEvent* pEvent,
void* pUserData)
170 val rect = pGraphics->
GetCanvas().call<val>(
"getBoundingClientRect");
171 info.x = (pEvent->targetX - rect[
"left"].as<
double>()) / pGraphics->GetDrawScale();
172 info.y = (pEvent->targetY - rect[
"top"].as<
double>()) / pGraphics->GetDrawScale();
173 info.dX = pEvent->movementX;
174 info.dY = pEvent->movementY;
175 info.ms = {(pEvent->buttons & 1) != 0, (pEvent->buttons & 2) != 0,
static_cast<bool>(pEvent->shiftKey),
static_cast<bool>(pEvent->ctrlKey),
static_cast<bool>(pEvent->altKey)};
176 std::vector<IMouseInfo> list {info};
180 case EMSCRIPTEN_EVENT_MOUSEUP:
183 list[0].ms.L = pEvent->button == 0;
184 list[0].ms.R = pEvent->button == 2;
185 pGraphics->OnMouseUp(list);
186 emscripten_set_mousemove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1,
nullptr);
187 emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1,
nullptr);
190 case EMSCRIPTEN_EVENT_MOUSEMOVE:
192 if(pEvent->buttons != 0 && !pGraphics->IsInPlatformTextEntry())
193 pGraphics->OnMouseDrag(list);
200 pGraphics->mPrevX = info.x;
201 pGraphics->mPrevY = info.y;
206static EM_BOOL mouse_callback(
int eventType,
const EmscriptenMouseEvent* pEvent,
void* pUserData)
211 info.x = pEvent->targetX / pGraphics->GetDrawScale();
212 info.y = pEvent->targetY / pGraphics->GetDrawScale();
213 info.dX = pEvent->movementX;
214 info.dY = pEvent->movementY;
215 info.ms = {(pEvent->buttons & 1) != 0,
216 (pEvent->buttons & 2) != 0,
217 static_cast<bool>(pEvent->shiftKey),
218 static_cast<bool>(pEvent->ctrlKey),
219 static_cast<bool>(pEvent->altKey)};
221 std::vector<IMouseInfo> list {info};
224 case EMSCRIPTEN_EVENT_MOUSEDOWN:
226 const double timestamp = GetTimestamp();
227 const double timeDiff = timestamp - gPrevMouseDownTime;
229 if (gFirstClick && timeDiff < 0.3)
232 pGraphics->OnMouseDblClick(info.x, info.y, info.ms);
237 pGraphics->OnMouseDown(list);
240 gPrevMouseDownTime = timestamp;
244 case EMSCRIPTEN_EVENT_MOUSEUP:
247 list[0].ms.L = pEvent->button == 0;
248 list[0].ms.R = pEvent->button == 2;
249 pGraphics->OnMouseUp(list);
252 case EMSCRIPTEN_EVENT_MOUSEMOVE:
256 if(pEvent->buttons == 0)
257 pGraphics->OnMouseOver(info.x, info.y, info.ms);
260 if(!pGraphics->IsInPlatformTextEntry())
261 pGraphics->OnMouseDrag(list);
265 case EMSCRIPTEN_EVENT_MOUSEENTER:
266 pGraphics->OnSetCursor();
267 pGraphics->OnMouseOver(info.x, info.y, info.ms);
268 emscripten_set_mousemove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1,
nullptr);
270 case EMSCRIPTEN_EVENT_MOUSELEAVE:
271 if(pEvent->buttons != 0)
273 emscripten_set_mousemove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1, outside_mouse_callback);
274 emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1, outside_mouse_callback);
276 pGraphics->OnMouseOut();
break;
281 pGraphics->mPrevX = info.x;
282 pGraphics->mPrevY = info.y;
287static EM_BOOL wheel_callback(
int eventType,
const EmscriptenWheelEvent* pEvent,
void* pUserData)
291 IMouseMod modifiers(
false,
false, pEvent->mouse.shiftKey, pEvent->mouse.ctrlKey, pEvent->mouse.altKey);
293 double x = pEvent->mouse.targetX;
294 double y = pEvent->mouse.targetY;
300 case EMSCRIPTEN_EVENT_WHEEL: pGraphics->
OnMouseWheel(x, y, modifiers, pEvent->deltaY);
308EM_BOOL touch_callback(
int eventType,
const EmscriptenTouchEvent* pEvent,
void* pUserData)
313 std::vector<IMouseInfo> points;
315 static EmscriptenTouchPoint previousTouches[32];
317 for (
auto i = 0; i < pEvent->numTouches; i++)
320 info.x = pEvent->touches[i].targetX / drawScale;
321 info.y = pEvent->touches[i].targetY / drawScale;
322 info.dX = info.x - (previousTouches[i].targetX / drawScale);
323 info.dY = info.y - (previousTouches[i].targetY / drawScale);
326 static_cast<bool>(pEvent->shiftKey),
327 static_cast<bool>(pEvent->ctrlKey),
328 static_cast<bool>(pEvent->altKey),
329 static_cast<ITouchID
>(pEvent->touches[i].identifier)
332 if(pEvent->touches[i].isChanged)
333 points.push_back(info);
336 memcpy(previousTouches, pEvent->touches,
sizeof(previousTouches));
340 case EMSCRIPTEN_EVENT_TOUCHSTART:
343 case EMSCRIPTEN_EVENT_TOUCHEND:
346 case EMSCRIPTEN_EVENT_TOUCHMOVE:
349 case EMSCRIPTEN_EVENT_TOUCHCANCEL:
357static EM_BOOL complete_text_entry(
int eventType,
const EmscriptenFocusEvent* focusEvent,
void* pUserData)
361 val input = val::global(
"document").call<val>(
"getElementById", std::string(
"textEntry"));
362 std::string str = input[
"value"].as<std::string>();
363 val::global(
"document")[
"body"].call<
void>(
"removeChild", input);
364 pGraphics->SetControlValueAfterTextEdit(str.c_str());
369static EM_BOOL text_entry_keydown(
int eventType,
const EmscriptenKeyboardEvent* pEvent,
void* pUserData)
374 static_cast<bool>(pEvent->shiftKey),
375 static_cast<bool>(pEvent->ctrlKey),
376 static_cast<bool>(pEvent->altKey)};
378 if (keyPress.VK == kVK_RETURN || keyPress.VK == kVK_TAB)
379 return complete_text_entry(0,
nullptr, pUserData);
384static EM_BOOL uievent_callback(
int eventType,
const EmscriptenUiEvent* pEvent,
void* pUserData)
388 if (eventType == EMSCRIPTEN_EVENT_RESIZE)
390 pGraphics->GetDelegate()->OnParentWindowResize(pEvent->windowInnerWidth, pEvent->windowInnerHeight);
398IColorPickerHandlerFunc gColorPickerHandlerFunc =
nullptr;
400static void color_picker_callback(val e)
402 if(gColorPickerHandlerFunc)
404 std::string colorStrHex = e[
"target"][
"value"].as<std::string>();
406 if (colorStrHex[0] ==
'#')
407 colorStrHex = colorStrHex.erase(0, 1);
411 sscanf(colorStrHex.c_str(),
"%02x%02x%02x", &result.R, &result.G, &result.B);
413 gColorPickerHandlerFunc(result);
417static void file_dialog_callback(val e)
422EMSCRIPTEN_BINDINGS(events) {
423 function(
"color_picker_callback", color_picker_callback);
424 function(
"file_dialog_callback", file_dialog_callback);
430: IGRAPHICS_DRAW_CLASS(dlg, w, h, fps, scale)
432 val keys = val::global(
"Object").call<val>(
"keys", GetPreloadedImages());
434 DBGMSG(
"Preloaded %i images\n", keys[
"length"].as<int>());
437 if (canvas.isUndefined() || canvas.isNull())
440 val moduleCanvas = val::global(
"Module")[
"canvas"];
441 if (!moduleCanvas.isUndefined() && !moduleCanvas.isNull())
443 mCanvas = moduleCanvas;
448 mCanvas = val::global(
"document").call<val>(
"getElementById", std::string(
"canvas"));
457 mRootNode = mCanvas.call<val>(
"getRootNode");
458 std::string rootNodeType = mRootNode[
"constructor"][
"name"].as<std::string>();
459 mInShadowDOM = (rootNodeType ==
"ShadowRoot");
464 std::string existingId = mCanvas[
"id"].as<std::string>();
465 if (existingId.empty())
468 snprintf(idBuf,
sizeof(idBuf),
"iplug-canvas-%p",
static_cast<void*
>(
this));
470 mCanvas.set(
"id", existingId);
472 mCanvasSelector = std::string(
"#") + existingId;
474 DBGMSG(
"IGraphicsWeb: Shadow DOM = %s, selector = %s\n", mInShadowDOM ?
"true" :
"false", mCanvasSelector.c_str());
476 RegisterCanvasEvents();
479void IGraphicsWeb::RegisterCanvasEvents()
482 emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
this, 1, key_callback);
483 emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
this, 1, key_callback);
484 emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
this, 1, uievent_callback);
492 var canvas = Module.canvas;
496 canvas._iplugGraphics = pGraphics;
498 canvas.addEventListener(
'mousedown', function(e) {
499 Module._iGraphicsMouseCallback(pGraphics, 0, e.offsetX, e.offsetY, e.movementX, e.movementY, e.buttons, e.button, e.shiftKey, e.ctrlKey, e.altKey);
501 canvas.addEventListener(
'mouseup', function(e) {
502 Module._iGraphicsMouseCallback(pGraphics, 1, e.offsetX, e.offsetY, e.movementX, e.movementY, e.buttons, e.button, e.shiftKey, e.ctrlKey, e.altKey);
504 canvas.addEventListener(
'mousemove', function(e) {
505 Module._iGraphicsMouseCallback(pGraphics, 2, e.offsetX, e.offsetY, e.movementX, e.movementY, e.buttons, e.button, e.shiftKey, e.ctrlKey, e.altKey);
507 canvas.addEventListener(
'mouseenter', function(e) {
508 Module._iGraphicsMouseCallback(pGraphics, 3, e.offsetX, e.offsetY, e.movementX, e.movementY, e.buttons, e.button, e.shiftKey, e.ctrlKey, e.altKey);
510 canvas.addEventListener(
'mouseleave', function(e) {
511 Module._iGraphicsMouseCallback(pGraphics, 4, e.offsetX, e.offsetY, e.movementX, e.movementY, e.buttons, e.button, e.shiftKey, e.ctrlKey, e.altKey);
513 canvas.addEventListener(
'wheel', function(e) {
514 Module._iGraphicsWheelCallback(pGraphics, e.offsetX, e.offsetY, e.deltaY, e.shiftKey, e.ctrlKey, e.altKey);
516 }, { passive:
false });
523 const char* target = mCanvasSelector.c_str();
524 emscripten_set_mousedown_callback(target,
this, 1, mouse_callback);
525 emscripten_set_mouseup_callback(target,
this, 1, mouse_callback);
526 emscripten_set_mousemove_callback(target,
this, 1, mouse_callback);
527 emscripten_set_mouseenter_callback(target,
this, 1, mouse_callback);
528 emscripten_set_mouseleave_callback(target,
this, 1, mouse_callback);
529 emscripten_set_wheel_callback(target,
this, 1, wheel_callback);
530 emscripten_set_touchstart_callback(target,
this, 1, touch_callback);
531 emscripten_set_touchend_callback(target,
this, 1, touch_callback);
532 emscripten_set_touchmove_callback(target,
this, 1, touch_callback);
533 emscripten_set_touchcancel_callback(target,
this, 1, touch_callback);
537void IGraphicsWeb::UnregisterCanvasEvents()
539 const char* target = mCanvasSelector.c_str();
541 emscripten_set_mousedown_callback(target,
this, 1,
nullptr);
542 emscripten_set_mouseup_callback(target,
this, 1,
nullptr);
543 emscripten_set_mousemove_callback(target,
this, 1,
nullptr);
544 emscripten_set_mouseenter_callback(target,
this, 1,
nullptr);
545 emscripten_set_mouseleave_callback(target,
this, 1,
nullptr);
546 emscripten_set_wheel_callback(target,
this, 1,
nullptr);
547 emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
this, 1,
nullptr);
548 emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
this, 1,
nullptr);
549 emscripten_set_touchstart_callback(target,
this, 1,
nullptr);
550 emscripten_set_touchend_callback(target,
this, 1,
nullptr);
551 emscripten_set_touchmove_callback(target,
this, 1,
nullptr);
552 emscripten_set_touchcancel_callback(target,
this, 1,
nullptr);
555IGraphicsWeb::~IGraphicsWeb()
557 UnregisterCanvasEvents();
558 UnregisterGraphicsInstance(
this);
561void* IGraphicsWeb::OpenWindow(
void* pHandle)
564 EmscriptenWebGLContextAttributes attr;
565 emscripten_webgl_init_context_attributes(&attr);
570 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx;
575 ctx = createWebGLContextForShadowDOM();
580 ctx = emscripten_webgl_create_context(mCanvasSelector.c_str(), &attr);
583 emscripten_webgl_make_context_current(ctx);
586 OnViewInitialized(
nullptr );
588 SetScreenScale(std::ceil(std::max(emscripten_get_device_pixel_ratio(), 1.)));
590 GetDelegate()->LayoutUI(
this);
591 GetDelegate()->OnUIOpen();
596void IGraphicsWeb::HideMouseCursor(
bool hide,
bool lock)
598 if (mCursorHidden == hide)
603#ifdef IGRAPHICS_WEB_POINTERLOCK
605 emscripten_request_pointerlock(mCanvasSelector.c_str(), EM_FALSE);
608 mCanvas[
"style"].set(
"cursor",
"none");
610 mCursorHidden =
true;
615#ifdef IGRAPHICS_WEB_POINTERLOCK
617 emscripten_exit_pointerlock();
622 mCursorHidden =
false;
627ECursor IGraphicsWeb::SetMouseCursor(ECursor cursorType)
629 std::string cursor(
"pointer");
633 case ECursor::ARROW: cursor =
"default";
break;
634 case ECursor::IBEAM: cursor =
"text";
break;
635 case ECursor::WAIT: cursor =
"wait";
break;
636 case ECursor::CROSS: cursor =
"crosshair";
break;
637 case ECursor::UPARROW: cursor =
"n-resize";
break;
638 case ECursor::SIZENWSE: cursor =
"nwse-resize";
break;
639 case ECursor::SIZENESW: cursor =
"nesw-resize";
break;
640 case ECursor::SIZEWE: cursor =
"ew-resize";
break;
641 case ECursor::SIZENS: cursor =
"ns-resize";
break;
642 case ECursor::SIZEALL: cursor =
"move";
break;
643 case ECursor::INO: cursor =
"not-allowed";
break;
644 case ECursor::HAND: cursor =
"pointer";
break;
645 case ECursor::APPSTARTING: cursor =
"progress";
break;
646 case ECursor::HELP: cursor =
"help";
break;
649 mCanvas[
"style"].set(
"cursor", cursor);
653void IGraphicsWeb::GetMouseLocation(
float& x,
float&y)
const
660void IGraphicsWeb::OnMainLoopTimer()
662 int screenScale = (int) std::ceil(std::max(emscripten_get_device_pixel_ratio(), 1.));
667 if (pGraphics ==
nullptr)
670 if (screenScale != pGraphics->GetScreenScale())
672 pGraphics->SetScreenScale(screenScale);
676 if (pGraphics->IsDirty(rects))
678 pGraphics->SetAllControlsClean();
679 pGraphics->Draw(rects);
684EMsgBoxResult IGraphicsWeb::ShowMessageBox(
const char* str,
const char* , EMsgBoxType type, IMsgBoxCompletionHandlerFunc completionHandler)
686 ReleaseMouseCapture();
688 EMsgBoxResult result = kNoResult;
694 val::global(
"window").call<val>(
"alert", std::string(str));
695 result = EMsgBoxResult::kOK;
701 result =
static_cast<EMsgBoxResult
>(val::global(
"window").call<val>(
"confirm", std::string(str)).as<int>());
706 return result = kNoResult;
709 if(completionHandler)
710 completionHandler(result);
715void IGraphicsWeb::PromptForFile(WDL_String& filename, WDL_String& path, EFileAction action,
const char* ext, IFileDialogCompletionHandlerFunc completionHandler)
727void IGraphicsWeb::PromptForDirectory(WDL_String& path, IFileDialogCompletionHandlerFunc completionHandler)
740bool IGraphicsWeb::PromptForColor(
IColor& color,
const char* str, IColorPickerHandlerFunc func)
742 ReleaseMouseCapture();
744 gColorPickerHandlerFunc = func;
746 val inputEl = val::global(
"document").call<val>(
"createElement", std::string(
"input"));
747 inputEl.call<
void>(
"setAttribute", std::string(
"type"), std::string(
"color"));
749 colorStr.SetFormatted(64,
"#%02x%02x%02x", color.R, color.G, color.B);
750 inputEl.call<
void>(
"setAttribute", std::string(
"value"), std::string(colorStr.Get()));
751 inputEl.call<
void>(
"click");
752 inputEl.call<
void>(
"addEventListener", std::string(
"input"), val::module_property(
"color_picker_callback"),
false);
753 inputEl.call<
void>(
"addEventListener", std::string(
"onChange"), val::module_property(
"color_picker_callback"),
false);
758void IGraphicsWeb::CreatePlatformTextEntry(
int paramIdx,
const IText& text,
const IRECT& bounds,
int length,
const char* str)
760 val input = val::global(
"document").call<val>(
"createElement", std::string(
"input"));
761 val rect = mCanvas.call<val>(
"getBoundingClientRect");
763 auto setDim = [&input](
const char *dimName,
double pixels)
766 dimstr.SetFormatted(32,
"%fpx", pixels);
767 input[
"style"].set(dimName, std::string(dimstr.Get()));
770 auto setColor = [&input](
const char *colorName,
IColor color)
773 str.SetFormatted(64,
"rgba(%d, %d, %d, %d)", color.R, color.G, color.B, color.A);
774 input[
"style"].set(colorName, std::string(str.Get()));
777 input.set(
"id", std::string(
"textEntry"));
778 input[
"style"].set(
"position", val(
"fixed"));
779 setDim(
"left", rect[
"left"].as<double>() + bounds.L);
780 setDim(
"top", rect[
"top"].as<double>() + bounds.T);
781 setDim(
"width", bounds.
W());
782 setDim(
"height", bounds.
H());
784 setColor(
"color", text.mTextEntryFGColor);
785 setColor(
"background-color", text.mTextEntryBGColor);
786 if (paramIdx > kNoParameter)
788 const IParam* pParam = GetDelegate()->GetParam(paramIdx);
790 switch (pParam->
Type())
792 case IParam::kTypeEnum:
793 case IParam::kTypeInt:
794 case IParam::kTypeBool:
795 input.set(
"type", val(
"number"));
797 case IParam::kTypeDouble:
798 input.set(
"type", val(
"number"));
806 input.set(
"type", val(
"text"));
812 mRootNode.call<
void>(
"appendChild", input);
816 val::global(
"document")[
"body"].call<
void>(
"appendChild", input);
819 input.call<
void>(
"focus");
820 emscripten_set_focusout_callback(
"textEntry",
this, 1, complete_text_entry);
821 emscripten_set_keydown_callback(
"textEntry",
this, 1, text_entry_keydown);
829bool IGraphicsWeb::OpenURL(
const char* url,
const char* msgWindowTitle,
const char* confirmMsg,
const char* errMsgOnFailure)
831 val::global(
"window").call<val>(
"open", std::string(url), std::string(
"_blank"));
836void IGraphicsWeb::DrawResize()
839 std::string widthPx = std::to_string(
static_cast<int>(Width() * GetDrawScale())) +
"px";
840 std::string heightPx = std::to_string(
static_cast<int>(Height() * GetDrawScale())) +
"px";
841 mCanvas[
"style"].set(
"width", val(widthPx));
842 mCanvas[
"style"].set(
"height", val(heightPx));
848 const int newBufW = Width() * GetBackingPixelScale();
849 const int newBufH = Height() * GetBackingPixelScale();
850 const int curBufW = mCanvas[
"width"].as<
int>();
851 const int curBufH = mCanvas[
"height"].as<
int>();
852 if (newBufW != curBufW || newBufH != curBufH)
854 mCanvas.set(
"width", newBufW);
855 mCanvas.set(
"height", newBufH);
858 IGRAPHICS_DRAW_CLASS::DrawResize();
861void IGraphicsWeb::PostResize()
872 rects.
Add(GetBounds());
873 SetAllControlsClean();
877PlatformFontPtr IGraphicsWeb::LoadPlatformFont(
const char* fontID,
const char* fileNameOrResID)
880 const EResourceLocation fontLocation =
LocateResource(fileNameOrResID,
"ttf", fullPath, GetBundleID(),
nullptr,
nullptr);
882 if (fontLocation == kNotFound)
885 return PlatformFontPtr(
new FileFont(fontID,
"", fullPath.Get()));
888PlatformFontPtr IGraphicsWeb::LoadPlatformFont(
const char* fontID,
const char* fontName, ETextStyle style)
890 const char* styles[] = {
"normal",
"bold",
"italic" };
892 return PlatformFontPtr(
new Font(fontName, styles[
static_cast<int>(style)]));
895PlatformFontPtr IGraphicsWeb::LoadPlatformFont(
const char* fontID,
void* pData,
int dataSize)
897 return PlatformFontPtr(
new MemoryFont(fontID,
"", pData, dataSize));
904void iGraphicsMouseCallback(
void* pGraphics,
int eventType,
double x,
double y,
double dx,
double dy,
int buttons,
int button,
int shift,
int ctrl,
int alt)
907 float scale = pG->GetDrawScale();
914 info.ms = {(buttons & 1) != 0, (buttons & 2) != 0,
static_cast<bool>(shift),
static_cast<bool>(ctrl),
static_cast<bool>(alt)};
915 std::vector<IMouseInfo> list{info};
920 pG->OnMouseDown(list);
923 list[0].ms.L = button == 0;
924 list[0].ms.R = button == 2;
929 pG->OnMouseOver(info.x, info.y, info.ms);
930 else if (!pG->IsInPlatformTextEntry())
931 pG->OnMouseDrag(list);
935 pG->OnMouseOver(info.x, info.y, info.ms);
947void iGraphicsWheelCallback(
void* pGraphics,
double x,
double y,
double deltaY,
int shift,
int ctrl,
int alt)
950 float scale = pG->GetDrawScale();
951 IMouseMod mod(
false,
false,
static_cast<bool>(shift),
static_cast<bool>(ctrl),
static_cast<bool>(alt));
952 pG->OnMouseWheel(x / scale, y / scale, mod, deltaY);
957#if defined IGRAPHICS_NANOVG
958#include "IGraphicsNanoVG.cpp"
960#ifdef IGRAPHICS_FREETYPE
961#define FONS_USE_FREETYPE
EResourceLocation LocateResource(const char *fileNameOrResID, const char *type, WDL_String &result, const char *bundleID, void *pHInstance, const char *sharedResourcesSubPath)
Find the absolute path of a resource based on it's file name (e.g.
An editor delegate base class that uses IGraphics for the UI.
The lowest level base class of an IGraphics context.
virtual ECursor SetMouseCursor(ECursor cursorType=ECursor::ARROW)
Sets the mouse cursor to one of ECursor (implementations should return the result of the base impleme...
void OnMouseDrag(const std::vector< IMouseInfo > &points)
Called when the platform class sends drag events.
void OnMouseUp(const std::vector< IMouseInfo > &points)
Called when the platform class sends mouse up events.
void OnTouchCancelled(const std::vector< IMouseInfo > &points)
Called when the platform class sends touch cancel events.
void OnMouseDown(const std::vector< IMouseInfo > &points)
Called when the platform class sends mouse down events.
bool OnMouseWheel(float x, float y, const IMouseMod &mod, float delta)
float GetDrawScale() const
Gets the graphics context scaling factor.
IGraphics platform class for the web.
IGraphicsWeb(IGEditorDelegate &dlg, int w, int h, int fps, float scale, val canvas=val::undefined())
Constructor.
val GetCanvas() const
Get the canvas element for this instance.
EParamType Type() const
Get the parameter's type.
Used to manage a list of rectangular areas and optimize them for drawing to the screen.
void Add(const IRECT &rect)
Add a rectangle to the list.
Used to group mouse coordinates with mouse modifier information.
int DOMKeyToVirtualKey(uint32_t domKeyCode)
Converts a DOM virtual key code to an iPlug2 virtual key code.
Used to manage color data, independent of draw class/platform.
Used for key press info, such as ASCII representation, virtual key (mapped to win32 codes) and modifi...
Used to manage mouse modifiers i.e.
Used to manage a rectangular area, independent of draw class/platform.
IText is used to manage font and text/text entry style for a piece of text on the UI,...