14#include <emscripten/key_codes.h>
16#include "IGraphicsWeb.h"
19BEGIN_IGRAPHICS_NAMESPACE
21void GetScreenDimensions(
int& width,
int& height)
23 width = val::global(
"window")[
"innerWidth"].as<
int>();
24 height = val::global(
"window")[
"innerHeight"].as<
int>();
28END_IGRAPHICS_NAMESPACE
31using namespace igraphics;
32using namespace emscripten;
35double gPrevMouseDownTime = 0.;
36bool gFirstClick =
false;
38#pragma mark - Private Classes and Structs
42class IGraphicsWeb::Font :
public PlatformFont
45 Font(
const char* fontName,
const char* fontStyle)
46 : PlatformFont(true), mDescriptor{fontName, fontStyle}
49 FontDescriptor GetDescriptor()
override {
return &mDescriptor; }
52 std::pair<WDL_String, WDL_String> mDescriptor;
58 FileFont(
const char* fontName,
const char* fontStyle,
const char* fontPath)
59 : Font(fontName, fontStyle), mPath(fontPath)
64 IFontDataPtr GetFontData()
override;
70IFontDataPtr IGraphicsWeb::FileFont::GetFontData()
72 IFontDataPtr fontData(
new IFontData());
73 FILE* fp = fopen(mPath.Get(),
"rb");
80 fontData = std::make_unique<IFontData>((
int) ftell(fp));
82 if (!fontData->GetSize())
86 size_t readSize = fread(fontData->Get(), 1, fontData->GetSize(), fp);
89 if (readSize && readSize == fontData->GetSize())
90 fontData->SetFaceIdx(0);
98 MemoryFont(
const char* fontName,
const char* fontStyle,
const void* pData,
int dataSize)
99 : Font(fontName, fontStyle)
102 mData.Set((
const uint8_t*)pData, dataSize);
105 IFontDataPtr GetFontData()
override
107 return IFontDataPtr(
new IFontData(mData.Get(), mData.GetSize(), 0));
111 WDL_TypedBuf<uint8_t> mData;
114#pragma mark - Utilities and Callbacks
118static int domVKToWinVK(
int dom_vk_code)
123 case DOM_VK_HELP:
return kVK_HELP;
124 case DOM_VK_BACK_SPACE:
return kVK_BACK;
125 case DOM_VK_TAB:
return kVK_TAB;
126 case DOM_VK_CLEAR:
return kVK_CLEAR;
127 case DOM_VK_RETURN:
return kVK_RETURN;
128 case DOM_VK_ENTER:
return kVK_RETURN;
129 case DOM_VK_SHIFT:
return kVK_SHIFT;
130 case DOM_VK_CONTROL:
return kVK_CONTROL;
131 case DOM_VK_ALT:
return kVK_MENU;
132 case DOM_VK_PAUSE:
return kVK_PAUSE;
133 case DOM_VK_CAPS_LOCK:
return kVK_CAPITAL;
134 case DOM_VK_ESCAPE:
return kVK_ESCAPE;
139 case DOM_VK_SPACE:
return kVK_SPACE;
140 case DOM_VK_PAGE_UP:
return kVK_PRIOR;
141 case DOM_VK_PAGE_DOWN:
return kVK_NEXT;
142 case DOM_VK_END:
return kVK_END;
143 case DOM_VK_HOME:
return kVK_HOME;
144 case DOM_VK_LEFT:
return kVK_LEFT;
145 case DOM_VK_UP:
return kVK_UP;
146 case DOM_VK_RIGHT:
return kVK_RIGHT;
147 case DOM_VK_DOWN:
return kVK_DOWN;
152 case DOM_VK_INSERT:
return kVK_INSERT;
153 case DOM_VK_DELETE:
return kVK_DELETE;
154 case DOM_VK_0:
return kVK_0;
155 case DOM_VK_1:
return kVK_1;
156 case DOM_VK_2:
return kVK_2;
157 case DOM_VK_3:
return kVK_3;
158 case DOM_VK_4:
return kVK_4;
159 case DOM_VK_5:
return kVK_5;
160 case DOM_VK_6:
return kVK_6;
161 case DOM_VK_7:
return kVK_7;
162 case DOM_VK_8:
return kVK_8;
163 case DOM_VK_9:
return kVK_9;
171 case DOM_VK_A:
return kVK_A;
172 case DOM_VK_B:
return kVK_B;
173 case DOM_VK_C:
return kVK_C;
174 case DOM_VK_D:
return kVK_D;
175 case DOM_VK_E:
return kVK_E;
176 case DOM_VK_F:
return kVK_F;
177 case DOM_VK_G:
return kVK_G;
178 case DOM_VK_H:
return kVK_H;
179 case DOM_VK_I:
return kVK_I;
180 case DOM_VK_J:
return kVK_J;
181 case DOM_VK_K:
return kVK_K;
182 case DOM_VK_L:
return kVK_L;
183 case DOM_VK_M:
return kVK_M;
184 case DOM_VK_N:
return kVK_N;
185 case DOM_VK_O:
return kVK_O;
186 case DOM_VK_P:
return kVK_P;
187 case DOM_VK_Q:
return kVK_Q;
188 case DOM_VK_R:
return kVK_R;
189 case DOM_VK_S:
return kVK_S;
190 case DOM_VK_T:
return kVK_T;
191 case DOM_VK_U:
return kVK_U;
192 case DOM_VK_V:
return kVK_V;
193 case DOM_VK_W:
return kVK_W;
194 case DOM_VK_X:
return kVK_X;
195 case DOM_VK_Y:
return kVK_Y;
196 case DOM_VK_Z:
return kVK_Z;
200 case DOM_VK_NUMPAD0:
return kVK_NUMPAD0;
201 case DOM_VK_NUMPAD1:
return kVK_NUMPAD1;
202 case DOM_VK_NUMPAD2:
return kVK_NUMPAD2;
203 case DOM_VK_NUMPAD3:
return kVK_NUMPAD3;
204 case DOM_VK_NUMPAD4:
return kVK_NUMPAD4;
205 case DOM_VK_NUMPAD5:
return kVK_NUMPAD5;
206 case DOM_VK_NUMPAD6:
return kVK_NUMPAD6;
207 case DOM_VK_NUMPAD7:
return kVK_NUMPAD7;
208 case DOM_VK_NUMPAD8:
return kVK_NUMPAD8;
209 case DOM_VK_NUMPAD9:
return kVK_NUMPAD9;
210 case DOM_VK_MULTIPLY:
return kVK_MULTIPLY;
211 case DOM_VK_ADD:
return kVK_ADD;
212 case DOM_VK_SEPARATOR:
return kVK_SEPARATOR;
213 case DOM_VK_SUBTRACT:
return kVK_SUBTRACT;
214 case DOM_VK_DECIMAL:
return kVK_DECIMAL;
215 case DOM_VK_DIVIDE:
return kVK_DIVIDE;
216 case DOM_VK_F1:
return kVK_F1;
217 case DOM_VK_F2:
return kVK_F2;
218 case DOM_VK_F3:
return kVK_F3;
219 case DOM_VK_F4:
return kVK_F4;
220 case DOM_VK_F5:
return kVK_F5;
221 case DOM_VK_F6:
return kVK_F6;
222 case DOM_VK_F7:
return kVK_F7;
223 case DOM_VK_F8:
return kVK_F8;
224 case DOM_VK_F9:
return kVK_F9;
225 case DOM_VK_F10:
return kVK_F10;
226 case DOM_VK_F11:
return kVK_F11;
227 case DOM_VK_F12:
return kVK_F12;
228 case DOM_VK_F13:
return kVK_F13;
229 case DOM_VK_F14:
return kVK_F14;
230 case DOM_VK_F15:
return kVK_F15;
231 case DOM_VK_F16:
return kVK_F16;
232 case DOM_VK_F17:
return kVK_F17;
233 case DOM_VK_F18:
return kVK_F18;
234 case DOM_VK_F19:
return kVK_F19;
235 case DOM_VK_F20:
return kVK_F20;
236 case DOM_VK_F21:
return kVK_F21;
237 case DOM_VK_F22:
return kVK_F22;
238 case DOM_VK_F23:
return kVK_F23;
239 case DOM_VK_F24:
return kVK_F24;
240 case DOM_VK_NUM_LOCK:
return kVK_NUMLOCK;
241 case DOM_VK_SCROLL_LOCK:
return kVK_SCROLL;
300 default:
return kVK_NONE;
304static EM_BOOL key_callback(
int eventType,
const EmscriptenKeyboardEvent* pEvent,
void* pUserData)
308 int VK = domVKToWinVK(pEvent->keyCode);
312 if((VK >= kVK_0 && VK <= kVK_Z) || VK == kVK_NONE)
313 keyUTF8.Set(pEvent->key);
318 domVKToWinVK(pEvent->keyCode),
319 static_cast<bool>(pEvent->shiftKey),
320 static_cast<bool>(pEvent->ctrlKey || pEvent->metaKey),
321 static_cast<bool>(pEvent->altKey)};
325 case EMSCRIPTEN_EVENT_KEYDOWN:
327 return pGraphicsWeb->OnKeyDown(pGraphicsWeb->mPrevX, pGraphicsWeb->mPrevY, keyPress);
329 case EMSCRIPTEN_EVENT_KEYUP:
331 return pGraphicsWeb->OnKeyUp(pGraphicsWeb->mPrevX, pGraphicsWeb->mPrevY, keyPress);
340static EM_BOOL outside_mouse_callback(
int eventType,
const EmscriptenMouseEvent* pEvent,
void* pUserData)
345 val rect = GetCanvas().call<val>(
"getBoundingClientRect");
346 info.x = (pEvent->targetX - rect[
"left"].as<
double>()) / pGraphics->GetDrawScale();
347 info.y = (pEvent->targetY - rect[
"top"].as<
double>()) / pGraphics->GetDrawScale();
348 info.dX = pEvent->movementX;
349 info.dY = pEvent->movementY;
350 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)};
351 std::vector<IMouseInfo> list {info};
355 case EMSCRIPTEN_EVENT_MOUSEUP:
358 list[0].ms.L = pEvent->button == 0;
359 list[0].ms.R = pEvent->button == 2;
360 pGraphics->OnMouseUp(list);
361 emscripten_set_mousemove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1,
nullptr);
362 emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1,
nullptr);
365 case EMSCRIPTEN_EVENT_MOUSEMOVE:
367 if(pEvent->buttons != 0 && !pGraphics->IsInPlatformTextEntry())
368 pGraphics->OnMouseDrag(list);
375 pGraphics->mPrevX = info.x;
376 pGraphics->mPrevY = info.y;
381static EM_BOOL mouse_callback(
int eventType,
const EmscriptenMouseEvent* pEvent,
void* pUserData)
386 info.x = pEvent->targetX / pGraphics->GetDrawScale();
387 info.y = pEvent->targetY / pGraphics->GetDrawScale();
388 info.dX = pEvent->movementX;
389 info.dY = pEvent->movementY;
390 info.ms = {(pEvent->buttons & 1) != 0,
391 (pEvent->buttons & 2) != 0,
392 static_cast<bool>(pEvent->shiftKey),
393 static_cast<bool>(pEvent->ctrlKey),
394 static_cast<bool>(pEvent->altKey)};
396 std::vector<IMouseInfo> list {info};
399 case EMSCRIPTEN_EVENT_MOUSEDOWN:
401 const double timestamp = GetTimestamp();
402 const double timeDiff = timestamp - gPrevMouseDownTime;
404 if (gFirstClick && timeDiff < 0.3)
407 pGraphics->OnMouseDblClick(info.x, info.y, info.ms);
412 pGraphics->OnMouseDown(list);
415 gPrevMouseDownTime = timestamp;
419 case EMSCRIPTEN_EVENT_MOUSEUP:
422 list[0].ms.L = pEvent->button == 0;
423 list[0].ms.R = pEvent->button == 2;
424 pGraphics->OnMouseUp(list);
427 case EMSCRIPTEN_EVENT_MOUSEMOVE:
431 if(pEvent->buttons == 0)
432 pGraphics->OnMouseOver(info.x, info.y, info.ms);
435 if(!pGraphics->IsInPlatformTextEntry())
436 pGraphics->OnMouseDrag(list);
440 case EMSCRIPTEN_EVENT_MOUSEENTER:
441 pGraphics->OnSetCursor();
442 pGraphics->OnMouseOver(info.x, info.y, info.ms);
443 emscripten_set_mousemove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1,
nullptr);
445 case EMSCRIPTEN_EVENT_MOUSELEAVE:
446 if(pEvent->buttons != 0)
448 emscripten_set_mousemove_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1, outside_mouse_callback);
449 emscripten_set_mouseup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW, pGraphics, 1, outside_mouse_callback);
451 pGraphics->OnMouseOut();
break;
456 pGraphics->mPrevX = info.x;
457 pGraphics->mPrevY = info.y;
462static EM_BOOL wheel_callback(
int eventType,
const EmscriptenWheelEvent* pEvent,
void* pUserData)
466 IMouseMod modifiers(
false,
false, pEvent->mouse.shiftKey, pEvent->mouse.ctrlKey, pEvent->mouse.altKey);
468 double x = pEvent->mouse.targetX;
469 double y = pEvent->mouse.targetY;
475 case EMSCRIPTEN_EVENT_WHEEL: pGraphics->
OnMouseWheel(x, y, modifiers, pEvent->deltaY);
483EM_BOOL touch_callback(
int eventType,
const EmscriptenTouchEvent* pEvent,
void* pUserData)
488 std::vector<IMouseInfo> points;
490 static EmscriptenTouchPoint previousTouches[32];
492 for (
auto i = 0; i < pEvent->numTouches; i++)
495 info.x = pEvent->touches[i].targetX / drawScale;
496 info.y = pEvent->touches[i].targetY / drawScale;
497 info.dX = info.x - (previousTouches[i].targetX / drawScale);
498 info.dY = info.y - (previousTouches[i].targetY / drawScale);
501 static_cast<bool>(pEvent->shiftKey),
502 static_cast<bool>(pEvent->ctrlKey),
503 static_cast<bool>(pEvent->altKey),
504 static_cast<ITouchID
>(pEvent->touches[i].identifier)
507 if(pEvent->touches[i].isChanged)
508 points.push_back(info);
511 memcpy(previousTouches, pEvent->touches,
sizeof(previousTouches));
515 case EMSCRIPTEN_EVENT_TOUCHSTART:
518 case EMSCRIPTEN_EVENT_TOUCHEND:
521 case EMSCRIPTEN_EVENT_TOUCHMOVE:
524 case EMSCRIPTEN_EVENT_TOUCHCANCEL:
532static EM_BOOL complete_text_entry(
int eventType,
const EmscriptenFocusEvent* focusEvent,
void* pUserData)
536 val input = val::global(
"document").call<val>(
"getElementById", std::string(
"textEntry"));
537 std::string str = input[
"value"].as<std::string>();
538 val::global(
"document")[
"body"].call<
void>(
"removeChild", input);
539 pGraphics->SetControlValueAfterTextEdit(str.c_str());
544static EM_BOOL text_entry_keydown(
int eventType,
const EmscriptenKeyboardEvent* pEvent,
void* pUserData)
548 IKeyPress keyPress {pEvent->key, domVKToWinVK(pEvent->keyCode),
549 static_cast<bool>(pEvent->shiftKey),
550 static_cast<bool>(pEvent->ctrlKey),
551 static_cast<bool>(pEvent->altKey)};
553 if (keyPress.VK == kVK_RETURN || keyPress.VK == kVK_TAB)
554 return complete_text_entry(0,
nullptr, pUserData);
559static EM_BOOL uievent_callback(
int eventType,
const EmscriptenUiEvent* pEvent,
void* pUserData)
563 if (eventType == EMSCRIPTEN_EVENT_RESIZE)
565 pGraphics->GetDelegate()->OnParentWindowResize(pEvent->windowInnerWidth, pEvent->windowInnerHeight);
573IColorPickerHandlerFunc gColorPickerHandlerFunc =
nullptr;
575static void color_picker_callback(val e)
577 if(gColorPickerHandlerFunc)
579 std::string colorStrHex = e[
"target"][
"value"].as<std::string>();
581 if (colorStrHex[0] ==
'#')
582 colorStrHex = colorStrHex.erase(0, 1);
586 sscanf(colorStrHex.c_str(),
"%02x%02x%02x", &result.R, &result.G, &result.B);
588 gColorPickerHandlerFunc(result);
592static void file_dialog_callback(val e)
597EMSCRIPTEN_BINDINGS(events) {
598 function(
"color_picker_callback", color_picker_callback);
599 function(
"file_dialog_callback", file_dialog_callback);
604IGraphicsWeb::IGraphicsWeb(
IGEditorDelegate& dlg,
int w,
int h,
int fps,
float scale)
605: IGRAPHICS_DRAW_CLASS(dlg, w, h, fps, scale)
607 val keys = val::global(
"Object").call<val>(
"keys", GetPreloadedImages());
609 DBGMSG(
"Preloaded %i images\n", keys[
"length"].as<int>());
611 emscripten_set_mousedown_callback(
"#canvas",
this, 1, mouse_callback);
612 emscripten_set_mouseup_callback(
"#canvas",
this, 1, mouse_callback);
613 emscripten_set_mousemove_callback(
"#canvas",
this, 1, mouse_callback);
614 emscripten_set_mouseenter_callback(
"#canvas",
this, 1, mouse_callback);
615 emscripten_set_mouseleave_callback(
"#canvas",
this, 1, mouse_callback);
616 emscripten_set_wheel_callback(
"#canvas",
this, 1, wheel_callback);
617 emscripten_set_keydown_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
this, 1, key_callback);
618 emscripten_set_keyup_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
this, 1, key_callback);
619 emscripten_set_touchstart_callback(
"#canvas",
this, 1, touch_callback);
620 emscripten_set_touchend_callback(
"#canvas",
this, 1, touch_callback);
621 emscripten_set_touchmove_callback(
"#canvas",
this, 1, touch_callback);
622 emscripten_set_touchcancel_callback(
"#canvas",
this, 1, touch_callback);
623 emscripten_set_resize_callback(EMSCRIPTEN_EVENT_TARGET_WINDOW,
this, 1, uievent_callback);
626IGraphicsWeb::~IGraphicsWeb()
630void* IGraphicsWeb::OpenWindow(
void* pHandle)
633 EmscriptenWebGLContextAttributes attr;
634 emscripten_webgl_init_context_attributes(&attr);
639 EMSCRIPTEN_WEBGL_CONTEXT_HANDLE ctx = emscripten_webgl_create_context(
"#canvas", &attr);
640 emscripten_webgl_make_context_current(ctx);
643 OnViewInitialized(
nullptr );
645 SetScreenScale(std::ceil(std::max(emscripten_get_device_pixel_ratio(), 1.)));
647 GetDelegate()->LayoutUI(
this);
648 GetDelegate()->OnUIOpen();
653void IGraphicsWeb::HideMouseCursor(
bool hide,
bool lock)
655 if (mCursorHidden == hide)
660#ifdef IGRAPHICS_WEB_POINTERLOCK
662 emscripten_request_pointerlock(
"#canvas", EM_FALSE);
665 val::global(
"document")[
"body"][
"style"].set(
"cursor",
"none");
667 mCursorHidden =
true;
672#ifdef IGRAPHICS_WEB_POINTERLOCK
674 emscripten_exit_pointerlock();
679 mCursorHidden =
false;
684ECursor IGraphicsWeb::SetMouseCursor(ECursor cursorType)
686 std::string cursor(
"pointer");
690 case ECursor::ARROW: cursor =
"default";
break;
691 case ECursor::IBEAM: cursor =
"text";
break;
692 case ECursor::WAIT: cursor =
"wait";
break;
693 case ECursor::CROSS: cursor =
"crosshair";
break;
694 case ECursor::UPARROW: cursor =
"n-resize";
break;
695 case ECursor::SIZENWSE: cursor =
"nwse-resize";
break;
696 case ECursor::SIZENESW: cursor =
"nesw-resize";
break;
697 case ECursor::SIZEWE: cursor =
"ew-resize";
break;
698 case ECursor::SIZENS: cursor =
"ns-resize";
break;
699 case ECursor::SIZEALL: cursor =
"move";
break;
700 case ECursor::INO: cursor =
"not-allowed";
break;
701 case ECursor::HAND: cursor =
"pointer";
break;
702 case ECursor::APPSTARTING: cursor =
"progress";
break;
703 case ECursor::HELP: cursor =
"help";
break;
706 val::global(
"document")[
"body"][
"style"].set(
"cursor", cursor);
710void IGraphicsWeb::GetMouseLocation(
float& x,
float&y)
const
717void IGraphicsWeb::OnMainLoopTimer()
720 int screenScale = (int) std::ceil(std::max(emscripten_get_device_pixel_ratio(), 1.));
723 if (!gGraphics || !gGraphics->AssetsLoaded())
726 if (screenScale != gGraphics->GetScreenScale())
728 gGraphics->SetScreenScale(screenScale);
731 if (gGraphics->IsDirty(rects))
733 gGraphics->SetAllControlsClean();
734 gGraphics->Draw(rects);
738EMsgBoxResult IGraphicsWeb::ShowMessageBox(
const char* str,
const char* , EMsgBoxType type, IMsgBoxCompletionHandlerFunc completionHandler)
740 ReleaseMouseCapture();
742 EMsgBoxResult result = kNoResult;
748 val::global(
"window").call<val>(
"alert", std::string(str));
749 result = EMsgBoxResult::kOK;
755 result =
static_cast<EMsgBoxResult
>(val::global(
"window").call<val>(
"confirm", std::string(str)).as<int>());
760 return result = kNoResult;
763 if(completionHandler)
764 completionHandler(result);
769void IGraphicsWeb::PromptForFile(WDL_String& filename, WDL_String& path, EFileAction action,
const char* ext, IFileDialogCompletionHandlerFunc completionHandler)
781void IGraphicsWeb::PromptForDirectory(WDL_String& path, IFileDialogCompletionHandlerFunc completionHandler)
794bool IGraphicsWeb::PromptForColor(
IColor& color,
const char* str, IColorPickerHandlerFunc func)
796 ReleaseMouseCapture();
798 gColorPickerHandlerFunc = func;
800 val inputEl = val::global(
"document").call<val>(
"createElement", std::string(
"input"));
801 inputEl.call<
void>(
"setAttribute", std::string(
"type"), std::string(
"color"));
803 colorStr.SetFormatted(64,
"#%02x%02x%02x", color.R, color.G, color.B);
804 inputEl.call<
void>(
"setAttribute", std::string(
"value"), std::string(colorStr.Get()));
805 inputEl.call<
void>(
"click");
806 inputEl.call<
void>(
"addEventListener", std::string(
"input"), val::module_property(
"color_picker_callback"),
false);
807 inputEl.call<
void>(
"addEventListener", std::string(
"onChange"), val::module_property(
"color_picker_callback"),
false);
812void IGraphicsWeb::CreatePlatformTextEntry(
int paramIdx,
const IText& text,
const IRECT& bounds,
int length,
const char* str)
814 val input = val::global(
"document").call<val>(
"createElement", std::string(
"input"));
815 val rect = GetCanvas().call<val>(
"getBoundingClientRect");
817 auto setDim = [&input](
const char *dimName,
double pixels)
820 dimstr.SetFormatted(32,
"%fpx", pixels);
821 input[
"style"].set(dimName, std::string(dimstr.Get()));
824 auto setColor = [&input](
const char *colorName,
IColor color)
827 str.SetFormatted(64,
"rgba(%d, %d, %d, %d)", color.R, color.G, color.B, color.A);
828 input[
"style"].set(colorName, std::string(str.Get()));
831 input.set(
"id", std::string(
"textEntry"));
832 input[
"style"].set(
"position", val(
"fixed"));
833 setDim(
"left", rect[
"left"].as<double>() + bounds.L);
834 setDim(
"top", rect[
"top"].as<double>() + bounds.T);
835 setDim(
"width", bounds.
W());
836 setDim(
"height", bounds.
H());
838 setColor(
"color", text.mTextEntryFGColor);
839 setColor(
"background-color", text.mTextEntryBGColor);
840 if (paramIdx > kNoParameter)
842 const IParam* pParam = GetDelegate()->GetParam(paramIdx);
844 switch (pParam->
Type())
846 case IParam::kTypeEnum:
847 case IParam::kTypeInt:
848 case IParam::kTypeBool:
849 input.set(
"type", val(
"number"));
851 case IParam::kTypeDouble:
852 input.set(
"type", val(
"number"));
860 input.set(
"type", val(
"text"));
863 val::global(
"document")[
"body"].call<
void>(
"appendChild", input);
864 input.call<
void>(
"focus");
865 emscripten_set_focusout_callback(
"textEntry",
this, 1, complete_text_entry);
866 emscripten_set_keydown_callback(
"textEntry",
this, 1, text_entry_keydown);
874bool IGraphicsWeb::OpenURL(
const char* url,
const char* msgWindowTitle,
const char* confirmMsg,
const char* errMsgOnFailure)
876 val::global(
"window").call<val>(
"open", std::string(url), std::string(
"_blank"));
881void IGraphicsWeb::DrawResize()
883 val canvas = GetCanvas();
885 canvas[
"style"].set(
"width", val(Width() * GetDrawScale()));
886 canvas[
"style"].set(
"height", val(Height() * GetDrawScale()));
888 canvas.set(
"width", Width() * GetBackingPixelScale());
889 canvas.set(
"height", Height() * GetBackingPixelScale());
891 IGRAPHICS_DRAW_CLASS::DrawResize();
894PlatformFontPtr IGraphicsWeb::LoadPlatformFont(
const char* fontID,
const char* fileNameOrResID)
897 const EResourceLocation fontLocation =
LocateResource(fileNameOrResID,
"ttf", fullPath, GetBundleID(),
nullptr,
nullptr);
899 if (fontLocation == kNotFound)
902 return PlatformFontPtr(
new FileFont(fontID,
"", fullPath.Get()));
905PlatformFontPtr IGraphicsWeb::LoadPlatformFont(
const char* fontID,
const char* fontName, ETextStyle style)
907 const char* styles[] = {
"normal",
"bold",
"italic" };
909 return PlatformFontPtr(
new Font(fontName, styles[
static_cast<int>(style)]));
912PlatformFontPtr IGraphicsWeb::LoadPlatformFont(
const char* fontID,
void* pData,
int dataSize)
914 return PlatformFontPtr(
new MemoryFont(fontID,
"", pData, dataSize));
917#if defined IGRAPHICS_CANVAS
918#include "IGraphicsCanvas.cpp"
919#elif defined IGRAPHICS_NANOVG
920#include "IGraphicsNanoVG.cpp"
922#ifdef IGRAPHICS_FREETYPE
923#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 for a SOMETHING that uses IGraphics for it's 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.
void 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.
EParamType Type() const
Get the parameter's type.
Used to manage a list of rectangular areas and optimize them for drawing to the screen.
Used to group mouse coordinates with mouse modifier information.
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,...