mirror of
https://github.com/gnif/LookingGlass.git
synced 2024-12-22 05:42:58 +00:00
[client] add SVG loading support and use icons for status display
This brings nanosvg into the project for SVG loading and rendering. Unfortunatly we can not at this time use a submodule for this project until https://github.com/memononen/nanosvg/pull/214 is merged.
This commit is contained in:
parent
8aa36144dc
commit
8974ae4fb5
19 changed files with 4947 additions and 92 deletions
|
@ -110,7 +110,10 @@ add_custom_command(
|
|||
include_directories(
|
||||
${PROJECT_TOP}
|
||||
${PROJECT_SOURCE_DIR}/include
|
||||
${CMAKE_BINARY_DIR}
|
||||
${CMAKE_BINARY_DIR}/include
|
||||
|
||||
${PROJECT_TOP}/repos/nanosvg/src
|
||||
)
|
||||
|
||||
link_libraries(
|
||||
|
@ -142,12 +145,13 @@ set(SOURCES
|
|||
src/overlay/help.c
|
||||
src/overlay/config.c
|
||||
src/overlay/msg.c
|
||||
src/overlay/record.c
|
||||
src/overlay/status.c
|
||||
)
|
||||
|
||||
# Force cimgui to build as a static library.
|
||||
set(IMGUI_STATIC "yes" CACHE STRING "Build as a static library")
|
||||
|
||||
add_subdirectory("${PROJECT_TOP}/resources" "${CMAKE_BINARY_DIR}/resources")
|
||||
add_subdirectory("${PROJECT_TOP}/common" "${CMAKE_BINARY_DIR}/common" )
|
||||
add_subdirectory("${PROJECT_TOP}/repos/LGMP/lgmp" "${CMAKE_BINARY_DIR}/LGMP" )
|
||||
add_subdirectory("${PROJECT_TOP}/repos/PureSpice" "${CMAKE_BINARY_DIR}/PureSpice")
|
||||
|
@ -163,6 +167,7 @@ target_compile_definitions(looking-glass-client PRIVATE CIMGUI_DEFINE_ENUMS_AND_
|
|||
target_link_libraries(looking-glass-client
|
||||
${EXE_FLAGS}
|
||||
PkgConfig::FONTCONFIG
|
||||
lg_resources
|
||||
lg_common
|
||||
displayservers
|
||||
lgmp
|
||||
|
|
|
@ -172,6 +172,17 @@ typedef struct LG_RendererOps
|
|||
const bool newFrame, const bool invalidateWindow,
|
||||
void (*preSwap)(void * udata), void * udata);
|
||||
|
||||
/* called to create a texture from the specified 32-bit RGB image data. This
|
||||
* method is for use with Dear ImGui
|
||||
* Context: renderThread */
|
||||
void * (*createTexture)(LG_Renderer * renderer,
|
||||
int width, int height, uint8_t * data);
|
||||
|
||||
/* called to free a texture previously created by createTexture. This method
|
||||
* is for use with Dear ImGui
|
||||
* Context: renderThread */
|
||||
void (*freeTexture)(LG_Renderer * renderer, void * texture);
|
||||
|
||||
/* setup the spice display */
|
||||
void (*spiceConfigure)(LG_Renderer * renderer, int width, int height);
|
||||
|
||||
|
|
|
@ -27,9 +27,23 @@
|
|||
|
||||
typedef struct ImVec2 ImVec2;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
void * tex;
|
||||
int width;
|
||||
int height;
|
||||
}
|
||||
OverlayImage;
|
||||
|
||||
void overlayGetImGuiRect(struct Rect * rect);
|
||||
ImVec2 * overlayGetScreenSize(void);
|
||||
void overlayTextURL(const char * url, const char * text);
|
||||
void overlayTextMaybeURL(const char * text, bool wrapped);
|
||||
|
||||
// create a texture from a SVG and scale it to fit the supplied width & height
|
||||
bool overlayLoadSVG(const char * data, unsigned int size, OverlayImage * image,
|
||||
int width, int height);
|
||||
|
||||
void overlayFreeImage(OverlayImage * image);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1210,6 +1210,41 @@ static bool egl_render(LG_Renderer * renderer, LG_RendererRotate rotate,
|
|||
return true;
|
||||
}
|
||||
|
||||
static void * egl_createTexture(LG_Renderer * renderer,
|
||||
int width, int height, uint8_t * data)
|
||||
{
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
data);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
return (void*)(intptr_t)tex;
|
||||
}
|
||||
|
||||
static void egl_freeTexture(LG_Renderer * renderer, void * texture)
|
||||
{
|
||||
GLuint tex = (GLuint)(intptr_t)texture;
|
||||
glDeleteTextures(1, &tex);
|
||||
}
|
||||
|
||||
static void egl_spiceConfigure(LG_Renderer * renderer, int width, int height)
|
||||
{
|
||||
struct Inst * this = UPCAST(struct Inst, renderer);
|
||||
|
@ -1257,6 +1292,8 @@ struct LG_RendererOps LGR_EGL =
|
|||
.renderStartup = egl_renderStartup,
|
||||
.needsRender = egl_needsRender,
|
||||
.render = egl_render,
|
||||
.createTexture = egl_createTexture,
|
||||
.freeTexture = egl_freeTexture,
|
||||
|
||||
.spiceConfigure = egl_spiceConfigure,
|
||||
.spiceDrawFill = egl_spiceDrawFill,
|
||||
|
|
|
@ -663,6 +663,41 @@ static void renderWait(struct Inst * this)
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
static void * opengl_createTexture(LG_Renderer * renderer,
|
||||
int width, int height, uint8_t * data)
|
||||
{
|
||||
GLuint tex;
|
||||
glGenTextures(1, &tex);
|
||||
glBindTexture(GL_TEXTURE_2D, tex);
|
||||
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
|
||||
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
|
||||
|
||||
glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
|
||||
glTexImage2D(
|
||||
GL_TEXTURE_2D,
|
||||
0,
|
||||
GL_RGBA,
|
||||
width,
|
||||
height,
|
||||
0,
|
||||
GL_RGBA,
|
||||
GL_UNSIGNED_BYTE,
|
||||
data);
|
||||
|
||||
glBindTexture(GL_TEXTURE_2D, 0);
|
||||
|
||||
return (void*)(intptr_t)tex;
|
||||
}
|
||||
|
||||
static void opengl_freeTexture(LG_Renderer * renderer, void * texture)
|
||||
{
|
||||
GLuint tex = (GLuint)(intptr_t)texture;
|
||||
glDeleteTextures(1, &tex);
|
||||
}
|
||||
|
||||
static void opengl_spiceConfigure(LG_Renderer * renderer, int width, int height)
|
||||
{
|
||||
struct Inst * this = UPCAST(struct Inst, renderer);
|
||||
|
@ -797,6 +832,8 @@ const LG_RendererOps LGR_OpenGL =
|
|||
.renderStartup = opengl_renderStartup,
|
||||
.needsRender = opengl_needsRender,
|
||||
.render = opengl_render,
|
||||
.createTexture = opengl_createTexture,
|
||||
.freeTexture = opengl_freeTexture,
|
||||
|
||||
.spiceConfigure = opengl_spiceConfigure,
|
||||
.spiceDrawFill = opengl_spiceDrawFill,
|
||||
|
|
|
@ -676,7 +676,7 @@ void app_msgBoxClose(MsgBoxHandle handle)
|
|||
|
||||
void app_showRecord(bool show)
|
||||
{
|
||||
overlayRecord_show(show);
|
||||
overlayStatus_set(LG_USER_STATUS_RECORDING, show);
|
||||
}
|
||||
|
||||
KeybindHandle app_registerKeybind(int sc, KeybindFn callback, void * opaque, const char * description)
|
||||
|
@ -1072,4 +1072,5 @@ void app_useSpiceDisplay(bool enable)
|
|||
renderQueue_spiceShow(false);
|
||||
purespice_disconnectChannel(PS_CHANNEL_DISPLAY);
|
||||
}
|
||||
overlayStatus_set(LG_USER_STATUS_SPICE, enable);
|
||||
}
|
||||
|
|
|
@ -1725,7 +1725,7 @@ int main(int argc, char * argv[])
|
|||
app_registerOverlay(&LGOverlayGraphs, NULL);
|
||||
app_registerOverlay(&LGOverlayHelp , NULL);
|
||||
app_registerOverlay(&LGOverlayMsg , NULL);
|
||||
app_registerOverlay(&LGOverlayRecord, NULL);
|
||||
app_registerOverlay(&LGOverlayStatus, NULL);
|
||||
|
||||
// early renderer setup for option registration
|
||||
for(unsigned int i = 0; i < LG_RENDERER_COUNT; ++i)
|
||||
|
|
|
@ -1,87 +0,0 @@
|
|||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2022 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "interface/overlay.h"
|
||||
#include "cimgui.h"
|
||||
#include "overlay_utils.h"
|
||||
|
||||
#include "common/stringutils.h"
|
||||
|
||||
#include "../main.h"
|
||||
|
||||
static bool recordShow = false;
|
||||
static bool recordToggle = false;
|
||||
static unsigned long long lastTick = 0;
|
||||
|
||||
static bool record_init(void ** udata, const void * params)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
static void record_free(void * udata)
|
||||
{}
|
||||
|
||||
static int record_render(void * udata, bool interactive, struct Rect * windowRects,
|
||||
int maxRects)
|
||||
{
|
||||
if (!recordShow || !recordToggle)
|
||||
return 0;
|
||||
|
||||
ImVec2 * screen = overlayGetScreenSize();
|
||||
ImDrawList_AddCircleFilled(igGetBackgroundDrawList_Nil(),
|
||||
(ImVec2) { screen->x - 20.0f, 20.0f },
|
||||
5.0f, 0xFF0000FF, 0
|
||||
);
|
||||
|
||||
*windowRects = (struct Rect) {
|
||||
.x = screen->x - 26, .y = 14, .w = 12, .h = 12
|
||||
};
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool record_tick(void * udata, unsigned long long tickCount)
|
||||
{
|
||||
if (tickCount - lastTick >= 25)
|
||||
{
|
||||
recordToggle = !recordToggle;
|
||||
lastTick = tickCount;
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
struct LG_OverlayOps LGOverlayRecord =
|
||||
{
|
||||
.name = "record",
|
||||
.init = record_init,
|
||||
.free = record_free,
|
||||
.render = record_render,
|
||||
.tick = record_tick,
|
||||
};
|
||||
|
||||
void overlayRecord_show(bool show)
|
||||
{
|
||||
if (show == recordShow)
|
||||
return;
|
||||
|
||||
recordShow = show;
|
||||
if (g_state.state != APP_STATE_SHUTDOWN)
|
||||
app_invalidateOverlay(true);
|
||||
}
|
134
client/src/overlay/status.c
Normal file
134
client/src/overlay/status.c
Normal file
|
@ -0,0 +1,134 @@
|
|||
/**
|
||||
* Looking Glass
|
||||
* Copyright © 2017-2022 The Looking Glass Authors
|
||||
* https://looking-glass.io
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify it
|
||||
* under the terms of the GNU General Public License as published by the Free
|
||||
* Software Foundation; either version 2 of the License, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but WITHOUT
|
||||
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
|
||||
* more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc., 59
|
||||
* Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*/
|
||||
|
||||
#include "interface/overlay.h"
|
||||
#include "cimgui.h"
|
||||
|
||||
#include "../overlays.h"
|
||||
#include "../main.h"
|
||||
#include "overlay_utils.h"
|
||||
|
||||
#include "resources/status/recording.svg.h"
|
||||
#include "resources/status/spice.svg.h"
|
||||
|
||||
//TODO: Make this user configurable?
|
||||
#define ICON_SIZE 32
|
||||
|
||||
static bool l_state[LG_USER_STATUS_MAX] = { 0 };
|
||||
static OverlayImage l_image[LG_USER_STATUS_MAX] = { 0 };
|
||||
static bool l_recordToggle;
|
||||
|
||||
static bool status_init(void ** udata, const void * params)
|
||||
{
|
||||
overlayLoadSVG(b_status_recording_svg, b_status_recording_svg_size,
|
||||
&l_image[LG_USER_STATUS_RECORDING], ICON_SIZE, ICON_SIZE);
|
||||
|
||||
overlayLoadSVG(b_status_spice_svg, b_status_spice_svg_size,
|
||||
&l_image[LG_USER_STATUS_SPICE], ICON_SIZE, ICON_SIZE);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void status_free(void * udata)
|
||||
{
|
||||
for(int i = 0; i < LG_USER_STATUS_MAX; ++i)
|
||||
overlayFreeImage(&l_image[i]);
|
||||
}
|
||||
|
||||
static int status_render(void * udata, bool interactive, struct Rect * windowRects,
|
||||
int maxRects)
|
||||
{
|
||||
const int marginX = 10;
|
||||
const int marginY = 10;
|
||||
const int gapX = 5;
|
||||
|
||||
ImVec2 * screen = overlayGetScreenSize();
|
||||
struct Rect rect = {
|
||||
.x = screen->x - LG_USER_STATUS_MAX * (ICON_SIZE + gapX) - marginX,
|
||||
.y = marginY,
|
||||
.w = LG_USER_STATUS_MAX * (ICON_SIZE + gapX),
|
||||
.h = ICON_SIZE
|
||||
};
|
||||
|
||||
int xPos = screen->x - marginX;
|
||||
for(int i = 0; i < LG_USER_STATUS_MAX; ++i)
|
||||
{
|
||||
OverlayImage * img = &l_image[i];
|
||||
if (!l_state[i] || !img->tex)
|
||||
continue;
|
||||
|
||||
// if the recording indicator is off, don't draw but reserve space
|
||||
if (i == LG_USER_STATUS_RECORDING && !l_recordToggle)
|
||||
goto next;
|
||||
|
||||
ImDrawList_AddImage(
|
||||
igGetBackgroundDrawList_Nil(),
|
||||
img->tex,
|
||||
(ImVec2){
|
||||
xPos,
|
||||
marginY
|
||||
},
|
||||
(ImVec2){
|
||||
xPos - ICON_SIZE,
|
||||
img->height + marginY
|
||||
},
|
||||
(ImVec2){ 0, 0 },
|
||||
(ImVec2){ 1, 1 },
|
||||
0xFFFFFFFF);
|
||||
|
||||
next:
|
||||
xPos -= ICON_SIZE + gapX;
|
||||
}
|
||||
|
||||
*windowRects = rect;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static bool status_tick(void * udata, unsigned long long tickCount)
|
||||
{
|
||||
static unsigned long long lastTick = 0;
|
||||
|
||||
if (tickCount - lastTick >= 25)
|
||||
{
|
||||
l_recordToggle = !l_recordToggle;
|
||||
lastTick = tickCount;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
struct LG_OverlayOps LGOverlayStatus =
|
||||
{
|
||||
.name = "status",
|
||||
.init = status_init,
|
||||
.free = status_free,
|
||||
.render = status_render,
|
||||
.tick = status_tick,
|
||||
};
|
||||
|
||||
void overlayStatus_set(LGUserStatus status, bool value)
|
||||
{
|
||||
if (l_state[status] == value)
|
||||
return;
|
||||
|
||||
l_state[status] = value;
|
||||
app_invalidateOverlay(true);
|
||||
};
|
|
@ -26,6 +26,11 @@
|
|||
#include "cimgui.h"
|
||||
#include "main.h"
|
||||
|
||||
#define NANOSVG_IMPLEMENTATION
|
||||
#define NANOSVG_ALL_COLOR_KEYWORDS
|
||||
#define NANOSVGRAST_IMPLEMENTATION
|
||||
#include "nanosvgrast.h"
|
||||
|
||||
void overlayGetImGuiRect(struct Rect * rect)
|
||||
{
|
||||
ImVec2 size;
|
||||
|
@ -78,3 +83,93 @@ void overlayTextMaybeURL(const char * text, bool wrapped)
|
|||
else
|
||||
igText(text);
|
||||
}
|
||||
|
||||
bool overlayLoadSVG(const char * data, unsigned int size, OverlayImage * image,
|
||||
int width, int height)
|
||||
{
|
||||
image->tex = NULL;
|
||||
|
||||
//nsvgParse alters the data, we need to make a copy and null terminate it
|
||||
char * svg = malloc(size + 1);
|
||||
if (!svg)
|
||||
{
|
||||
DEBUG_ERROR("out of ram");
|
||||
goto err;
|
||||
}
|
||||
|
||||
memcpy(svg, data, size);
|
||||
svg[size] = 0;
|
||||
|
||||
NSVGimage * nvi = nsvgParse(svg, "px", 96.0);
|
||||
if (!nvi)
|
||||
{
|
||||
free(svg);
|
||||
DEBUG_ERROR("nvsgParseFromData failed");
|
||||
goto err;
|
||||
}
|
||||
free(svg);
|
||||
|
||||
NSVGrasterizer * rast = nsvgCreateRasterizer();
|
||||
if (!rast)
|
||||
{
|
||||
DEBUG_ERROR("nsvgCreateRasterizer failed");
|
||||
goto err_image;
|
||||
}
|
||||
|
||||
double srcAspect = nvi->width / nvi->height;
|
||||
double dstAspect = (double)width / (double)height;
|
||||
float scale;
|
||||
if (dstAspect > srcAspect)
|
||||
{
|
||||
image->width = (double)height * srcAspect;
|
||||
image->height = height;
|
||||
scale = (float)image->width / nvi->width;
|
||||
}
|
||||
else
|
||||
{
|
||||
image->width = width;
|
||||
image->height = (double)width / srcAspect;
|
||||
scale = (float)image->height / nvi->height;
|
||||
}
|
||||
|
||||
uint8_t * img = malloc(image->width * image->height * 4);
|
||||
if (!img)
|
||||
{
|
||||
DEBUG_ERROR("out of ram");
|
||||
goto err_rast;
|
||||
}
|
||||
|
||||
nsvgRasterize(rast, nvi,
|
||||
0.0f, 0.0f,
|
||||
scale,
|
||||
img,
|
||||
image->width,
|
||||
image->height,
|
||||
image->width * 4);
|
||||
|
||||
image->tex = RENDERER(createTexture, image->width, image->height, img);
|
||||
free(img);
|
||||
|
||||
if (!image->tex)
|
||||
{
|
||||
DEBUG_ERROR("renderer failed to create the texture");
|
||||
goto err_rast;
|
||||
}
|
||||
|
||||
err_rast:
|
||||
nsvgDeleteRasterizer(rast);
|
||||
|
||||
err_image:
|
||||
nsvgDelete(nvi);
|
||||
|
||||
err:
|
||||
return image->tex != NULL;
|
||||
}
|
||||
|
||||
void overlayFreeImage(OverlayImage * image)
|
||||
{
|
||||
if (!image->tex)
|
||||
return;
|
||||
|
||||
RENDERER(freeTexture, image->tex);
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ extern struct LG_OverlayOps LGOverlayGraphs;
|
|||
extern struct LG_OverlayOps LGOverlayHelp;
|
||||
extern struct LG_OverlayOps LGOverlayConfig;
|
||||
extern struct LG_OverlayOps LGOverlayMsg;
|
||||
extern struct LG_OverlayOps LGOverlayRecord;
|
||||
extern struct LG_OverlayOps LGOverlayStatus;
|
||||
|
||||
void overlayAlert_show(LG_MsgAlert type, const char * fmt, va_list args);
|
||||
|
||||
|
@ -56,6 +56,14 @@ void overlayConfig_register(const char * title,
|
|||
void overlayConfig_registerTab(const char * title,
|
||||
void (*callback)(void * udata, int * id), void * udata);
|
||||
|
||||
void overlayRecord_show(bool show);
|
||||
typedef enum LG_UserStatus
|
||||
{
|
||||
LG_USER_STATUS_SPICE,
|
||||
LG_USER_STATUS_RECORDING,
|
||||
LG_USER_STATUS_MAX
|
||||
}
|
||||
LGUserStatus;
|
||||
|
||||
void overlayStatus_set(LGUserStatus, bool value);
|
||||
|
||||
#endif
|
||||
|
|
31
repos/nanosvg/.gitignore
vendored
Normal file
31
repos/nanosvg/.gitignore
vendored
Normal file
|
@ -0,0 +1,31 @@
|
|||
## Compiled source #
|
||||
*.com
|
||||
*.class
|
||||
*.dll
|
||||
*.exe
|
||||
*.o
|
||||
*.so
|
||||
test
|
||||
|
||||
## Logs and databases #
|
||||
*.log
|
||||
*.sql
|
||||
*.sqlite
|
||||
|
||||
## OS generated files #
|
||||
.DS_Store
|
||||
.DS_Store?
|
||||
._*
|
||||
.Spotlight-V100
|
||||
.Trashes
|
||||
ehthumbs.db
|
||||
Thumbs.db
|
||||
|
||||
## Build dir
|
||||
build/*
|
||||
|
||||
## Stuff in example
|
||||
example/_*
|
||||
|
||||
## xcode specific
|
||||
*xcuserdata*
|
18
repos/nanosvg/LICENSE.txt
Normal file
18
repos/nanosvg/LICENSE.txt
Normal file
|
@ -0,0 +1,18 @@
|
|||
Copyright (c) 2013-14 Mikko Mononen memon@inside.org
|
||||
|
||||
This software is provided 'as-is', without any express or implied
|
||||
warranty. In no event will the authors be held liable for any damages
|
||||
arising from the use of this software.
|
||||
|
||||
Permission is granted to anyone to use this software for any purpose,
|
||||
including commercial applications, and to alter it and redistribute it
|
||||
freely, subject to the following restrictions:
|
||||
|
||||
1. The origin of this software must not be misrepresented; you must not
|
||||
claim that you wrote the original software. If you use this software
|
||||
in a product, an acknowledgment in the product documentation would be
|
||||
appreciated but is not required.
|
||||
2. Altered source versions must be plainly marked as such, and must not be
|
||||
misrepresented as being the original software.
|
||||
3. This notice may not be removed or altered from any source distribution.
|
||||
|
3010
repos/nanosvg/src/nanosvg.h
Normal file
3010
repos/nanosvg/src/nanosvg.h
Normal file
File diff suppressed because it is too large
Load diff
1458
repos/nanosvg/src/nanosvgrast.h
Normal file
1458
repos/nanosvg/src/nanosvgrast.h
Normal file
File diff suppressed because it is too large
Load diff
23
resources/CMakeLists.txt
Normal file
23
resources/CMakeLists.txt
Normal file
|
@ -0,0 +1,23 @@
|
|||
cmake_minimum_required(VERSION 3.0)
|
||||
project(lg_resources LANGUAGES C)
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${PROJECT_SOURCE_DIR}/cmake/")
|
||||
|
||||
include(MakeObject)
|
||||
|
||||
function(build_resources)
|
||||
make_object(
|
||||
LG_RESOURCES
|
||||
${ARGN}
|
||||
)
|
||||
set(LG_RESOURCES_OBJS "${LG_RESOURCES_OBJS}" PARENT_SCOPE)
|
||||
set(LG_RESOURCES_INCS "${LG_RESOURCES_INCS}" PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
build_resources(
|
||||
status/spice.svg
|
||||
status/recording.svg
|
||||
)
|
||||
|
||||
add_library(lg_resources STATIC ${LG_RESOURCES_OBJS})
|
||||
set_target_properties(lg_resources PROPERTIES LINKER_LANGUAGE C)
|
15
resources/status/recording.svg
Normal file
15
resources/status/recording.svg
Normal file
|
@ -0,0 +1,15 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg width="100px" height="100px" viewBox="0 0 100 100" version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink">
|
||||
<!-- Generator: Sketch 50 (54983) - http://www.bohemiancoding.com/sketch -->
|
||||
<title>32. Microphone</title>
|
||||
<desc>Created with Sketch.</desc>
|
||||
<defs></defs>
|
||||
<g id="32.-Microphone" stroke="none" stroke-width="1" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round">
|
||||
<g transform="translate(20.000000, 2.000000)" stroke="#FF6B6B" stroke-width="4">
|
||||
<rect id="Layer-1" x="10" y="0" width="40" height="70" rx="20"></rect>
|
||||
<path d="M59.1760883,56 C56.0189777,69.1888659 44.1567785,78.9927367 30,78.9927367 C15.8460957,78.9927367 3.98153075,69.1900571 0.823950814,56" id="Layer-2"></path>
|
||||
<path d="M30,78.9687805 L30,95" id="Layer-3"></path>
|
||||
<path d="M10,96 L50,96" id="Layer-4"></path>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 996 B |
45
resources/status/spice.svg
Normal file
45
resources/status/spice.svg
Normal file
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!-- Generator: Adobe Illustrator 26.0.2, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
|
||||
<svg version="1.1" id="Layer_3" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
|
||||
viewBox="0 0 64 64" style="enable-background:new 0 0 64 64;" xml:space="preserve">
|
||||
<g>
|
||||
<path style="fill:#88929F;" d="M58,2H36.667L35,4l2,4l-0.001,4L40,15l-8,17l-5-12l4-9l-4.5-9H6C3.791,2,2,3.791,2,6v40
|
||||
c0,2.209,1.791,4,4,4h52c2.209,0,4-1.791,4-4V6C62,3.791,60.209,2,58,2z"/>
|
||||
<polygon style="fill:#C7E2FB;" points="58,6 36,6 37,8 36.999,12 40,15 32,32 27,20 31,11 28.5,6 6,6 6,42 58,42 "/>
|
||||
<polygon style="fill:#C7E2FB;" points="58,6 36,6 37,8 36.999,12 40,15 32,32 27,20 31,11 28.5,6 6,6 6,42 58,42 "/>
|
||||
<path style="fill:#EBF7FE;" d="M36,6l1,2l-0.001,4L40,15l-8,17l-5-12l4-9l-2.5-5H6v33h44c2.209,0,4-1.791,4-4V6H36z"/>
|
||||
<path style="fill:#88929F;" d="M45,58c1.105,0,2,0.895,2,2v2H17v-2c0-1.105,0.895-2,2-2H45z"/>
|
||||
<rect x="23" y="50" style="fill:#A0A8B2;" width="18" height="8"/>
|
||||
<polygon style="fill:#FFFFFF;" points="21,35 19,30 24,31 "/>
|
||||
<polygon style="fill:#FFFFFF;" points="43,38 45,33 40,34 "/>
|
||||
<g>
|
||||
<path style="fill:#D9DCE0;" d="M57,47h-8c-0.552,0-1-0.448-1-1l0,0c0-0.552,0.448-1,1-1h8c0.552,0,1,0.448,1,1l0,0
|
||||
C58,46.552,57.552,47,57,47z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path style="fill:#D9DCE0;" d="M45,47h-4c-0.552,0-1-0.448-1-1l0,0c0-0.552,0.448-1,1-1h4c0.552,0,1,0.448,1,1l0,0
|
||||
C46,46.552,45.552,47,45,47z"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M58,1H36.667c-0.297,0-0.578,0.132-0.768,0.36l-1.667,2c-0.254,0.305-0.304,0.732-0.126,1.087L36,8.236L35.999,12
|
||||
c0,0.265,0.105,0.52,0.293,0.707l2.504,2.503l-6.74,14.323l-3.967-9.521l3.825-8.606c0.122-0.273,0.114-0.586-0.019-0.854l-4.5-9
|
||||
C27.225,1.214,26.879,1,26.5,1H6C3.243,1,1,3.243,1,6v40c0,2.757,2.243,5,5,5h16v6h-3c-1.654,0-3,1.346-3,3v2c0,0.552,0.448,1,1,1
|
||||
h30c0.552,0,1-0.448,1-1v-2c0-1.654-1.346-3-3-3h-3v-6h16c2.757,0,5-2.243,5-5V6C63,3.243,60.757,1,58,1z M26.35,19h-5.936
|
||||
L18,16.586V13h-2v4c0,0.265,0.105,0.52,0.293,0.707L18.586,20l-4.293,4.293l1.414,1.414L20.414,21h5.919l4.744,11.385
|
||||
c0.152,0.365,0.505,0.606,0.9,0.615c0.389,0.018,0.759-0.216,0.927-0.574l7.449-15.829l4.711,3.926l0.946,6.62l1.979-0.283
|
||||
l-0.929-6.505L49.414,18H53v-2h-4c-0.265,0-0.52,0.105-0.707,0.293l-2.354,2.354l-5.263-4.386l-2.676-2.675L38,8
|
||||
c0-0.155-0.036-0.308-0.105-0.447L37.618,7H57v34H7V7h20.882l2.013,4.025L26.35,19z M46,60v1H18v-1c0-0.551,0.449-1,1-1h26
|
||||
C45.551,59,46,59.449,46,60z M40,57H24v-6h16V57z M61,46c0,1.654-1.346,3-3,3H6c-1.654,0-3-1.346-3-3V6c0-1.654,1.346-3,3-3
|
||||
h19.882l1,2H6C5.448,5,5,5.448,5,6v36c0,0.552,0.448,1,1,1h52c0.552,0,1-0.448,1-1V6c0-0.552-0.448-1-1-1H36.618l-0.431-0.862
|
||||
L37.135,3H58c1.654,0,3,1.346,3,3V46z"/>
|
||||
<path d="M20.071,35.372c0.134,0.335,0.439,0.572,0.797,0.62C20.913,35.997,20.957,36,21,36c0.312,0,0.61-0.146,0.8-0.4l3-4
|
||||
c0.206-0.275,0.257-0.636,0.134-0.957s-0.401-0.556-0.738-0.624l-5-1c-0.361-0.071-0.73,0.059-0.965,0.341
|
||||
c-0.235,0.282-0.296,0.67-0.16,1.011L20.071,35.372z M22.248,31.669l-0.98,1.307l-0.653-1.634L22.248,31.669z"/>
|
||||
<path d="M42.2,38.6c0.19,0.253,0.487,0.4,0.8,0.4c0.043,0,0.087-0.003,0.131-0.009c0.358-0.047,0.663-0.284,0.797-0.62l2-5
|
||||
c0.136-0.341,0.075-0.729-0.16-1.011c-0.234-0.282-0.603-0.415-0.965-0.341l-5,1c-0.336,0.067-0.615,0.303-0.738,0.624
|
||||
S38.994,34.325,39.2,34.6L42.2,38.6z M43.386,34.343l-0.653,1.634l-0.98-1.307L43.386,34.343z"/>
|
||||
<rect x="40" y="25" width="2" height="2"/>
|
||||
<rect x="20" y="10" width="2" height="2"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
After Width: | Height: | Size: 3.5 KiB |
Loading…
Reference in a new issue