| 12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025 |
- /*
- * Nuklear - 1.32.0 - public domain
- * no warrenty implied; use at your own risk.
- * authored from 2015-2016 by Micha Mettke
- */
- /*
- * ==============================================================
- *
- * API
- *
- * ===============================================================
- */
- #ifndef NK_GDI_H_
- #define NK_GDI_H_
- #define WIN32_LEAN_AND_MEAN
- #include <windows.h>
- #include <wingdi.h>
- typedef struct GdiFont GdiFont;
- NK_API struct nk_context* nk_gdi_init(GdiFont *font, HDC window_dc, unsigned int width, unsigned int height);
- NK_API int nk_gdi_handle_event(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam);
- NK_API void nk_gdi_render(struct nk_color clear);
- NK_API void nk_gdi_shutdown(void);
- /* font */
- NK_API GdiFont* nk_gdifont_create(const char *name, int size);
- NK_API void nk_gdifont_del(GdiFont *font);
- NK_API void nk_gdi_set_font(GdiFont *font);
- #endif
- /*
- * ==============================================================
- *
- * IMPLEMENTATION
- *
- * ===============================================================
- */
- #ifdef NK_GDI_IMPLEMENTATION
- #include <string.h>
- #include <stdlib.h>
- #include <malloc.h>
- struct GdiFont {
- struct nk_user_font nk;
- int height;
- HFONT handle;
- HDC dc;
- };
- static struct {
- HBITMAP bitmap;
- HDC window_dc;
- HDC memory_dc;
- unsigned int width;
- unsigned int height;
- struct nk_context ctx;
- } gdi;
- static void
- nk_create_image(struct nk_image * image, const char * frame_buffer, const int width, const int height)
- {
- if (image && frame_buffer && (width > 0) && (height > 0))
- {
- const unsigned char * src = (const unsigned char *)frame_buffer;
- INT row = ((width * 3 + 3) & ~3);
- LPBYTE lpBuf, pb = NULL;
- BITMAPINFO bi = { 0 };
- HBITMAP hbm;
- int v, i;
- image->w = width;
- image->h = height;
- image->region[0] = 0;
- image->region[1] = 0;
- image->region[2] = width;
- image->region[3] = height;
- bi.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- bi.bmiHeader.biWidth = width;
- bi.bmiHeader.biHeight = height;
- bi.bmiHeader.biPlanes = 1;
- bi.bmiHeader.biBitCount = 24;
- bi.bmiHeader.biCompression = BI_RGB;
- bi.bmiHeader.biSizeImage = row * height;
- hbm = CreateDIBSection(NULL, &bi, DIB_RGB_COLORS, (void**)&lpBuf, NULL, 0);
- pb = lpBuf + row * height;
- for (v = 0; v < height; v++)
- {
- pb -= row;
- for (i = 0; i < row; i += 3)
- {
- pb[i + 0] = src[0];
- pb[i + 1] = src[1];
- pb[i + 2] = src[2];
- src += 3;
- }
- }
- SetDIBits(NULL, hbm, 0, height, lpBuf, &bi, DIB_RGB_COLORS);
- image->handle.ptr = hbm;
- }
- }
- static void
- nk_delete_image(struct nk_image * image)
- {
- if (image && image->handle.id != 0)
- {
- HBITMAP hbm = (HBITMAP)image->handle.ptr;
- DeleteObject(hbm);
- memset(image, 0, sizeof(struct nk_image));
- }
- }
- static void
- nk_gdi_draw_image(short x, short y, unsigned short w, unsigned short h,
- struct nk_image img, struct nk_color col)
- {
- HBITMAP hbm = (HBITMAP)img.handle.ptr;
- HDC hDCBits;
- BITMAP bitmap;
- if (!gdi.memory_dc || !hbm)
- return;
- hDCBits = CreateCompatibleDC(gdi.memory_dc);
- GetObject(hbm, sizeof(BITMAP), (LPSTR)&bitmap);
- SelectObject(hDCBits, hbm);
- StretchBlt(gdi.memory_dc, x, y, w, h, hDCBits, 0, 0, bitmap.bmWidth, bitmap.bmHeight, SRCCOPY);
- DeleteDC(hDCBits);
- }
- static COLORREF
- convert_color(struct nk_color c)
- {
- return c.r | (c.g << 8) | (c.b << 16);
- }
- static void
- nk_gdi_scissor(HDC dc, float x, float y, float w, float h)
- {
- SelectClipRgn(dc, NULL);
- IntersectClipRect(dc, (int)x, (int)y, (int)(x + w + 1), (int)(y + h + 1));
- }
- static void
- nk_gdi_stroke_line(HDC dc, short x0, short y0, short x1,
- short y1, unsigned int line_thickness, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- HPEN pen = NULL;
- if (line_thickness == 1) {
- SetDCPenColor(dc, color);
- } else {
- pen = CreatePen(PS_SOLID, line_thickness, color);
- SelectObject(dc, pen);
- }
- MoveToEx(dc, x0, y0, NULL);
- LineTo(dc, x1, y1);
- if (pen) {
- SelectObject(dc, GetStockObject(DC_PEN));
- DeleteObject(pen);
- }
- }
- static void
- nk_gdi_stroke_rect(HDC dc, short x, short y, unsigned short w,
- unsigned short h, unsigned short r, unsigned short line_thickness, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- HGDIOBJ br;
- HPEN pen = NULL;
- if (line_thickness == 1) {
- SetDCPenColor(dc, color);
- } else {
- pen = CreatePen(PS_SOLID, line_thickness, color);
- SelectObject(dc, pen);
- }
- br = SelectObject(dc, GetStockObject(NULL_BRUSH));
- if (r == 0) {
- Rectangle(dc, x, y, x + w, y + h);
- } else {
- RoundRect(dc, x, y, x + w, y + h, r, r);
- }
- SelectObject(dc, br);
- if (pen) {
- SelectObject(dc, GetStockObject(DC_PEN));
- DeleteObject(pen);
- }
- }
- static void
- nk_gdi_fill_rect(HDC dc, short x, short y, unsigned short w,
- unsigned short h, unsigned short r, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- if (r == 0) {
- RECT rect;
- SetRect(&rect, x, y, x + w, y + h);
- SetBkColor(dc, color);
- ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
- } else {
- SetDCPenColor(dc, color);
- SetDCBrushColor(dc, color);
- RoundRect(dc, x, y, x + w, y + h, r, r);
- }
- }
- static void
- nk_gdi_set_vertexColor(PTRIVERTEX tri, struct nk_color col)
- {
- tri->Red = col.r << 8;
- tri->Green = col.g << 8;
- tri->Blue = col.b << 8;
- tri->Alpha = 0xff << 8;
- }
- static void
- nk_gdi_rect_multi_color(HDC dc, short x, short y, unsigned short w,
- unsigned short h, struct nk_color left, struct nk_color top,
- struct nk_color right, struct nk_color bottom)
- {
- BLENDFUNCTION alphaFunction;
- GRADIENT_RECT gRect;
- GRADIENT_TRIANGLE gTri[2];
- TRIVERTEX vt[4];
- alphaFunction.BlendOp = AC_SRC_OVER;
- alphaFunction.BlendFlags = 0;
- alphaFunction.SourceConstantAlpha = 0;
- alphaFunction.AlphaFormat = AC_SRC_ALPHA;
- /* TODO: This Case Needs Repair.*/
- /* Top Left Corner */
- vt[0].x = x;
- vt[0].y = y;
- nk_gdi_set_vertexColor(&vt[0], left);
- /* Top Right Corner */
- vt[1].x = x+w;
- vt[1].y = y;
- nk_gdi_set_vertexColor(&vt[1], top);
- /* Bottom Left Corner */
- vt[2].x = x;
- vt[2].y = y+h;
- nk_gdi_set_vertexColor(&vt[2], right);
- /* Bottom Right Corner */
- vt[3].x = x+w;
- vt[3].y = y+h;
- nk_gdi_set_vertexColor(&vt[3], bottom);
- gTri[0].Vertex1 = 0;
- gTri[0].Vertex2 = 1;
- gTri[0].Vertex3 = 2;
- gTri[1].Vertex1 = 2;
- gTri[1].Vertex2 = 1;
- gTri[1].Vertex3 = 3;
- GdiGradientFill(dc, vt, 4, gTri, 2 , GRADIENT_FILL_TRIANGLE);
- AlphaBlend(gdi.window_dc, x, y, x+w, y+h,gdi.memory_dc, x, y, x+w, y+h,alphaFunction);
- }
- static BOOL
- SetPoint(POINT *p, LONG x, LONG y)
- {
- if (!p)
- return FALSE;
- p->x = x;
- p->y = y;
- return TRUE;
- }
- static void
- nk_gdi_fill_triangle(HDC dc, short x0, short y0, short x1,
- short y1, short x2, short y2, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- POINT points[3];
- SetPoint(&points[0], x0, y0);
- SetPoint(&points[1], x1, y1);
- SetPoint(&points[2], x2, y2);
- SetDCPenColor(dc, color);
- SetDCBrushColor(dc, color);
- Polygon(dc, points, 3);
- }
- static void
- nk_gdi_stroke_triangle(HDC dc, short x0, short y0, short x1,
- short y1, short x2, short y2, unsigned short line_thickness, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- POINT points[4];
- HPEN pen = NULL;
- SetPoint(&points[0], x0, y0);
- SetPoint(&points[1], x1, y1);
- SetPoint(&points[2], x2, y2);
- SetPoint(&points[3], x0, y0);
- if (line_thickness == 1) {
- SetDCPenColor(dc, color);
- } else {
- pen = CreatePen(PS_SOLID, line_thickness, color);
- SelectObject(dc, pen);
- }
- Polyline(dc, points, 4);
- if (pen) {
- SelectObject(dc, GetStockObject(DC_PEN));
- DeleteObject(pen);
- }
- }
- static void
- nk_gdi_fill_polygon(HDC dc, const struct nk_vec2i *pnts, int count, struct nk_color col)
- {
- int i = 0;
- #define MAX_POINTS 64
- POINT points[MAX_POINTS];
- COLORREF color = convert_color(col);
- SetDCBrushColor(dc, color);
- SetDCPenColor(dc, color);
- for (i = 0; i < count && i < MAX_POINTS; ++i) {
- points[i].x = pnts[i].x;
- points[i].y = pnts[i].y;
- }
- Polygon(dc, points, i);
- #undef MAX_POINTS
- }
- static void
- nk_gdi_stroke_polygon(HDC dc, const struct nk_vec2i *pnts, int count,
- unsigned short line_thickness, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- HPEN pen = NULL;
- if (line_thickness == 1) {
- SetDCPenColor(dc, color);
- } else {
- pen = CreatePen(PS_SOLID, line_thickness, color);
- SelectObject(dc, pen);
- }
- if (count > 0) {
- int i;
- MoveToEx(dc, pnts[0].x, pnts[0].y, NULL);
- for (i = 1; i < count; ++i)
- LineTo(dc, pnts[i].x, pnts[i].y);
- LineTo(dc, pnts[0].x, pnts[0].y);
- }
- if (pen) {
- SelectObject(dc, GetStockObject(DC_PEN));
- DeleteObject(pen);
- }
- }
- static void
- nk_gdi_stroke_polyline(HDC dc, const struct nk_vec2i *pnts,
- int count, unsigned short line_thickness, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- HPEN pen = NULL;
- if (line_thickness == 1) {
- SetDCPenColor(dc, color);
- } else {
- pen = CreatePen(PS_SOLID, line_thickness, color);
- SelectObject(dc, pen);
- }
- if (count > 0) {
- int i;
- MoveToEx(dc, pnts[0].x, pnts[0].y, NULL);
- for (i = 1; i < count; ++i)
- LineTo(dc, pnts[i].x, pnts[i].y);
- }
- if (pen) {
- SelectObject(dc, GetStockObject(DC_PEN));
- DeleteObject(pen);
- }
- }
- static void
- nk_gdi_stroke_arc(HDC dc, short cx, short cy, unsigned short r, float amin, float adelta, unsigned short line_thickness, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- /* setup pen */
- HPEN pen = NULL;
- if (line_thickness == 1)
- SetDCPenColor(dc, color);
- else
- {
- /* the flat endcap makes thick arcs look better */
- DWORD pen_style = PS_SOLID | PS_ENDCAP_FLAT | PS_GEOMETRIC;
- LOGBRUSH brush;
- brush.lbStyle = BS_SOLID;
- brush.lbColor = color;
- brush.lbHatch = 0;
- pen = ExtCreatePen(pen_style, line_thickness, &brush, 0, NULL);
- SelectObject(dc, pen);
- }
- /* calculate arc and draw */
- int start_x = cx + (int) ((float)r*nk_cos(amin+adelta)),
- start_y = cy + (int) ((float)r*nk_sin(amin+adelta)),
- end_x = cx + (int) ((float)r*nk_cos(amin)),
- end_y = cy + (int) ((float)r*nk_sin(amin));
- HGDIOBJ br = SelectObject(dc, GetStockObject(NULL_BRUSH));
- SetArcDirection(dc, AD_COUNTERCLOCKWISE);
- Pie(dc, cx-r, cy-r, cx+r, cy+r, start_x, start_y, end_x, end_y);
- SelectObject(dc, br);
- if (pen)
- {
- SelectObject(dc, GetStockObject(DC_PEN));
- DeleteObject(pen);
- }
- }
- static void
- nk_gdi_fill_arc(HDC dc, short cx, short cy, unsigned short r, float amin, float adelta, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- SetDCBrushColor(dc, color);
- SetDCPenColor(dc, color);
- int start_x = cx + (int) ((float)r*nk_cos(amin+adelta)),
- start_y = cy + (int) ((float)r*nk_sin(amin+adelta)),
- end_x = cx + (int) ((float)r*nk_cos(amin)),
- end_y = cy + (int) ((float)r*nk_sin(amin));
- Pie(dc, cx-r, cy-r, cx+r, cy+r, start_x, start_y, end_x, end_y);
- }
- static void
- nk_gdi_fill_circle(HDC dc, short x, short y, unsigned short w,
- unsigned short h, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- SetDCBrushColor(dc, color);
- SetDCPenColor(dc, color);
- Ellipse(dc, x, y, x + w, y + h);
- }
- static void
- nk_gdi_stroke_circle(HDC dc, short x, short y, unsigned short w,
- unsigned short h, unsigned short line_thickness, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- HPEN pen = NULL;
- if (line_thickness == 1) {
- SetDCPenColor(dc, color);
- } else {
- pen = CreatePen(PS_SOLID, line_thickness, color);
- SelectObject(dc, pen);
- }
- HGDIOBJ br = SelectObject(dc, GetStockObject(NULL_BRUSH));
- SetDCBrushColor(dc, OPAQUE);
- Ellipse(dc, x, y, x + w, y + h);
- SelectObject(dc, br);
- if (pen) {
- SelectObject(dc, GetStockObject(DC_PEN));
- DeleteObject(pen);
- }
- }
- static void
- nk_gdi_stroke_curve(HDC dc, struct nk_vec2i p1,
- struct nk_vec2i p2, struct nk_vec2i p3, struct nk_vec2i p4,
- unsigned short line_thickness, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- POINT p[4];
- HPEN pen = NULL;
- SetPoint(&p[0], p1.x, p1.y);
- SetPoint(&p[1], p2.x, p2.y);
- SetPoint(&p[2], p3.x, p3.y);
- SetPoint(&p[3], p4.x, p4.y);
- if (line_thickness == 1) {
- SetDCPenColor(dc, color);
- } else {
- pen = CreatePen(PS_SOLID, line_thickness, color);
- SelectObject(dc, pen);
- }
- SetDCBrushColor(dc, OPAQUE);
- PolyBezier(dc, p, 4);
- if (pen) {
- SelectObject(dc, GetStockObject(DC_PEN));
- DeleteObject(pen);
- }
- }
- static void
- nk_gdi_draw_text(HDC dc, short x, short y, unsigned short w, unsigned short h,
- const char *text, int len, GdiFont *font, struct nk_color cbg, struct nk_color cfg)
- {
- int wsize;
- WCHAR* wstr;
- if(!text || !font || !len) return;
- wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
- wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
- SetBkMode(dc, TRANSPARENT); /* Transparent Text Background */
- SetBkColor(dc, convert_color(cbg));
- SetTextColor(dc, convert_color(cfg));
- SelectObject(dc, font->handle);
- ExtTextOutW(dc, x, y, ETO_OPAQUE, NULL, wstr, wsize, NULL);
- }
- static void
- nk_gdi_clear(HDC dc, struct nk_color col)
- {
- COLORREF color = convert_color(col);
- RECT rect;
- SetRect(&rect, 0, 0, gdi.width, gdi.height);
- SetBkColor(dc, color);
- ExtTextOutW(dc, 0, 0, ETO_OPAQUE, &rect, NULL, 0, NULL);
- }
- static void
- nk_gdi_blit(HDC dc)
- {
- BitBlt(dc, 0, 0, gdi.width, gdi.height, gdi.memory_dc, 0, 0, SRCCOPY);
- }
- GdiFont*
- nk_gdifont_create(const char *name, int size)
- {
- TEXTMETRICW metric;
- GdiFont *font = (GdiFont*)calloc(1, sizeof(GdiFont));
- if (!font)
- return NULL;
- font->dc = CreateCompatibleDC(0);
- font->handle = CreateFontA(size, 0, 0, 0, FW_NORMAL, FALSE, FALSE, FALSE, DEFAULT_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, CLEARTYPE_QUALITY, DEFAULT_PITCH | FF_DONTCARE, name);
- SelectObject(font->dc, font->handle);
- GetTextMetricsW(font->dc, &metric);
- font->height = metric.tmHeight;
- return font;
- }
- static float
- nk_gdifont_get_text_width(nk_handle handle, float height, const char *text, int len)
- {
- GdiFont *font = (GdiFont*)handle.ptr;
- SIZE size;
- int wsize;
- WCHAR* wstr;
- if (!font || !text)
- return 0;
- wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
- wstr = (WCHAR*)_alloca(wsize * sizeof(wchar_t));
- MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
- if (GetTextExtentPoint32W(font->dc, wstr, wsize, &size))
- return (float)size.cx;
- return -1.0f;
- }
- void
- nk_gdifont_del(GdiFont *font)
- {
- if(!font) return;
- DeleteObject(font->handle);
- DeleteDC(font->dc);
- free(font);
- }
- static void
- nk_gdi_clipboard_paste(nk_handle usr, struct nk_text_edit *edit)
- {
- (void)usr;
- if (IsClipboardFormatAvailable(CF_UNICODETEXT) && OpenClipboard(NULL))
- {
- HGLOBAL mem = GetClipboardData(CF_UNICODETEXT);
- if (mem)
- {
- SIZE_T size = GlobalSize(mem) - 1;
- if (size)
- {
- LPCWSTR wstr = (LPCWSTR)GlobalLock(mem);
- if (wstr)
- {
- int utf8size = WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), NULL, 0, NULL, NULL);
- if (utf8size)
- {
- char* utf8 = (char*)malloc(utf8size);
- if (utf8)
- {
- WideCharToMultiByte(CP_UTF8, 0, wstr, (int)(size / sizeof(wchar_t)), utf8, utf8size, NULL, NULL);
- nk_textedit_paste(edit, utf8, utf8size);
- free(utf8);
- }
- }
- GlobalUnlock(mem);
- }
- }
- }
- CloseClipboard();
- }
- }
- static void
- nk_gdi_clipboard_copy(nk_handle usr, const char *text, int len)
- {
- if (OpenClipboard(NULL))
- {
- int wsize = MultiByteToWideChar(CP_UTF8, 0, text, len, NULL, 0);
- if (wsize)
- {
- HGLOBAL mem = (HGLOBAL)GlobalAlloc(GMEM_MOVEABLE, (wsize + 1) * sizeof(wchar_t));
- if (mem)
- {
- wchar_t* wstr = (wchar_t*)GlobalLock(mem);
- if (wstr)
- {
- MultiByteToWideChar(CP_UTF8, 0, text, len, wstr, wsize);
- wstr[wsize] = 0;
- GlobalUnlock(mem);
- SetClipboardData(CF_UNICODETEXT, mem);
- }
- }
- }
- CloseClipboard();
- }
- }
- NK_API struct nk_context*
- nk_gdi_init(GdiFont *gdifont, HDC window_dc, unsigned int width, unsigned int height)
- {
- struct nk_user_font *font = &gdifont->nk;
- font->userdata = nk_handle_ptr(gdifont);
- font->height = (float)gdifont->height;
- font->width = nk_gdifont_get_text_width;
- gdi.bitmap = CreateCompatibleBitmap(window_dc, width, height);
- gdi.window_dc = window_dc;
- gdi.memory_dc = CreateCompatibleDC(window_dc);
- gdi.width = width;
- gdi.height = height;
- SelectObject(gdi.memory_dc, gdi.bitmap);
- nk_init_default(&gdi.ctx, font);
- gdi.ctx.clip.copy = nk_gdi_clipboard_copy;
- gdi.ctx.clip.paste = nk_gdi_clipboard_paste;
- return &gdi.ctx;
- }
- NK_API void
- nk_gdi_set_font(GdiFont *gdifont)
- {
- struct nk_user_font *font = &gdifont->nk;
- font->userdata = nk_handle_ptr(gdifont);
- font->height = (float)gdifont->height;
- font->width = nk_gdifont_get_text_width;
- nk_style_set_font(&gdi.ctx, font);
- }
- NK_API int
- nk_gdi_handle_event(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
- {
- static int insert_toggle = 0;
- switch (msg)
- {
- case WM_SIZE:
- {
- unsigned width = LOWORD(lparam);
- unsigned height = HIWORD(lparam);
- if (width != gdi.width || height != gdi.height)
- {
- DeleteObject(gdi.bitmap);
- gdi.bitmap = CreateCompatibleBitmap(gdi.window_dc, width, height);
- gdi.width = width;
- gdi.height = height;
- SelectObject(gdi.memory_dc, gdi.bitmap);
- }
- break;
- }
- case WM_PAINT:
- {
- PAINTSTRUCT paint;
- HDC dc = BeginPaint(wnd, &paint);
- nk_gdi_blit(dc);
- EndPaint(wnd, &paint);
- return 1;
- }
- case WM_KEYDOWN:
- case WM_KEYUP:
- case WM_SYSKEYDOWN:
- case WM_SYSKEYUP:
- {
- int down = !((lparam >> 31) & 1);
- int ctrl = GetKeyState(VK_CONTROL) & (1 << 15);
- switch (wparam)
- {
- case VK_SHIFT:
- case VK_LSHIFT:
- case VK_RSHIFT:
- nk_input_key(&gdi.ctx, NK_KEY_SHIFT, down);
- return 1;
- case VK_DELETE:
- nk_input_key(&gdi.ctx, NK_KEY_DEL, down);
- return 1;
- case VK_RETURN:
- case VK_SEPARATOR:
- nk_input_key(&gdi.ctx, NK_KEY_ENTER, down);
- return 1;
- case VK_TAB:
- nk_input_key(&gdi.ctx, NK_KEY_TAB, down);
- return 1;
- case VK_LEFT:
- if (ctrl)
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_WORD_LEFT, down);
- else
- nk_input_key(&gdi.ctx, NK_KEY_LEFT, down);
- return 1;
- case VK_RIGHT:
- if (ctrl)
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_WORD_RIGHT, down);
- else
- nk_input_key(&gdi.ctx, NK_KEY_RIGHT, down);
- return 1;
- case VK_BACK:
- nk_input_key(&gdi.ctx, NK_KEY_BACKSPACE, down);
- return 1;
- case VK_HOME:
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_START, down);
- nk_input_key(&gdi.ctx, NK_KEY_SCROLL_START, down);
- return 1;
- case VK_END:
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_END, down);
- nk_input_key(&gdi.ctx, NK_KEY_SCROLL_END, down);
- return 1;
- case VK_NEXT:
- nk_input_key(&gdi.ctx, NK_KEY_SCROLL_DOWN, down);
- return 1;
- case VK_PRIOR:
- nk_input_key(&gdi.ctx, NK_KEY_SCROLL_UP, down);
- return 1;
- case VK_ESCAPE:
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_RESET_MODE, down);
- return 1;
- case VK_INSERT:
- /* Only switch on release to avoid repeat issues
- * kind of confusing since we have to negate it but we're already
- * hacking it since Nuklear treats them as two separate keys rather
- * than a single toggle state */
- if (!down) {
- insert_toggle = !insert_toggle;
- if (insert_toggle) {
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_INSERT_MODE, !down);
- /* nk_input_key(&gdi.ctx, NK_KEY_TEXT_REPLACE_MODE, down); */
- } else {
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_REPLACE_MODE, !down);
- /* nk_input_key(&gdi.ctx, NK_KEY_TEXT_INSERT_MODE, down); */
- }
- }
- return 1;
- case 'A':
- if (ctrl) {
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_SELECT_ALL, down);
- return 1;
- }
- break;
- case 'B':
- if (ctrl) {
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_LINE_START, down);
- return 1;
- }
- break;
- case 'E':
- if (ctrl) {
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_LINE_END, down);
- return 1;
- }
- break;
- case 'C':
- if (ctrl) {
- nk_input_key(&gdi.ctx, NK_KEY_COPY, down);
- return 1;
- }
- break;
- case 'V':
- if (ctrl) {
- nk_input_key(&gdi.ctx, NK_KEY_PASTE, down);
- return 1;
- }
- break;
- case 'X':
- if (ctrl) {
- nk_input_key(&gdi.ctx, NK_KEY_CUT, down);
- return 1;
- }
- break;
- case 'Z':
- if (ctrl) {
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_UNDO, down);
- return 1;
- }
- break;
- case 'R':
- if (ctrl) {
- nk_input_key(&gdi.ctx, NK_KEY_TEXT_REDO, down);
- return 1;
- }
- break;
- }
- return 0;
- }
- case WM_CHAR:
- if (wparam >= 32)
- {
- nk_input_unicode(&gdi.ctx, (nk_rune)wparam);
- return 1;
- }
- break;
- case WM_LBUTTONDOWN:
- nk_input_button(&gdi.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
- SetCapture(wnd);
- return 1;
- case WM_LBUTTONUP:
- nk_input_button(&gdi.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
- nk_input_button(&gdi.ctx, NK_BUTTON_LEFT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
- ReleaseCapture();
- return 1;
- case WM_RBUTTONDOWN:
- nk_input_button(&gdi.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
- SetCapture(wnd);
- return 1;
- case WM_RBUTTONUP:
- nk_input_button(&gdi.ctx, NK_BUTTON_RIGHT, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
- ReleaseCapture();
- return 1;
- case WM_MBUTTONDOWN:
- nk_input_button(&gdi.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
- SetCapture(wnd);
- return 1;
- case WM_MBUTTONUP:
- nk_input_button(&gdi.ctx, NK_BUTTON_MIDDLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 0);
- ReleaseCapture();
- return 1;
- case WM_MOUSEWHEEL:
- nk_input_scroll(&gdi.ctx, nk_vec2(0,(float)(short)HIWORD(wparam) / WHEEL_DELTA));
- return 1;
- case WM_MOUSEMOVE:
- nk_input_motion(&gdi.ctx, (short)LOWORD(lparam), (short)HIWORD(lparam));
- return 1;
- case WM_LBUTTONDBLCLK:
- nk_input_button(&gdi.ctx, NK_BUTTON_DOUBLE, (short)LOWORD(lparam), (short)HIWORD(lparam), 1);
- return 1;
- }
- return 0;
- }
- NK_API void
- nk_gdi_shutdown(void)
- {
- DeleteObject(gdi.memory_dc);
- DeleteObject(gdi.bitmap);
- nk_free(&gdi.ctx);
- }
- NK_API void
- nk_gdi_render(struct nk_color clear)
- {
- const struct nk_command *cmd;
- HDC memory_dc = gdi.memory_dc;
- SelectObject(memory_dc, GetStockObject(DC_PEN));
- SelectObject(memory_dc, GetStockObject(DC_BRUSH));
- nk_gdi_clear(memory_dc, clear);
- nk_foreach(cmd, &gdi.ctx)
- {
- switch (cmd->type) {
- case NK_COMMAND_NOP: break;
- case NK_COMMAND_SCISSOR: {
- const struct nk_command_scissor *s =(const struct nk_command_scissor*)cmd;
- nk_gdi_scissor(memory_dc, s->x, s->y, s->w, s->h);
- } break;
- case NK_COMMAND_LINE: {
- const struct nk_command_line *l = (const struct nk_command_line *)cmd;
- nk_gdi_stroke_line(memory_dc, l->begin.x, l->begin.y, l->end.x,
- l->end.y, l->line_thickness, l->color);
- } break;
- case NK_COMMAND_RECT: {
- const struct nk_command_rect *r = (const struct nk_command_rect *)cmd;
- nk_gdi_stroke_rect(memory_dc, r->x, r->y, r->w, r->h,
- (unsigned short)r->rounding, r->line_thickness, r->color);
- } break;
- case NK_COMMAND_RECT_FILLED: {
- const struct nk_command_rect_filled *r = (const struct nk_command_rect_filled *)cmd;
- nk_gdi_fill_rect(memory_dc, r->x, r->y, r->w, r->h,
- (unsigned short)r->rounding, r->color);
- } break;
- case NK_COMMAND_CIRCLE: {
- const struct nk_command_circle *c = (const struct nk_command_circle *)cmd;
- nk_gdi_stroke_circle(memory_dc, c->x, c->y, c->w, c->h, c->line_thickness, c->color);
- } break;
- case NK_COMMAND_CIRCLE_FILLED: {
- const struct nk_command_circle_filled *c = (const struct nk_command_circle_filled *)cmd;
- nk_gdi_fill_circle(memory_dc, c->x, c->y, c->w, c->h, c->color);
- } break;
- case NK_COMMAND_ARC: {
- const struct nk_command_arc *q = (const struct nk_command_arc *)cmd;
- nk_gdi_stroke_arc(memory_dc, q->cx, q->cy, q->r, q->a[0], q->a[1], q->line_thickness, q->color);
- } break;
- case NK_COMMAND_ARC_FILLED: {
- const struct nk_command_arc_filled *q = (const struct nk_command_arc_filled *)cmd;
- nk_gdi_fill_arc(memory_dc, q->cx, q->cy, q->r, q->a[0], q->a[1], q->color);
- } break;
- case NK_COMMAND_TRIANGLE: {
- const struct nk_command_triangle*t = (const struct nk_command_triangle*)cmd;
- nk_gdi_stroke_triangle(memory_dc, t->a.x, t->a.y, t->b.x, t->b.y,
- t->c.x, t->c.y, t->line_thickness, t->color);
- } break;
- case NK_COMMAND_TRIANGLE_FILLED: {
- const struct nk_command_triangle_filled *t = (const struct nk_command_triangle_filled *)cmd;
- nk_gdi_fill_triangle(memory_dc, t->a.x, t->a.y, t->b.x, t->b.y,
- t->c.x, t->c.y, t->color);
- } break;
- case NK_COMMAND_POLYGON: {
- const struct nk_command_polygon *p =(const struct nk_command_polygon*)cmd;
- nk_gdi_stroke_polygon(memory_dc, p->points, p->point_count, p->line_thickness,p->color);
- } break;
- case NK_COMMAND_POLYGON_FILLED: {
- const struct nk_command_polygon_filled *p = (const struct nk_command_polygon_filled *)cmd;
- nk_gdi_fill_polygon(memory_dc, p->points, p->point_count, p->color);
- } break;
- case NK_COMMAND_POLYLINE: {
- const struct nk_command_polyline *p = (const struct nk_command_polyline *)cmd;
- nk_gdi_stroke_polyline(memory_dc, p->points, p->point_count, p->line_thickness, p->color);
- } break;
- case NK_COMMAND_TEXT: {
- const struct nk_command_text *t = (const struct nk_command_text*)cmd;
- nk_gdi_draw_text(memory_dc, t->x, t->y, t->w, t->h,
- (const char*)t->string, t->length,
- (GdiFont*)t->font->userdata.ptr,
- t->background, t->foreground);
- } break;
- case NK_COMMAND_CURVE: {
- const struct nk_command_curve *q = (const struct nk_command_curve *)cmd;
- nk_gdi_stroke_curve(memory_dc, q->begin, q->ctrl[0], q->ctrl[1],
- q->end, q->line_thickness, q->color);
- } break;
- case NK_COMMAND_RECT_MULTI_COLOR: {
- const struct nk_command_rect_multi_color *r = (const struct nk_command_rect_multi_color *)cmd;
- nk_gdi_rect_multi_color(memory_dc, r->x, r->y,r->w, r->h, r->left, r->top, r->right, r->bottom);
- } break;
- case NK_COMMAND_IMAGE: {
- const struct nk_command_image *i = (const struct nk_command_image *)cmd;
- nk_gdi_draw_image(i->x, i->y, i->w, i->h, i->img, i->col);
- } break;
- case NK_COMMAND_CUSTOM:
- default: break;
- }
- }
- nk_gdi_blit(gdi.window_dc);
- nk_clear(&gdi.ctx);
- }
- #endif
|