diff --git a/.clang-format b/.clang-format index 067015041..526b64afa 100644 --- a/.clang-format +++ b/.clang-format @@ -23,7 +23,7 @@ PointerAlignment: Right ReflowComments: true SpaceAfterCStyleCast: false SpaceBeforeAssignmentOperators: true -SpaceBeforeParens: ControlStatements +SpaceBeforeParens: ControlStatements SpaceInEmptyParentheses: false SpacesBeforeTrailingComments: 4 SpacesInAngles: false @@ -32,4 +32,4 @@ SpacesInContainerLiterals: false SpacesInParentheses: false SpacesInSquareBrackets: false SortIncludes: false -UseTab: ForContinuationAndIndentation +UseTab: Never diff --git a/.commitlintrc.js b/.commitlintrc.js index 5a08d4fed..59c6b3e8f 100644 --- a/.commitlintrc.js +++ b/.commitlintrc.js @@ -1,16 +1,8 @@ -const fs = require("fs"); -const path = require("path"); - module.exports = { extends: ["@commitlint/config-conventional"], rules: { "header-min-length": [2, "always", 1], "header-max-length": [2, "always", 72], "subject-case": [0], - "scope-enum": [ - 2, - "always", - [...fs.readdirSync(path.resolve(__dirname, "lib")), "docs"], - ], }, }; diff --git a/.github/workflows/ccpp.yml b/.github/workflows/ccpp.yml index 2c26bdffa..760ced8da 100644 --- a/.github/workflows/ccpp.yml +++ b/.github/workflows/ccpp.yml @@ -22,7 +22,6 @@ jobs: - name: Build run: | xmake config -m coverage -y -v - xmake build headers xmake -w - name: Run PandaGL tests @@ -45,15 +44,29 @@ jobs: - name: Package run: | xmake clean - xmake config -m release -y -c -v - xmake -w + xmake config -m release -y -k shared -c -v xmake package + xmake install -o dist/ubuntu + + - name: Package exmaples + run: | + cd examples + xmake -P . -v + xmake install -P . -o ../dist/ubuntu-examples + mv ../dist/ubuntu-examples/bin/* ../dist/ubuntu-examples/ + rm -r ../dist/ubuntu-examples/bin + + - uses: actions/upload-artifact@master + with: + name: ubuntu-dist + path: | + dist/ubuntu - uses: actions/upload-artifact@master with: - name: ubuntu-pacakges + name: ubuntu-examples path: | - build/packages + dist/ubuntu-examples windows_build: timeout-minutes: 10 @@ -77,8 +90,7 @@ jobs: - name: Build run: | - xmake config -y -v --ci-env=y - xmake build headers + xmake config -y -v -k shared --ci-env=y xmake -w - name: Run PandaGL tests @@ -97,14 +109,28 @@ jobs: - name: Package run: | - xmake -v xmake package + xmake install -o dist/windows + + - name: Package exmaples + run: | + cd examples + xmake -P . -v + xmake install -P . -o ../dist/windows-examples + mv ../dist/windows-examples/bin/* ../dist/windows-examples/ + rm ../dist/windows-examples/bin + + - uses: actions/upload-artifact@master + with: + name: windows-dist + path: | + dist/windows - uses: actions/upload-artifact@master with: - name: ubuntu-pacakges + name: windows-examples path: | - build/packages + dist/windows-examples release: if: startsWith(github.ref, 'refs/tags/v') diff --git a/.gitignore b/.gitignore index d3870618c..64d952065 100644 --- a/.gitignore +++ b/.gitignore @@ -71,3 +71,4 @@ test/build lcpkg/* !lcpkg/ports vsxmake* +compile_commands.json \ No newline at end of file diff --git a/.vscode/c_cpp_properties.json b/.vscode/c_cpp_properties.json deleted file mode 100644 index 64c5def1b..000000000 --- a/.vscode/c_cpp_properties.json +++ /dev/null @@ -1,26 +0,0 @@ -{ - "configurations": [ - { - "name": "Linux", - "includePath": [ - "/usr/include/x86_64-linux-gnu", - "/usr/include/linux", - "/usr/local/include", - "${workspaceFolder}/**/include/" - ], - "browse": { - "path": [ - "${workspaceRoot}", - "${workspaceRoot}/include", - "/usr/include/x86_64-linux-gnu", - "/usr/include/linux", - "/usr/local/include" - ] - }, - "cStandard": "c11", - "cppStandard": "c++17", - "compileCommands": "${workspaceFolder}/compile_commands.json" - } - ], - "version": 4 -} \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json deleted file mode 100644 index c189806de..000000000 --- a/.vscode/settings.json +++ /dev/null @@ -1,31 +0,0 @@ -{ - "editor.rulers": [ - 78, - 80 - ], - "files.exclude": { - "**/*.lo": true, - "**/*.o": true, - "**/*.gcno": true - }, - "[c]": { - "editor.tabSize": 8, - "editor.insertSpaces": false - }, - "[cpp]": { - "editor.tabSize": 8, - "editor.insertSpaces": false - }, - "[javascript]": { - "editor.tabSize": 2, - "editor.insertSpaces": true - }, - "[xml]": { - "editor.tabSize": 2, - "editor.insertSpaces": true - }, - "[css]": { - "editor.tabSize": 2, - "editor.insertSpaces": true - } -} \ No newline at end of file diff --git a/examples/hello/app/style.css b/examples/hello/app/hello.css similarity index 100% rename from examples/hello/app/style.css rename to examples/hello/app/hello.css diff --git a/examples/hello/app/main.xml b/examples/hello/app/hello.xml similarity index 90% rename from examples/hello/app/main.xml rename to examples/hello/app/hello.xml index 05983f04c..838a056cb 100644 --- a/examples/hello/app/main.xml +++ b/examples/hello/app/hello.xml @@ -1,6 +1,6 @@ - + [i][color=#f00]Hello[/color][/i], [b][color=#fff][bgcolor=#f00]World![/bgcolor][/color][/b] diff --git a/examples/hello/src/main.c b/examples/hello/src/main.c index 7031243ab..950b07ef8 100644 --- a/examples/hello/src/main.c +++ b/examples/hello/src/main.c @@ -1,8 +1,8 @@ #include #include -#include #include #include +#include static void on_btn_click(ui_widget_t* self, ui_event_t* e, void *arg) { @@ -19,7 +19,7 @@ int main(int argc, char **argv) ui_widget_t *pack, *btn; lcui_init(); - pack = ui_load_xml_file("main.xml"); + pack = ui_load_xml_file("hello.xml"); if (!pack) { return -1; } diff --git a/examples/hello/xmake.lua b/examples/hello/xmake.lua index 588740195..f5bb3ab21 100644 --- a/examples/hello/xmake.lua +++ b/examples/hello/xmake.lua @@ -1,6 +1,6 @@ target("hello") - set_default(false) + add_installfiles("app/*") set_kind("binary") set_rundir("app") - add_deps("lcui") + add_packages("lcui") add_files("src/*.c") diff --git a/examples/xmake.lua b/examples/xmake.lua new file mode 100644 index 000000000..a27974be8 --- /dev/null +++ b/examples/xmake.lua @@ -0,0 +1,6 @@ +add_repositories("lcui-repo ../build") +add_requires("lcui") +if is_plat("windows") then + add_rules("win.sdk.application") +end +includes("*/xmake.lua") diff --git a/include/LCUI.h b/include/LCUI.h index 52d31b6d1..d68cfaf2f 100644 --- a/include/LCUI.h +++ b/include/LCUI.h @@ -5,7 +5,8 @@ #include #include #include -#include +#include #include -#include +#include +#include #include diff --git a/include/LCUI/app.h b/include/LCUI/app.h index 222562fa1..475a6c7e9 100644 --- a/include/LCUI/app.h +++ b/include/LCUI/app.h @@ -1,9 +1,9 @@ -#ifndef LCUI_H -#define LCUI_H +#ifndef LCUI_INCLUDE_LCUI_APP_H +#define LCUI_INCLUDE_LCUI_APP_H -#include +#include "common.h" #include -#include +#include #define LCUI_MAX_FRAMES_PER_SEC 120 #define LCUI_MAX_FRAME_MSEC ((int)(1000.0 / LCUI_MAX_FRAMES_PER_SEC + 0.5)) @@ -13,11 +13,11 @@ LCUI_BEGIN_HEADER // Settings typedef struct lcui_settings_t { - int frame_rate_cap; - int parallel_rendering_threads; - LCUI_BOOL record_profile; - LCUI_BOOL fps_meter; - LCUI_BOOL paint_flashing; + int frame_rate_cap; + int parallel_rendering_threads; + bool record_profile; + bool fps_meter; + bool paint_flashing; } lcui_settings_t; /* Initialize settings with the current global settings. */ @@ -29,26 +29,13 @@ LCUI_API void lcui_apply_settings(lcui_settings_t *settings); /* Reset global settings to their defaults. */ LCUI_API void lcui_reset_settings(void); -// Timers - -LCUI_API int lcui_destroy_timer(int timer_id); -LCUI_API int lcui_pause_timer(int timer_id); -LCUI_API int lcui_continue_timer(int timer_id); -LCUI_API int lcui_reset_timer(int timer_id, long int n_ms); -LCUI_API int lcui_set_timeout(long int n_ms, void (*callback)(void *), - void *arg); -LCUI_API int lcui_set_interval(long int n_ms, void (*callback)(void *), - void *arg); - // Tasks -typedef void (*LCUI_AppTaskFunc)(void *, void *); - /** * 添加任务 * 该任务将会添加至主线程中执行 */ -LCUI_API LCUI_BOOL lcui_post_task(LCUI_Task task); +LCUI_API bool lcui_post_task(worker_task_t *task); /** * 添加异步任务 @@ -56,25 +43,18 @@ LCUI_API LCUI_BOOL lcui_post_task(LCUI_Task task); * @param[in] task 任务数据 * @param[in] target_worker_id 目标工作线程的编号 */ -LCUI_API void lcui_post_async_task(LCUI_Task task, int target_worker_id); - -/** lcui_post_task 的简化版本 */ -#define lcui_post_simple_task(FUNC, ARG1, ARG2) \ - do { \ - LCUI_TaskRec _ui_task = { 0 }; \ - _ui_task.arg[0] = (void *)ARG1; \ - _ui_task.arg[1] = (void *)ARG2; \ - _ui_task.func = (LCUI_AppTaskFunc)(FUNC); \ - lcui_post_task(&_ui_task); \ - } while (0); +LCUI_API void lcui_post_async_task(worker_task_t *task, int target_worker_id); + +LCUI_API bool lcui_post_simple_task(worker_callback_t callback, void *arg1, + void *arg2); // UI typedef enum lcui_display_mode_t { - LCUI_DISPLAY_MODE_DEFAULT, - LCUI_DISPLAY_MODE_WINDOWED, - LCUI_DISPLAY_MODE_FULLSCREEN, - LCUI_DISPLAY_MODE_SEAMLESS, + LCUI_DISPLAY_MODE_DEFAULT, + LCUI_DISPLAY_MODE_WINDOWED, + LCUI_DISPLAY_MODE_FULLSCREEN, + LCUI_DISPLAY_MODE_SEAMLESS, } lcui_display_mode_t; LCUI_API void lcui_init_ui(void); @@ -93,7 +73,7 @@ LCUI_API int lcui_process_events(app_process_events_option_t option); INLINE int lcui_process_all_events(void) { - return lcui_process_events(APP_PROCESS_EVENTS_ALL_IF_PRESENT); + return lcui_process_events(APP_PROCESS_EVENTS_ALL_IF_PRESENT); } // Base diff --git a/include/LCUI/common.h b/include/LCUI/common.h new file mode 100644 index 000000000..c0cea24ca --- /dev/null +++ b/include/LCUI/common.h @@ -0,0 +1,67 @@ + +#ifndef LCUI_INCLUDE_LCUI_COMMON_H +#define LCUI_INCLUDE_LCUI_COMMON_H + +#include "config.h" + +#ifndef LCUI_API +#if defined(_MSC_VER) && !defined(LCUI_STATIC_BUILD) +#ifdef LCUI_DLL_EXPORT +#define LCUI_API __declspec(dllexport) +#else +#define LCUI_API __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LCUI_API extern __attribute__((visibility("default"))) +#else +#define LCUI_API extern +#endif +#endif + +#if defined(_WIN32) && !defined(__cplusplus) +#define INLINE __inline +#else +#define INLINE static inline +#endif + +#ifdef _WIN32 +#define LIBPLAT_WIN32 +#if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) +#define LIBPLAT_UWP +#else +#define LIBPLAT_WIN_DESKTOP +#endif +#else +#define LIBPLAT_LINUX +#endif + +#ifdef __cplusplus +#define LCUI_BEGIN_HEADER extern "C" { +#define LCUI_END_HEADER } +#else +#define LCUI_BEGIN_HEADER /* nothing */ +#define LCUI_END_HEADER +#endif + +#ifdef DEBUG +#define DEBUG_MSG _DEBUG_MSG +#else +#define DEBUG_MSG(format, ...) +#endif + +#define _DEBUG_MSG(format, ...) \ + logger_log(LOGGER_LEVEL_DEBUG, __FILE__ ":%d: %s(): " format, \ + __LINE__, __FUNCTION__, ##__VA_ARGS__) + +#ifndef FALSE +#define FALSE 0 +#endif + +#ifndef TRUE +#define TRUE 1 +#endif + +typedef unsigned char LCUI_BOOL; +typedef unsigned char uchar_t; + +#endif diff --git a/include/LCUI/def.h b/include/LCUI/def.h deleted file mode 100644 index 74c7ea7af..000000000 --- a/include/LCUI/def.h +++ /dev/null @@ -1,65 +0,0 @@ - -#ifndef LCUI_DEF_INCLUDE_LCUI_DEF_H -#define LCUI_DEF_INCLUDE_LCUI_DEF_H - -#if defined(__GNUC__) - #define LCUI_API extern __attribute__((visibility("default"))) -#else - #if LCUI_DLL - #ifdef LCUI_EXPORTS - #define LCUI_API __declspec(dllexport) - #else - #define LCUI_API __declspec(dllimport) - #endif - #else - #define LCUI_API extern - #endif -#endif - -#if defined(_WIN32) && !defined(__cplusplus) - #define INLINE __inline -#else - #define INLINE static inline -#endif - -#ifdef _WIN32 - #define LIBPLAT_WIN32 - #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) - #define LIBPLAT_UWP - #else - #define LIBPLAT_WIN_DESKTOP - #endif -#else - #define LIBPLAT_LINUX -#endif - -#ifdef __cplusplus -#define LCUI_BEGIN_HEADER extern "C" { -#define LCUI_END_HEADER } -#else -#define LCUI_BEGIN_HEADER /* nothing */ -#define LCUI_END_HEADER -#endif - -#ifdef DEBUG -#define DEBUG_MSG _DEBUG_MSG -#else -#define DEBUG_MSG(format, ...) -#endif - -#define _DEBUG_MSG(format, ...) \ - logger_log(LOGGER_LEVEL_DEBUG, __FILE__ ":%d: %s(): " format, \ - __LINE__, __FUNCTION__, ##__VA_ARGS__) - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -typedef unsigned char LCUI_BOOL; -typedef unsigned char uchar_t; - -#endif diff --git a/include/LCUI/thread.h b/include/LCUI/thread.h deleted file mode 100644 index 16f0a098c..000000000 --- a/include/LCUI/thread.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * thread.h -- basic thread management - * - * Copyright (c) 2018-2022, Liu chao All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of LCUI nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LCUI_THREAD_H -#define LCUI_THREAD_H - -#include - -typedef unsigned long thread_t; -typedef union thread_mutex_record_t *thread_mutex_t; -typedef union thread_cond_record_t *thread_cond_t; - -LCUI_BEGIN_HEADER - -LCUI_API int thread_mutex_init(thread_mutex_t *mutex); -LCUI_API void thread_mutex_destroy(thread_mutex_t *mutex); -LCUI_API int thread_mutex_trylock(thread_mutex_t *mutex); -LCUI_API int thread_mutex_lock(thread_mutex_t *mutex); -LCUI_API int thread_mutex_unlock(thread_mutex_t *mutex); - -LCUI_API int thread_cond_init(thread_cond_t *cond); -LCUI_API int thread_cond_destroy(thread_cond_t *cond); -LCUI_API int thread_cond_wait(thread_cond_t *cond, thread_mutex_t *mutex); -LCUI_API int thread_cond_timedwait(thread_cond_t *cond, thread_mutex_t *mutex, - unsigned int ms); -LCUI_API int thread_cond_signal(thread_cond_t *cond); -LCUI_API int thread_cond_broadcast(thread_cond_t *cond); - -LCUI_API thread_t thread_self(void); -LCUI_API int thread_create(thread_t *tidp, void (*start_rtn)(void *), - void *arg); -LCUI_API int thread_join(thread_t thread, void **retval); -LCUI_API void thread_cancel(thread_t thread); -LCUI_API void thread_exit(void *retval); - -LCUI_END_HEADER - -#endif diff --git a/include/LCUI/timer.h b/include/LCUI/timer.h deleted file mode 100644 index 3292c4623..000000000 --- a/include/LCUI/timer.h +++ /dev/null @@ -1,22 +0,0 @@ - -#ifndef LCUI_TIMER_H -#define LCUI_TIMER_H - -#include -#include - -LCUI_BEGIN_HEADER - -LCUI_API int lcui_destroy_timer(int timer_id); -LCUI_API int lcui_pause_timer(int timer_id); -LCUI_API int lcui_continue_timer(int timer_id); -LCUI_API int lcui_reset_timer(int timer_id, long int n_ms); -LCUI_API int lcui_set_timeout(long int n_ms, void (*callback)(void *), void *arg); -LCUI_API int lcui_set_interval(long int n_ms, void (*callback)(void *), void *arg); -LCUI_API size_t lcui_process_timers(void); -LCUI_API void lcui_init_timers(void); -LCUI_API void lcui_destroy_timers(void); - -LCUI_END_HEADER - -#endif diff --git a/include/LCUI/worker.h b/include/LCUI/worker.h deleted file mode 100644 index f683e8237..000000000 --- a/include/LCUI/worker.h +++ /dev/null @@ -1,60 +0,0 @@ -/* - * worker.h -- worker threading and task - * - * Copyright (c) 2018, Liu chao All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of LCUI nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#ifndef LCUI_WORKER_H -#define LCUI_WORKER_H - -LCUI_BEGIN_HEADER - -typedef void(*LCUI_TaskFunc)(void*, void*); - -typedef struct LCUI_TaskRec_ { - LCUI_TaskFunc func; /**< 任务处理函数 */ - void *arg[2]; /**< 两个参数 */ - void(*destroy_arg[2])(void*); /**< 参数的销毁函数 */ -} LCUI_TaskRec, *LCUI_Task; - -typedef struct LCUI_WorkerRec_ *LCUI_Worker; - -LCUI_API LCUI_Worker LCUIWorker_New(void); - -LCUI_API void LCUIWorker_setFrameRateCap(LCUI_Worker worker, unsigned rate_cap); - -LCUI_API void LCUIWorker_PostTask(LCUI_Worker worker, LCUI_Task task); - -LCUI_API LCUI_BOOL LCUIWorker_RunTask(LCUI_Worker worker); - -LCUI_API int LCUIWorker_RunAsync(LCUI_Worker worker); - -LCUI_API void LCUIWorker_Destroy(LCUI_Worker worker); - -LCUI_END_HEADER - -#endif diff --git a/lib/css/include/css/computed.h b/lib/css/include/css/computed.h index c853ec0a3..75109855c 100644 --- a/lib/css/include/css/computed.h +++ b/lib/css/include/css/computed.h @@ -10,163 +10,168 @@ LIBCSS_BEGIN_DECLS #define IS_CSS_LENGTH(S, PROP_KEY) (S)->type_bits.PROP_KEY == CSS_LENGTH_SET #define IS_CSS_FIXED_LENGTH(S, PROP_KEY) \ - ((S)->type_bits.PROP_KEY == CSS_LENGTH_SET && \ - (S)->unit_bits.PROP_KEY == CSS_UNIT_PX) + ((S)->type_bits.PROP_KEY == CSS_LENGTH_SET && \ + (S)->unit_bits.PROP_KEY == CSS_UNIT_PX) #define IS_CSS_PERCENTAGE(S, PROP_KEY) \ - ((S)->type_bits.PROP_KEY == CSS_LENGTH_SET && \ - (S)->unit_bits.PROP_KEY == CSS_UNIT_PERCENT) + ((S)->type_bits.PROP_KEY == CSS_LENGTH_SET && \ + (S)->unit_bits.PROP_KEY == CSS_UNIT_PERCENT) #define CSS_SET_FIXED_LENGTH(S, PROP_KEY, PROP_VALUE) \ - do { \ - (S)->PROP_KEY = PROP_VALUE; \ - (S)->type_bits.PROP_KEY = CSS_LENGTH_SET; \ - (S)->unit_bits.PROP_KEY = CSS_UNIT_PX; \ - } while (0); + do { \ + (S)->PROP_KEY = PROP_VALUE; \ + (S)->type_bits.PROP_KEY = CSS_LENGTH_SET; \ + (S)->unit_bits.PROP_KEY = CSS_UNIT_PX; \ + } while (0); #define CSS_COPY_LENGTH(SRC, DEST, PROP_KEY) \ - do { \ - (SRC)->PROP_KEY = (DEST)->PROP_KEY; \ - (SRC)->type_bits.PROP_KEY = (DEST)->type_bits.PROP_KEY; \ - (SRC)->unit_bits.PROP_KEY = (DEST)->unit_bits.PROP_KEY; \ - } while (0); + do { \ + (SRC)->PROP_KEY = (DEST)->PROP_KEY; \ + (SRC)->type_bits.PROP_KEY = (DEST)->type_bits.PROP_KEY; \ + (SRC)->unit_bits.PROP_KEY = (DEST)->unit_bits.PROP_KEY; \ + } while (0); LIBCSS_INLINE libcss_bool_t is_css_display_inline(uint8_t display) { - return display == CSS_DISPLAY_INLINE || - display == CSS_DISPLAY_INLINE_BLOCK || - display == CSS_DISPLAY_INLINE_FLEX; + return display == CSS_DISPLAY_INLINE || + display == CSS_DISPLAY_INLINE_BLOCK || + display == CSS_DISPLAY_INLINE_FLEX; } LIBCSS_INLINE css_numeric_value_t css_padding_x(const css_computed_style_t *s) { - return s->padding_left + s->padding_right; + return s->padding_left + s->padding_right; } LIBCSS_INLINE css_numeric_value_t css_padding_y(const css_computed_style_t *s) { - return s->padding_top + s->padding_bottom; + return s->padding_top + s->padding_bottom; } LIBCSS_INLINE css_numeric_value_t css_margin_x(const css_computed_style_t *s) { - return s->margin_left + s->margin_right; + return s->margin_left + s->margin_right; } LIBCSS_INLINE css_numeric_value_t css_margin_y(const css_computed_style_t *s) { - return s->margin_top + s->margin_bottom; + return s->margin_top + s->margin_bottom; } LIBCSS_INLINE css_numeric_value_t css_border_x(const css_computed_style_t *s) { - return s->border_left_width + s->border_right_width; + return s->border_left_width + s->border_right_width; } LIBCSS_INLINE css_numeric_value_t css_border_y(const css_computed_style_t *s) { - return s->border_top_width + s->border_bottom_width; + return s->border_top_width + s->border_bottom_width; } LIBCSS_PUBLIC uint8_t css_computed_padding_top(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_padding_right(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_padding_bottom(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_padding_left(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_margin_top(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_margin_right(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_margin_bottom(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_margin_left(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_top(const css_computed_style_t *s, - css_numeric_value_t *value, css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_right(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_bottom(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_left(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_display(const css_computed_style_t *s); -LIBCSS_PUBLIC uint8_t css_computed_vertical_align(const css_computed_style_t *s); +LIBCSS_PUBLIC uint8_t +css_computed_vertical_align(const css_computed_style_t *s); LIBCSS_PUBLIC uint8_t css_computed_box_sizing(const css_computed_style_t *s); LIBCSS_PUBLIC uint8_t css_computed_position(const css_computed_style_t *s); LIBCSS_PUBLIC uint8_t css_computed_min_width(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_min_height(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_max_width(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_max_height(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_width(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_height(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); -LIBCSS_PUBLIC uint8_t css_computed_border_top_style(const css_computed_style_t *s); +LIBCSS_PUBLIC uint8_t +css_computed_border_top_style(const css_computed_style_t *s); -LIBCSS_PUBLIC uint8_t css_computed_border_right_style(const css_computed_style_t *s); +LIBCSS_PUBLIC uint8_t +css_computed_border_right_style(const css_computed_style_t *s); LIBCSS_PUBLIC uint8_t css_computed_border_bottom_style(const css_computed_style_t *s); -LIBCSS_PUBLIC uint8_t css_computed_border_left_style(const css_computed_style_t *s); +LIBCSS_PUBLIC uint8_t +css_computed_border_left_style(const css_computed_style_t *s); -LIBCSS_PUBLIC uint8_t css_computed_border_top_color(const css_computed_style_t *s, - css_color_value_t *value); +LIBCSS_PUBLIC uint8_t css_computed_border_top_color( + const css_computed_style_t *s, css_color_value_t *value); -LIBCSS_PUBLIC uint8_t css_computed_border_right_color(const css_computed_style_t *s, - css_color_value_t *value); +LIBCSS_PUBLIC uint8_t css_computed_border_right_color( + const css_computed_style_t *s, css_color_value_t *value); -LIBCSS_PUBLIC uint8_t css_computed_border_bottom_color(const css_computed_style_t *s, - css_color_value_t *value); +LIBCSS_PUBLIC uint8_t css_computed_border_bottom_color( + const css_computed_style_t *s, css_color_value_t *value); -LIBCSS_PUBLIC uint8_t css_computed_border_left_color(const css_computed_style_t *s, - css_color_value_t *value); +LIBCSS_PUBLIC uint8_t css_computed_border_left_color( + const css_computed_style_t *s, css_color_value_t *value); LIBCSS_PUBLIC uint8_t css_computed_background_position_x( const css_computed_style_t *s, css_numeric_value_t *value, @@ -176,81 +181,81 @@ LIBCSS_PUBLIC uint8_t css_computed_background_position_y( const css_computed_style_t *s, css_numeric_value_t *value, css_unit_t *unit); -LIBCSS_PUBLIC uint8_t css_computed_background_width(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); +LIBCSS_PUBLIC uint8_t +css_computed_background_width(const css_computed_style_t *s, + css_numeric_value_t *value, css_unit_t *unit); -LIBCSS_PUBLIC uint8_t css_computed_background_height(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); +LIBCSS_PUBLIC uint8_t +css_computed_background_height(const css_computed_style_t *s, + css_numeric_value_t *value, css_unit_t *unit); -LIBCSS_PUBLIC uint8_t css_computed_background_image(const css_computed_style_t *s, - css_image_value_t *value); +LIBCSS_PUBLIC uint8_t css_computed_background_image( + const css_computed_style_t *s, css_image_value_t *value); LIBCSS_PUBLIC uint8_t css_computed_box_shadow_x(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); LIBCSS_PUBLIC uint8_t css_computed_box_shadow_y(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); + css_numeric_value_t *value, + css_unit_t *unit); -LIBCSS_PUBLIC uint8_t css_computed_box_shadow_blur(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); +LIBCSS_PUBLIC uint8_t +css_computed_box_shadow_blur(const css_computed_style_t *s, + css_numeric_value_t *value, css_unit_t *unit); -LIBCSS_PUBLIC uint8_t css_computed_box_shadow_spread(const css_computed_style_t *s, - css_numeric_value_t *value, - css_unit_t *unit); +LIBCSS_PUBLIC uint8_t +css_computed_box_shadow_spread(const css_computed_style_t *s, + css_numeric_value_t *value, css_unit_t *unit); -LIBCSS_PUBLIC uint8_t css_computed_box_shadow_color(const css_computed_style_t *s, - css_color_value_t *value); +LIBCSS_PUBLIC uint8_t css_computed_box_shadow_color( + const css_computed_style_t *s, css_color_value_t *value); LIBCSS_PUBLIC uint8_t css_computed_visibility(const css_computed_style_t *s); LIBCSS_PUBLIC void css_computed_style_destroy(css_computed_style_t *s); LIBCSS_PUBLIC int css_cascade_style(const css_style_decl_t *style, - css_computed_style_t *computed); + css_computed_style_t *computed); -LIBCSS_PUBLIC void css_compute_absolute_values(const css_computed_style_t *parent, - css_computed_style_t *s, - css_metrics_t *m); +LIBCSS_PUBLIC void css_compute_absolute_values( + const css_computed_style_t *parent, css_computed_style_t *s, + css_metrics_t *m); LIBCSS_INLINE css_numeric_value_t css_convert_content_box_width( css_computed_style_t *s, css_numeric_value_t content_width) { - if (css_computed_box_sizing(s) == CSS_BOX_SIZING_BORDER_BOX) { - return content_width + css_border_x(s) + css_padding_x(s); - } - return content_width; + if (css_computed_box_sizing(s) == CSS_BOX_SIZING_BORDER_BOX) { + return content_width + css_border_x(s) + css_padding_x(s); + } + return content_width; } LIBCSS_INLINE css_numeric_value_t css_convert_content_box_height( css_computed_style_t *s, css_numeric_value_t content_height) { - if (css_computed_box_sizing(s) == CSS_BOX_SIZING_BORDER_BOX) { - return content_height + css_border_y(s) + css_padding_y(s); - } - return content_height; + if (css_computed_box_sizing(s) == CSS_BOX_SIZING_BORDER_BOX) { + return content_height + css_border_y(s) + css_padding_y(s); + } + return content_height; } LIBCSS_INLINE css_numeric_value_t css_convert_border_box_width( css_computed_style_t *s, css_numeric_value_t border_width) { - if (css_computed_box_sizing(s) == CSS_BOX_SIZING_CONTENT_BOX) { - return border_width - css_border_x(s) - css_padding_x(s); - } - return border_width; + if (css_computed_box_sizing(s) == CSS_BOX_SIZING_CONTENT_BOX) { + return border_width - css_border_x(s) - css_padding_x(s); + } + return border_width; } LIBCSS_INLINE css_numeric_value_t css_convert_border_box_height( css_computed_style_t *s, css_numeric_value_t border_height) { - if (css_computed_box_sizing(s) == CSS_BOX_SIZING_CONTENT_BOX) { - return border_height - css_border_y(s) - css_padding_y(s); - } - return border_height; + if (css_computed_box_sizing(s) == CSS_BOX_SIZING_CONTENT_BOX) { + return border_height - css_border_y(s) - css_padding_y(s); + } + return border_height; } LIBCSS_END_DECLS diff --git a/lib/css/include/css/types.h b/lib/css/include/css/types.h index 28667f06e..45eacc1f3 100644 --- a/lib/css/include/css/types.h +++ b/lib/css/include/css/types.h @@ -591,17 +591,10 @@ struct css_style_value_t { }; }; -struct css_style_t { - css_style_value_t *list; - unsigned length; -}; - typedef struct css_valdef_t css_valdef_t; -typedef struct css_style_t css_style_t; typedef list_t css_style_decl_t; typedef css_style_decl_t css_style_decl_t; -typedef css_style_t css_style_t; typedef unsigned css_selector_hash_t; /** 样式规则记录 */ diff --git a/lib/css/include/css/value.h b/lib/css/include/css/value.h index b88cc1143..f77a096dd 100644 --- a/lib/css/include/css/value.h +++ b/lib/css/include/css/value.h @@ -6,7 +6,7 @@ LIBCSS_BEGIN_DECLS -void css_valdef_destroy(css_valdef_t *valdef); +LIBCSS_PUBLIC void css_valdef_destroy(css_valdef_t *valdef); LIBCSS_PUBLIC void css_init_value_definitons(void); diff --git a/lib/css/src/library.c b/lib/css/src/library.c index 5d6153e1d..8ba7a2be6 100644 --- a/lib/css/src/library.c +++ b/lib/css/src/library.c @@ -47,547 +47,549 @@ typedef dict_t css_style_group_t; /** 样式链接记录组 */ typedef struct css_style_link_group_t { - dict_t *links; /**< 样式链接表 */ - char *name; /**< 选择器名称 */ - css_selector_node_t *snode; /**< 选择器结点 */ + dict_t *links; /**< 样式链接表 */ + char *name; /**< 选择器名称 */ + css_selector_node_t *snode; /**< 选择器结点 */ } css_style_link_group_t; /** 样式链接记录 */ typedef struct css_style_link_t { - char *selector; /**< 选择器 */ - css_style_link_group_t *group; /**< 所属组 */ - - /** - * 作用于当前选择器的样式 - * list_t - */ - list_t styles; - - /** - * 父级节点 - * dict_t - */ - dict_t *parents; + char *selector; /**< 选择器 */ + css_style_link_group_t *group; /**< 所属组 */ + + /** + * 作用于当前选择器的样式 + * list_t + */ + list_t styles; + + /** + * 父级节点 + * dict_t + */ + dict_t *parents; } css_style_link_t; static struct css_library_module_t { - /** - * 样式组列表 - * list_t - */ - list_t groups; + /** + * 样式组列表 + * list_t + */ + list_t groups; - /** 字符串池 */ - strpool_t *strpool; + /** 字符串池 */ + strpool_t *strpool; - /** - * 样式表缓存,以选择器的 hash 值索引 - * dict_t - */ - dict_t *cache; + /** + * 样式表缓存,以选择器的 hash 值索引 + * dict_t + */ + dict_t *cache; } css_library; static uint64_t ikey_dict_hash(const void *key) { - return (*(unsigned int *)key); + return (*(unsigned int *)key); } static int ikey_dict_key_compare(void *privdata, const void *key1, - const void *key2) + const void *key2) { - return *(unsigned int *)key1 == *(unsigned int *)key2; + return *(unsigned int *)key1 == *(unsigned int *)key2; } static void ikey_dict_key_destructor(void *privdata, void *key) { - free(key); + free(key); } static void *ikey_dict_key_dup(void *privdata, const void *key) { - unsigned int *newkey = malloc(sizeof(unsigned int)); - *newkey = *(unsigned int *)key; - return newkey; + unsigned int *newkey = malloc(sizeof(unsigned int)); + *newkey = *(unsigned int *)key; + return newkey; } static void css_style_cache_destructor(void *privdata, void *val) { - css_style_decl_destroy(val); + css_style_decl_destroy(val); } libcss_bool_t css_selector_node_match(css_selector_node_t *sn1, - css_selector_node_t *sn2) + css_selector_node_t *sn2) { - int i, j; - if (sn2->id) { - if (!sn1->id || strcmp(sn1->id, sn2->id) != 0) { - return LIBCSS_FALSE; - } - } - if (sn2->type && strcmp(sn2->type, "*") != 0) { - if (!sn1->type || strcmp(sn1->type, sn2->type) != 0) { - return LIBCSS_FALSE; - } - } - if (sn2->classes) { - if (!sn1->classes) { - return LIBCSS_FALSE; - } - for (i = 0; sn2->classes[i]; ++i) { - for (j = 0; sn1->classes[j]; ++j) { - if (strcmp(sn2->classes[i], sn1->classes[i]) == - 0) { - j = -1; - break; - } - } - if (j != -1) { - return LIBCSS_FALSE; - } - } - } - if (sn2->status) { - if (!sn1->status) { - return LIBCSS_FALSE; - } - for (i = 0; sn2->status[i]; ++i) { - for (j = 0; sn1->status[j]; ++j) { - if (strcmp(sn2->status[i], sn1->status[i]) == - 0) { - j = -1; - break; - } - } - if (j != -1) { - return LIBCSS_FALSE; - } - } - } - return LIBCSS_TRUE; + int i, j; + if (sn2->id) { + if (!sn1->id || strcmp(sn1->id, sn2->id) != 0) { + return LIBCSS_FALSE; + } + } + if (sn2->type && strcmp(sn2->type, "*") != 0) { + if (!sn1->type || strcmp(sn1->type, sn2->type) != 0) { + return LIBCSS_FALSE; + } + } + if (sn2->classes) { + if (!sn1->classes) { + return LIBCSS_FALSE; + } + for (i = 0; sn2->classes[i]; ++i) { + for (j = 0; sn1->classes[j]; ++j) { + if (strcmp(sn2->classes[i], sn1->classes[i]) == + 0) { + j = -1; + break; + } + } + if (j != -1) { + return LIBCSS_FALSE; + } + } + } + if (sn2->status) { + if (!sn1->status) { + return LIBCSS_FALSE; + } + for (i = 0; sn2->status[i]; ++i) { + for (j = 0; sn1->status[j]; ++j) { + if (strcmp(sn2->status[i], sn1->status[i]) == + 0) { + j = -1; + break; + } + } + if (j != -1) { + return LIBCSS_FALSE; + } + } + } + return LIBCSS_TRUE; } static void css_style_rule_destroy(css_style_rule_t *node) { - if (node->space) { - strpool_free_str(node->space); - node->space = NULL; - } - if (node->selector) { - free(node->selector); - node->selector = NULL; - } - css_style_decl_destroy(node->list); - node->list = NULL; - free(node); + if (node->space) { + strpool_free_str(node->space); + node->space = NULL; + } + if (node->selector) { + free(node->selector); + node->selector = NULL; + } + css_style_decl_destroy(node->list); + node->list = NULL; + free(node); } static css_style_link_t *css_style_link_create(void) { - css_style_link_t *link = calloc(sizeof(css_style_link_t), 1); - static dict_type_t t; - - dict_init_string_copy_key_type(&t); - link->group = NULL; - list_create(&link->styles); - link->parents = dict_create(&t, NULL); - return link; + css_style_link_t *link = calloc(sizeof(css_style_link_t), 1); + static dict_type_t t; + + dict_init_string_copy_key_type(&t); + link->group = NULL; + list_create(&link->styles); + link->parents = dict_create(&t, NULL); + return link; } static void css_style_link_destroy(css_style_link_t *link) { - dict_destroy(link->parents); - list_destroy_without_node( - &link->styles, (list_item_destructor_t)css_style_rule_destroy); - free(link->selector); - link->selector = NULL; - link->parents = NULL; - link->group = NULL; - free(link); + dict_destroy(link->parents); + list_destroy_without_node( + &link->styles, (list_item_destructor_t)css_style_rule_destroy); + free(link->selector); + link->selector = NULL; + link->parents = NULL; + link->group = NULL; + free(link); } static void css_style_link_destructor(void *privdata, void *data) { - css_style_link_destroy(data); + css_style_link_destroy(data); } static css_style_link_group_t *css_style_link_group_create( css_selector_node_t *snode) { - static dict_type_t dt = { 0 }; - css_style_link_group_t *group; - - dict_init_string_copy_key_type(&dt); - dt.val_destructor = css_style_link_destructor; - group = calloc(sizeof(css_style_link_group_t), 1); - group->snode = css_selector_node_duplicate(snode); - group->links = dict_create(&dt, NULL); - group->name = group->snode->fullname; - return group; + static dict_type_t dt = { 0 }; + css_style_link_group_t *group; + + dict_init_string_copy_key_type(&dt); + dt.val_destructor = css_style_link_destructor; + group = calloc(sizeof(css_style_link_group_t), 1); + group->snode = css_selector_node_duplicate(snode); + group->links = dict_create(&dt, NULL); + group->name = group->snode->fullname; + return group; } static void css_style_link_group_destroy(css_style_link_group_t *group) { - dict_type_t *dtype; - dtype = group->links->priv_data; - css_selector_node_destroy(group->snode); - dict_destroy(group->links); - free(dtype); - free(group); + dict_type_t *dtype; + dtype = group->links->priv_data; + css_selector_node_destroy(group->snode); + dict_destroy(group->links); + free(dtype); + free(group); } static void css_style_link_group_destructor(void *privdata, void *data) { - css_style_link_group_destroy(data); + css_style_link_group_destroy(data); } static css_style_group_t *css_style_group_create(void) { - static dict_type_t type = { 0 }; + static dict_type_t type = { 0 }; - dict_init_string_copy_key_type(&type); - type.val_destructor = css_style_link_group_destructor; - return dict_create(&type, NULL); + dict_init_string_copy_key_type(&type); + type.val_destructor = css_style_link_group_destructor; + return dict_create(&type, NULL); } /** 根据选择器查找匹配的样式存储空间 */ static css_style_decl_t *css_find_style_store(css_selector_t *selector, - const char *space) + const char *space) { - int i, right; - css_style_link_t *link; - css_style_rule_t *snode; - css_style_link_group_t *slg; - css_selector_node_t *sn; - css_style_group_t *group; - dict_t *parents; - - char buf[CSS_SELECTOR_MAX_LEN]; - char fullname[CSS_SELECTOR_MAX_LEN]; - - link = NULL; - parents = NULL; - for (i = 0, right = selector->length - 1; right >= 0; --right, ++i) { - group = list_get(&css_library.groups, i); - if (!group) { - group = css_style_group_create(); - list_append(&css_library.groups, group); - } - sn = selector->nodes[right]; - slg = dict_fetch_value(group, sn->fullname); - if (!slg) { - slg = css_style_link_group_create(sn); - dict_add(group, sn->fullname, slg); - } - if (i == 0) { - strcpy(fullname, "*"); - } else { - strcpy(fullname, buf); - } - link = dict_fetch_value(slg->links, fullname); - if (!link) { - link = css_style_link_create(); - link->group = slg; - link->selector = strdup2(fullname); - dict_add(slg->links, fullname, link); - } - if (i == 0) { - strcpy(buf, sn->fullname); - strcpy(fullname, buf); - } else { - strcpy(fullname, buf); - sprintf(buf, "%s %s", sn->fullname, fullname); - } - /* 如果有上一级的父链接记录,则将当前链接添加进去 */ - if (parents) { - if (!dict_fetch_value(parents, sn->fullname)) { - dict_add(parents, sn->fullname, link); - } - } - parents = link->parents; - } - if (!link) { - return NULL; - } - snode = calloc(sizeof(css_style_rule_t), 1); - if (space) { - snode->space = strpool_alloc_str(css_library.strpool, space); - strcpy(snode->space, space); - } else { - snode->space = NULL; - } - snode->node.data = snode; - snode->list = css_style_decl_create(); - snode->rank = selector->rank; - snode->selector = strdup2(fullname); - snode->batch_num = selector->batch_num; - list_append_node(&link->styles, &snode->node); - return snode->list; + int i, right; + css_style_link_t *link; + css_style_rule_t *snode; + css_style_link_group_t *slg; + css_selector_node_t *sn; + css_style_group_t *group; + dict_t *parents; + + char buf[CSS_SELECTOR_MAX_LEN]; + char fullname[CSS_SELECTOR_MAX_LEN]; + + link = NULL; + parents = NULL; + for (i = 0, right = selector->length - 1; right >= 0; --right, ++i) { + group = list_get(&css_library.groups, i); + if (!group) { + group = css_style_group_create(); + list_append(&css_library.groups, group); + } + sn = selector->nodes[right]; + slg = dict_fetch_value(group, sn->fullname); + if (!slg) { + slg = css_style_link_group_create(sn); + dict_add(group, sn->fullname, slg); + } + if (i == 0) { + strcpy(fullname, "*"); + } else { + strcpy(fullname, buf); + } + link = dict_fetch_value(slg->links, fullname); + if (!link) { + link = css_style_link_create(); + link->group = slg; + link->selector = strdup2(fullname); + dict_add(slg->links, fullname, link); + } + if (i == 0) { + strcpy(buf, sn->fullname); + strcpy(fullname, buf); + } else { + strcpy(fullname, buf); + snprintf(buf, CSS_SELECTOR_MAX_LEN, "%s %s", + sn->fullname, fullname); + } + /* 如果有上一级的父链接记录,则将当前链接添加进去 */ + if (parents) { + if (!dict_fetch_value(parents, sn->fullname)) { + dict_add(parents, sn->fullname, link); + } + } + parents = link->parents; + } + if (!link) { + return NULL; + } + snode = calloc(sizeof(css_style_rule_t), 1); + if (space) { + snode->space = strpool_alloc_str(css_library.strpool, space); + strcpy(snode->space, space); + } else { + snode->space = NULL; + } + snode->node.data = snode; + snode->list = css_style_decl_create(); + snode->rank = selector->rank; + snode->selector = strdup2(fullname); + snode->batch_num = selector->batch_num; + list_append_node(&link->styles, &snode->node); + return snode->list; } int css_add_style_decl(css_selector_t *selector, const css_style_decl_t *style, - const char *space) + const char *space) { - css_style_decl_t *list; - - dict_empty(css_library.cache, NULL); - list = css_find_style_store(selector, space); - if (list) { - css_style_decl_merge(list, style); - } - return 0; + css_style_decl_t *list; + + dict_empty(css_library.cache, NULL); + list = css_find_style_store(selector, space); + if (list) { + css_style_decl_merge(list, style); + } + return 0; } static size_t css_style_link_get_styles(css_style_link_t *link, list_t *outlist) { - size_t i; - libcss_bool_t found; - css_style_rule_t *snode, *out_snode; - list_node_t *node, *out_node; - - if (!outlist) { - return link->styles.length; - } - for (list_each(node, &link->styles)) { - i = 0; - found = LIBCSS_FALSE; - snode = node->data; - for (list_each(out_node, outlist)) { - out_snode = out_node->data; - if (snode->rank > out_snode->rank) { - found = LIBCSS_TRUE; - break; - } - if (snode->rank != out_snode->rank) { - i += 1; - continue; - } - if (snode->batch_num > out_snode->batch_num) { - found = LIBCSS_TRUE; - break; - } - i += 1; - } - if (found) { - list_insert(outlist, i, snode); - } else { - list_append(outlist, snode); - } - } - return link->styles.length; + size_t i; + libcss_bool_t found; + css_style_rule_t *snode, *out_snode; + list_node_t *node, *out_node; + + if (!outlist) { + return link->styles.length; + } + for (list_each(node, &link->styles)) { + i = 0; + found = LIBCSS_FALSE; + snode = node->data; + for (list_each(out_node, outlist)) { + out_snode = out_node->data; + if (snode->rank > out_snode->rank) { + found = LIBCSS_TRUE; + break; + } + if (snode->rank != out_snode->rank) { + i += 1; + continue; + } + if (snode->batch_num > out_snode->batch_num) { + found = LIBCSS_TRUE; + break; + } + i += 1; + } + if (found) { + list_insert(outlist, i, snode); + } else { + list_append(outlist, snode); + } + } + return link->styles.length; } static size_t css_query_selector_from_link(css_style_link_t *link, - const css_selector_t *s, int i, - list_t *list) + const css_selector_t *s, int i, + list_t *list) { - size_t count = 0; - css_style_link_t *parent; - list_t names; - list_node_t *node; - css_selector_node_t *sn; - - list_create(&names); - count += css_style_link_get_styles(link, list); - while (--i >= 0) { - sn = s->nodes[i]; - css_selector_node_get_name_list(sn, &names); - for (list_each(node, &names)) { - parent = dict_fetch_value(link->parents, node->data); - if (!parent) { - continue; - } - count += - css_query_selector_from_link(parent, s, i, list); - } - list_destroy(&names, free); - } - return count; + size_t count = 0; + css_style_link_t *parent; + list_t names; + list_node_t *node; + css_selector_node_t *sn; + + list_create(&names); + count += css_style_link_get_styles(link, list); + while (--i >= 0) { + sn = s->nodes[i]; + css_selector_node_get_name_list(sn, &names); + for (list_each(node, &names)) { + parent = dict_fetch_value(link->parents, node->data); + if (!parent) { + continue; + } + count += + css_query_selector_from_link(parent, s, i, list); + } + list_destroy(&names, free); + } + return count; } int css_query_selector_from_group(int group, const char *name, - const css_selector_t *s, list_t *list) + const css_selector_t *s, list_t *list) { - int i; - size_t count; - dict_t *groups; - css_style_link_group_t *slg; - list_node_t *node; - list_t names; - - groups = list_get(&css_library.groups, group); - if (!groups || s->length < 1) { - return 0; - } - count = 0; - i = s->length - 1; - list_create(&names); - if (name) { - list_append(&names, strdup2(name)); - } else { - css_selector_node_get_name_list(s->nodes[i], &names); - list_append(&names, strdup2("*")); - } - for (list_each(node, &names)) { - dict_entry_t *entry; - dict_iterator_t *iter; - char *name = node->data; - slg = dict_fetch_value(groups, name); - if (!slg) { - continue; - } - iter = dict_get_iterator(slg->links); - while ((entry = dict_next(iter))) { - css_style_link_t *link = dict_get_val(entry); - count += css_query_selector_from_link(link, s, i, list); - } - dict_destroy_iterator(iter); - } - list_destroy(&names, free); - return (int)count; + int i; + size_t count; + dict_t *groups; + css_style_link_group_t *slg; + list_node_t *node; + list_t names; + + groups = list_get(&css_library.groups, group); + if (!groups || s->length < 1) { + return 0; + } + count = 0; + i = s->length - 1; + list_create(&names); + if (name) { + list_append(&names, strdup2(name)); + } else { + css_selector_node_get_name_list(s->nodes[i], &names); + list_append(&names, strdup2("*")); + } + for (list_each(node, &names)) { + dict_entry_t *entry; + dict_iterator_t *iter; + char *name = node->data; + slg = dict_fetch_value(groups, name); + if (!slg) { + continue; + } + iter = dict_get_iterator(slg->links); + while ((entry = dict_next(iter))) { + css_style_link_t *link = dict_get_val(entry); + count += css_query_selector_from_link(link, s, i, list); + } + dict_destroy_iterator(iter); + } + list_destroy(&names, free); + return (int)count; } static void css_each_style_link(css_style_link_t *link, const char *selector, - void (*callback)(css_style_rule_t *, - const char *, void *), - void *data) + void (*callback)(css_style_rule_t *, + const char *, void *), + void *data) { - dict_entry_t *entry; - dict_iterator_t *iter; - list_node_t *node; - char fullname[CSS_SELECTOR_MAX_LEN]; - - if (selector) { - sprintf(fullname, "%s %s", link->group->name, selector); - } else { - strcpy(fullname, link->group->name); - } - for (list_each(node, &link->styles)) { - callback(node->data, fullname, data); - } - iter = dict_get_iterator(link->parents); - while ((entry = dict_next(iter))) { - css_style_link_t *parent = dict_get_val(entry); - css_each_style_link(parent, fullname, callback, data); - } - dict_destroy_iterator(iter); + dict_entry_t *entry; + dict_iterator_t *iter; + list_node_t *node; + char fullname[CSS_SELECTOR_MAX_LEN]; + + if (selector) { + sprintf(fullname, "%s %s", link->group->name, selector); + } else { + strcpy(fullname, link->group->name); + } + for (list_each(node, &link->styles)) { + callback(node->data, fullname, data); + } + iter = dict_get_iterator(link->parents); + while ((entry = dict_next(iter))) { + css_style_link_t *parent = dict_get_val(entry); + css_each_style_link(parent, fullname, callback, data); + } + dict_destroy_iterator(iter); } -void css_each_style_rule(void (*callback)(css_style_rule_t *, const char *, void *), - void *data) +void css_each_style_rule(void (*callback)(css_style_rule_t *, const char *, + void *), + void *data) { - dict_t *group; - css_style_link_t *link; - css_style_link_group_t *slg; - dict_iterator_t *iter; - dict_entry_t *entry; - - link = NULL; - group = list_get(&css_library.groups, 0); - iter = dict_get_iterator(group); - while ((entry = dict_next(iter))) { - dict_entry_t *entry_slg; - dict_iterator_t *iter_slg; - - slg = dict_get_val(entry); - iter_slg = dict_get_iterator(slg->links); - while ((entry_slg = dict_next(iter_slg))) { - link = dict_get_val(entry_slg); - css_each_style_link(link, NULL, callback, data); - } - dict_destroy_iterator(iter_slg); - } - dict_destroy_iterator(iter); + dict_t *group; + css_style_link_t *link; + css_style_link_group_t *slg; + dict_iterator_t *iter; + dict_entry_t *entry; + + link = NULL; + group = list_get(&css_library.groups, 0); + iter = dict_get_iterator(group); + while ((entry = dict_next(iter))) { + dict_entry_t *entry_slg; + dict_iterator_t *iter_slg; + + slg = dict_get_val(entry); + iter_slg = dict_get_iterator(slg->links); + while ((entry_slg = dict_next(iter_slg))) { + link = dict_get_val(entry_slg); + css_each_style_link(link, NULL, callback, data); + } + dict_destroy_iterator(iter_slg); + } + dict_destroy_iterator(iter); } css_style_decl_t *css_select_style(const css_selector_t *s) { - list_t list; - list_node_t *node; - css_style_decl_t *style; - - list_create(&list); - style = css_style_decl_create(); - css_query_selector(s, &list); - for (list_each(node, &list)) { - css_style_decl_merge(style, - ((css_style_rule_t *)node->data)->list); - } - list_destroy(&list, NULL); - return style; + list_t list; + list_node_t *node; + css_style_decl_t *style; + + list_create(&list); + style = css_style_decl_create(); + css_query_selector(s, &list); + for (list_each(node, &list)) { + css_style_decl_merge(style, + ((css_style_rule_t *)node->data)->list); + } + list_destroy(&list, NULL); + return style; } css_style_decl_t *css_select_style_with_cache(const css_selector_t *s) { - css_style_decl_t *style; - - style = dict_fetch_value(css_library.cache, &s->hash); - if (style) { - return style; - } - style = css_select_style(s); - dict_add(css_library.cache, (void *)&s->hash, style); - return style; + css_style_decl_t *style; + + style = dict_fetch_value(css_library.cache, &s->hash); + if (style) { + return style; + } + style = css_select_style(s); + dict_add(css_library.cache, (void *)&s->hash, style); + return style; } void css_init_library(void) { - static dict_type_t dt = { 0 }; - - dt.val_dup = NULL; - dt.key_dup = ikey_dict_key_dup; - dt.key_compare = ikey_dict_key_compare; - dt.hash_function = ikey_dict_hash; - dt.key_destructor = ikey_dict_key_destructor; - dt.val_destructor = css_style_cache_destructor; - dt.key_destructor = ikey_dict_key_destructor; - css_library.cache = dict_create(&dt, NULL); - css_library.strpool = strpool_create(); - list_create(&css_library.groups); + static dict_type_t dt = { 0 }; + + dt.val_dup = NULL; + dt.key_dup = ikey_dict_key_dup; + dt.key_compare = ikey_dict_key_compare; + dt.hash_function = ikey_dict_hash; + dt.key_destructor = ikey_dict_key_destructor; + dt.val_destructor = css_style_cache_destructor; + dt.key_destructor = ikey_dict_key_destructor; + css_library.cache = dict_create(&dt, NULL); + css_library.strpool = strpool_create(); + list_create(&css_library.groups); } void css_destroy_library(void) { - dict_destroy(css_library.cache); - strpool_destroy(css_library.strpool); - list_destroy(&css_library.groups, (list_item_destructor_t)dict_destroy); - css_library.strpool = NULL; - css_library.cache = NULL; + dict_destroy(css_library.cache); + strpool_destroy(css_library.strpool); + list_destroy(&css_library.groups, (list_item_destructor_t)dict_destroy); + css_library.strpool = NULL; + css_library.cache = NULL; } static void css_dump_style_rule(css_style_rule_t *rule, - const char *selector_text, void *data) + const char *selector_text, void *data) { - css_dump_context_t *ctx = data; + css_dump_context_t *ctx = data; - DUMPF("\n[%s]", rule->space ? rule->space : ""); - DUMPF("[rank: %d]\n%s {\n", rule->rank, selector_text); - css_dump_style_decl(rule->list, ctx); - DUMP("}\n"); + DUMPF("\n[%s]", rule->space ? rule->space : ""); + DUMPF("[rank: %d]\n%s {\n", rule->rank, selector_text); + css_dump_style_decl(rule->list, ctx); + DUMP("}\n"); } static void css_dump_style_rules(css_dump_context_t *ctx) { - css_each_style_rule(css_dump_style_rule, ctx); + css_each_style_rule(css_dump_style_rule, ctx); } size_t css_print_style_rules(void) { - css_dump_context_t ctx = { - .data = NULL, .len = 0, .max_len = 0, .func = css_dump_to_stdout - }; + css_dump_context_t ctx = { + .data = NULL, .len = 0, .max_len = 0, .func = css_dump_to_stdout + }; - css_dump_style_rules(&ctx); - return ctx.len; + css_dump_style_rules(&ctx); + return ctx.len; } size_t css_style_rules_to_string(char *str, size_t max_len) { - css_dump_context_t ctx = { .data = str, - .len = 0, - .max_len = max_len, - .func = css_dump_to_buffer }; + css_dump_context_t ctx = { .data = str, + .len = 0, + .max_len = max_len, + .func = css_dump_to_buffer }; - css_dump_style_rules(&ctx); - return ctx.len; + css_dump_style_rules(&ctx); + return ctx.len; } diff --git a/lib/css/xmake.lua b/lib/css/xmake.lua index 2195d2f31..9336d7f8c 100644 --- a/lib/css/xmake.lua +++ b/lib/css/xmake.lua @@ -6,6 +6,7 @@ target("libcss") add_files("src/**.c") set_configdir("include/css") add_configfiles("src/config.h.in") + add_headerfiles("include/css.h", "include/(css/*.h)") add_deps("yutil") if is_kind("static") then set_configvar("LIBCSS_STATIC_BUILD", 1) diff --git a/lib/ctest/include/ctest.h b/lib/ctest/include/ctest.h index 8424d2ea6..9589762b5 100644 --- a/lib/ctest/include/ctest.h +++ b/lib/ctest/include/ctest.h @@ -1,7 +1,7 @@ #ifndef TEST_UTIL_H #define TEST_UTIL_H -#include +#include #include #include diff --git a/lib/def/include/LCUI/def.h b/lib/def/include/LCUI/def.h deleted file mode 100644 index 6819c434e..000000000 --- a/lib/def/include/LCUI/def.h +++ /dev/null @@ -1,65 +0,0 @@ - -#ifndef LCUI_DEF_INCLUDE_LCUI_DEF_H -#define LCUI_DEF_INCLUDE_LCUI_DEF_H - -#if defined(__GNUC__) - #define LCUI_API extern __attribute__((visibility("default"))) -#else - #if LCUI_DLL - #ifdef LCUI_EXPORTS - #define LCUI_API __declspec(dllexport) - #else - #define LCUI_API __declspec(dllimport) - #endif - #else - #define LCUI_API extern - #endif -#endif - -#if defined(_WIN32) && !defined(__cplusplus) - #define INLINE __inline -#else - #define INLINE static inline -#endif - -#ifdef _WIN32 - #define LCUI_PLATFORM_WIN32 - #if defined(WINAPI_FAMILY) && (WINAPI_FAMILY == WINAPI_FAMILY_APP) - #define LCUI_PLATFORM_UWP - #else - #define LCUI_PLATFORM_WIN_DESKTOP - #endif -#else - #define LCUI_PLATFORM_LINUX -#endif - -#ifdef __cplusplus -#define LCUI_BEGIN_HEADER extern "C" { -#define LCUI_END_HEADER } -#else -#define LCUI_BEGIN_HEADER /* nothing */ -#define LCUI_END_HEADER -#endif - -#ifdef DEBUG -#define DEBUG_MSG _DEBUG_MSG -#else -#define DEBUG_MSG(format, ...) -#endif - -#define _DEBUG_MSG(format, ...) \ - logger_log(LOGGER_LEVEL_DEBUG, __FILE__ " %d: %s(): " format, \ - __LINE__, __FUNCTION__, ##__VA_ARGS__) - -#ifndef FALSE -#define FALSE 0 -#endif - -#ifndef TRUE -#define TRUE 1 -#endif - -typedef unsigned char LCUI_BOOL; -typedef unsigned char uchar_t; - -#endif diff --git a/lib/def/xmake.lua b/lib/def/xmake.lua deleted file mode 100644 index 5c86594c6..000000000 --- a/lib/def/xmake.lua +++ /dev/null @@ -1,3 +0,0 @@ -target("lcui-def") - set_kind("headeronly") - add_headerfiles("include/(LCUI/def.h)") diff --git a/lib/pandagl/README.md b/lib/pandagl/README.md index 63341268e..7e1717a3b 100644 --- a/lib/pandagl/README.md +++ b/lib/pandagl/README.md @@ -1,3 +1,3 @@ # PandaGL -PandaGL (Panda Graphics Library) a 2D graph library to draw some basic graphics. +PandaGL (Panda Graphics Library) is a 2D graph library to draw some basic graphics. diff --git a/lib/pandagl/src/font/bitmap.h b/lib/pandagl/src/font/bitmap.h index 8f2d5445e..cd8d234c4 100644 --- a/lib/pandagl/src/font/bitmap.h +++ b/lib/pandagl/src/font/bitmap.h @@ -1,4 +1,4 @@ - + /** 初始化字体位图 */ void pd_font_bitmap_init(pd_font_bitmap_t *bitmap); diff --git a/lib/pandagl/xmake.lua b/lib/pandagl/xmake.lua index 65a2b68a1..3c44f10c5 100644 --- a/lib/pandagl/xmake.lua +++ b/lib/pandagl/xmake.lua @@ -29,6 +29,8 @@ target("pandagl") add_includedirs("include") set_configdir("include/pandagl") add_configfiles("src/config.h.in") + add_headerfiles("include/pandagl.h", "include/(pandagl/*.h)") + add_packages("libpng", "libjpeg", "freetype", "fontconfig") if is_kind("static") then set_configvar("PANDAGL_STATIC_BUILD", 1) elseif is_plat("windows") then @@ -37,7 +39,6 @@ target("pandagl") add_options("with-pandagl-font", "with-pandagl-image", "with-pandagl-text") if has_config("with-pandagl-font") then add_files("src/font/*.c") - add_packages("freetype", "fontconfig") if has_package("freetype") then set_configvar("PANDAGL_HAS_FREETYPE", 1) end @@ -50,7 +51,6 @@ target("pandagl") end if has_config("with-pandagl-image") then add_files("src/image/*.c") - add_packages("libpng", "libjpeg") if has_package("libpng") then set_configvar("PANDAGL_HAS_LIBPNG", 1) end diff --git a/lib/platform/include/platform/main.h b/lib/platform/include/platform/main.h index 184de1014..8a2fbfe1a 100644 --- a/lib/platform/include/platform/main.h +++ b/lib/platform/include/platform/main.h @@ -1,3 +1,3 @@ -#ifdef LIBPLAT_WIN_DESKTOP +#ifdef _WIN32 #include "win32_main.h" #endif diff --git a/lib/platform/include/platform/step_timer.h b/lib/platform/include/platform/step_timer.h index 9507dcf44..a5cfc9cf8 100644 --- a/lib/platform/include/platform/step_timer.h +++ b/lib/platform/include/platform/step_timer.h @@ -7,35 +7,35 @@ LIBPLAT_BEGIN_DECLS typedef struct step_timer_t { - // Source timing data. - uint64_t frequency; - uint64_t last_time; - uint64_t max_delta; - - // Derived timing data. - uint64_t elapsed_time; - uint64_t total_time; - uint64_t left_over_time; - - // Members for tracking the framerate. - uint32_t frame_count; - uint32_t frames_per_second; - uint32_t frames_this_second; - uint64_t second_counter; - - // Members for configuring fixed timestep mode. - bool is_fixed_time_step; - uint64_t target_elapsed_time; + // Source timing data. + uint64_t frequency; + uint64_t last_time; + uint64_t max_delta; + + // Derived timing data. + uint64_t elapsed_time; + uint64_t total_time; + uint64_t left_over_time; + + // Members for tracking the framerate. + uint32_t frame_count; + uint32_t frames_per_second; + uint32_t frames_this_second; + uint64_t second_counter; + + // Members for configuring fixed timestep mode. + bool is_fixed_time_step; + uint64_t target_elapsed_time; } step_timer_t; typedef void (*step_timer_handler_t)(step_timer_t *timer, void *data); -void step_timer_init(step_timer_t *timer); +LIBPLAT_PUBLIC void step_timer_init(step_timer_t *timer); // Update timer state, calling the specified Update function the appropriate // number of times. -void step_timer_tick(step_timer_t *timer, step_timer_handler_t handler, - void *data); +LIBPLAT_PUBLIC void step_timer_tick(step_timer_t *timer, + step_timer_handler_t handler, void *data); LIBPLAT_END_DECLS diff --git a/lib/platform/include/platform/win32_main.h b/lib/platform/include/platform/win32_main.h index 26bdd2551..7162145ca 100644 --- a/lib/platform/include/platform/win32_main.h +++ b/lib/platform/include/platform/win32_main.h @@ -1,10 +1,12 @@ -#ifdef LIBPLATFORM_INCLUDE_MAIN_H -#define LIBPLATFORM_INCLUDE_MAIN_H +#ifndef LIBPLATFORM_INCLUDE_PLATFORM_MAIN_H +#define LIBPLATFORM_INCLUDE_PLATFORM_MAIN_H -#include #include #include + +#ifdef LIBPLAT_WIN_DESKTOP #include +#include extern int main(int argc, char *argv[]); @@ -30,3 +32,4 @@ int APIENTRY WinMain(_In_ HINSTANCE hInstance, } #endif +#endif diff --git a/lib/platform/src/linux/linux_keyboard.c b/lib/platform/src/linux/linux_keyboard.c index 7c25da92f..9f92b01eb 100644 --- a/lib/platform/src/linux/linux_keyboard.c +++ b/lib/platform/src/linux/linux_keyboard.c @@ -37,7 +37,7 @@ #include #include #include -#include +#include static struct linux_keyboard_t { int fd; @@ -85,7 +85,6 @@ static void linux_keyboard_dispatch_event(int key) default: break; } - DEBUG_MSG("%c, %d\n", ev.key.code, ev.key.code); ev.type = APP_EVENT_KEYDOWN; app_post_event(&ev); app_event_destroy(&ev); diff --git a/lib/platform/src/linux/linux_mouse.c b/lib/platform/src/linux/linux_mouse.c index e7412c107..38a7d3187 100644 --- a/lib/platform/src/linux/linux_mouse.c +++ b/lib/platform/src/linux/linux_mouse.c @@ -40,7 +40,7 @@ #include #include #include -#include +#include static struct linux_mouse_t { int x; diff --git a/lib/platform/src/linux/linux_x11clipboard.c b/lib/platform/src/linux/linux_x11clipboard.c index 09642f8a7..c7f772566 100644 --- a/lib/platform/src/linux/linux_x11clipboard.c +++ b/lib/platform/src/linux/linux_x11clipboard.c @@ -44,7 +44,7 @@ #include "../app.h" #if defined(LIBPLAT_LINUX) && defined(LIBPLAT_HAS_LIBX11) -#include +#include #define CLIPBOARD_TIMEOUT 1000 diff --git a/lib/platform/xmake.lua b/lib/platform/xmake.lua index 390ea7bbb..e82e9adfa 100644 --- a/lib/platform/xmake.lua +++ b/lib/platform/xmake.lua @@ -16,6 +16,7 @@ target("libplatform") set_configdir("include/platform") add_configfiles("src/config.h.in") add_deps("yutil", "pandagl") + add_headerfiles("include/platform.h", "include/(platform/*.h)") if is_kind("static") then set_configvar("LIBPLAT_STATIC_BUILD", 1) elseif is_plat("windows") then diff --git a/lib/thread/include/thread.h b/lib/thread/include/thread.h index 16f0a098c..f2acd0daf 100644 --- a/lib/thread/include/thread.h +++ b/lib/thread/include/thread.h @@ -1,4 +1,4 @@ -/* +/* * thread.h -- basic thread management * * Copyright (c) 2018-2022, Liu chao All rights reserved. @@ -28,38 +28,62 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LCUI_THREAD_H -#define LCUI_THREAD_H +#ifndef LIB_THREAD_INCLUDE_THREAD_H +#define LIB_THREAD_INCLUDE_THREAD_H -#include +#define LIBTHREAD_VERSION "3.0.0-a" +#define LIBTHREAD_VERSION_MAJOR 3 +#define LIBTHREAD_VERSION_MINOR 0 +#define LIBTHREAD_VERSION_ALTER 0 +/* #undef LIBTHREAD_STATIC_BUILD */ + +#ifndef LIBTHREAD_PUBLIC +#if defined(_MSC_VER) && !defined(LIBTHREAD_STATIC_BUILD) +#ifdef LIBTHREAD_DLL_EXPORT +#define LIBTHREAD_PUBLIC __declspec(dllexport) +#else +#define LIBTHREAD_PUBLIC __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LIBTHREAD_PUBLIC extern __attribute__((visibility("default"))) +#else +#define LIBTHREAD_PUBLIC extern +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif typedef unsigned long thread_t; typedef union thread_mutex_record_t *thread_mutex_t; typedef union thread_cond_record_t *thread_cond_t; -LCUI_BEGIN_HEADER +LIBTHREAD_PUBLIC int thread_mutex_init(thread_mutex_t *mutex); +LIBTHREAD_PUBLIC void thread_mutex_destroy(thread_mutex_t *mutex); +LIBTHREAD_PUBLIC int thread_mutex_trylock(thread_mutex_t *mutex); +LIBTHREAD_PUBLIC int thread_mutex_lock(thread_mutex_t *mutex); +LIBTHREAD_PUBLIC int thread_mutex_unlock(thread_mutex_t *mutex); -LCUI_API int thread_mutex_init(thread_mutex_t *mutex); -LCUI_API void thread_mutex_destroy(thread_mutex_t *mutex); -LCUI_API int thread_mutex_trylock(thread_mutex_t *mutex); -LCUI_API int thread_mutex_lock(thread_mutex_t *mutex); -LCUI_API int thread_mutex_unlock(thread_mutex_t *mutex); +LIBTHREAD_PUBLIC int thread_cond_init(thread_cond_t *cond); +LIBTHREAD_PUBLIC int thread_cond_destroy(thread_cond_t *cond); +LIBTHREAD_PUBLIC int thread_cond_wait(thread_cond_t *cond, + thread_mutex_t *mutex); +LIBTHREAD_PUBLIC int thread_cond_timedwait(thread_cond_t *cond, + thread_mutex_t *mutex, + unsigned int ms); +LIBTHREAD_PUBLIC int thread_cond_signal(thread_cond_t *cond); +LIBTHREAD_PUBLIC int thread_cond_broadcast(thread_cond_t *cond); -LCUI_API int thread_cond_init(thread_cond_t *cond); -LCUI_API int thread_cond_destroy(thread_cond_t *cond); -LCUI_API int thread_cond_wait(thread_cond_t *cond, thread_mutex_t *mutex); -LCUI_API int thread_cond_timedwait(thread_cond_t *cond, thread_mutex_t *mutex, - unsigned int ms); -LCUI_API int thread_cond_signal(thread_cond_t *cond); -LCUI_API int thread_cond_broadcast(thread_cond_t *cond); +LIBTHREAD_PUBLIC thread_t thread_self(void); +LIBTHREAD_PUBLIC int thread_create(thread_t *tidp, void (*start_rtn)(void *), + void *arg); +LIBTHREAD_PUBLIC int thread_join(thread_t thread, void **retval); +LIBTHREAD_PUBLIC void thread_cancel(thread_t thread); +LIBTHREAD_PUBLIC void thread_exit(void *retval); -LCUI_API thread_t thread_self(void); -LCUI_API int thread_create(thread_t *tidp, void (*start_rtn)(void *), - void *arg); -LCUI_API int thread_join(thread_t thread, void **retval); -LCUI_API void thread_cancel(thread_t thread); -LCUI_API void thread_exit(void *retval); - -LCUI_END_HEADER +#ifdef __cplusplus +} +#endif #endif diff --git a/lib/thread/src/pthread.c b/lib/thread/src/pthread.c index 230076d70..04027a375 100644 --- a/lib/thread/src/pthread.c +++ b/lib/thread/src/pthread.c @@ -5,7 +5,7 @@ #include #include #include -#include "../include/thread.h" +#include "thread.h" typedef union thread_mutex_record_t { pthread_mutex_t handle; @@ -73,10 +73,7 @@ int thread_cond_timedwait(thread_cond_t *cond, thread_mutex_t *mutex, out_usec = now.tv_usec + ms * 1000; outtime.tv_sec = now.tv_sec + out_usec / 1000000; outtime.tv_nsec = (out_usec % 1000000) * 1000; - DEBUG_MSG("wait, ms = %u, outtime.tv_nsec: %ld\n", ms, outtime.tv_nsec); ret = pthread_cond_timedwait(&(*cond)->handle, &(*mutex)->handle, &outtime); - DEBUG_MSG("ret: %d, ETIMEDOUT = %d, EINVAL = %d\n", ret, ETIMEDOUT, - EINVAL); switch (ret) { case 0: return 0; diff --git a/lib/thread/src/thread.h.in b/lib/thread/src/thread.h.in new file mode 100644 index 000000000..246d25358 --- /dev/null +++ b/lib/thread/src/thread.h.in @@ -0,0 +1,89 @@ +/* + * thread.h -- basic thread management + * + * Copyright (c) 2018-2022, Liu chao All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of LCUI nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef LIB_THREAD_INCLUDE_THREAD_H +#define LIB_THREAD_INCLUDE_THREAD_H + +#define LIBTHREAD_VERSION "${VERSION}" +#define LIBTHREAD_VERSION_MAJOR ${VERSION_MAJOR} +#define LIBTHREAD_VERSION_MINOR ${VERSION_MINOR} +#define LIBTHREAD_VERSION_ALTER ${VERSION_ALTER} +${define LIBTHREAD_STATIC_BUILD} + +#ifndef LIBTHREAD_PUBLIC +#if defined(_MSC_VER) && !defined(LIBTHREAD_STATIC_BUILD) +#ifdef LIBTHREAD_DLL_EXPORT +#define LIBTHREAD_PUBLIC __declspec(dllexport) +#else +#define LIBTHREAD_PUBLIC __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LIBTHREAD_PUBLIC extern __attribute__((visibility("default"))) +#else +#define LIBTHREAD_PUBLIC extern +#endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +typedef unsigned long thread_t; +typedef union thread_mutex_record_t *thread_mutex_t; +typedef union thread_cond_record_t *thread_cond_t; + +LIBTHREAD_PUBLIC int thread_mutex_init(thread_mutex_t *mutex); +LIBTHREAD_PUBLIC void thread_mutex_destroy(thread_mutex_t *mutex); +LIBTHREAD_PUBLIC int thread_mutex_trylock(thread_mutex_t *mutex); +LIBTHREAD_PUBLIC int thread_mutex_lock(thread_mutex_t *mutex); +LIBTHREAD_PUBLIC int thread_mutex_unlock(thread_mutex_t *mutex); + +LIBTHREAD_PUBLIC int thread_cond_init(thread_cond_t *cond); +LIBTHREAD_PUBLIC int thread_cond_destroy(thread_cond_t *cond); +LIBTHREAD_PUBLIC int thread_cond_wait(thread_cond_t *cond, + thread_mutex_t *mutex); +LIBTHREAD_PUBLIC int thread_cond_timedwait(thread_cond_t *cond, + thread_mutex_t *mutex, + unsigned int ms); +LIBTHREAD_PUBLIC int thread_cond_signal(thread_cond_t *cond); +LIBTHREAD_PUBLIC int thread_cond_broadcast(thread_cond_t *cond); + +LIBTHREAD_PUBLIC thread_t thread_self(void); +LIBTHREAD_PUBLIC int thread_create(thread_t *tidp, void (*start_rtn)(void *), + void *arg); +LIBTHREAD_PUBLIC int thread_join(thread_t thread, void **retval); +LIBTHREAD_PUBLIC void thread_cancel(thread_t thread); +LIBTHREAD_PUBLIC void thread_exit(void *retval); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/thread/src/windows.c b/lib/thread/src/windows.c index ab2af99ac..643acc8c4 100644 --- a/lib/thread/src/windows.c +++ b/lib/thread/src/windows.c @@ -4,7 +4,7 @@ #include #include #include -#include "../include/thread.h" +#include "thread.h" typedef union thread_mutex_record_t { HANDLE handle; diff --git a/lib/thread/xmake.lua b/lib/thread/xmake.lua index 35d330263..da14327e1 100644 --- a/lib/thread/xmake.lua +++ b/lib/thread/xmake.lua @@ -1,8 +1,15 @@ target("libthread") - set_default(false) set_kind("$(kind)") add_files("src/*.c") + set_configdir("include") + add_configfiles("src/thread.h.in") + add_headerfiles("include/thread.h") if not is_plat("windows") then add_syslinks("pthread", "dl") end add_deps("yutil") + if is_kind("static") then + set_configvar("LIBTHREAD_STATIC_BUILD", 1) + elseif is_plat("windows") then + add_defines("LIBTHREAD_DLL_EXPORT") + end diff --git a/lib/timer/include/timer.h b/lib/timer/include/timer.h index 3292c4623..9791bcb7b 100644 --- a/lib/timer/include/timer.h +++ b/lib/timer/include/timer.h @@ -2,21 +2,44 @@ #ifndef LCUI_TIMER_H #define LCUI_TIMER_H -#include +#define LIBTIMER_VERSION "3.0.0-a" +#define LIBTIMER_VERSION_MAJOR 3 +#define LIBTIMER_VERSION_MINOR 0 +#define LIBTIMER_VERSION_ALTER 0 +/* #undef LIBTIMER_STATIC_BUILD */ + #include -LCUI_BEGIN_HEADER +#ifdef __cplusplus +extern "C" { +#endif -LCUI_API int lcui_destroy_timer(int timer_id); -LCUI_API int lcui_pause_timer(int timer_id); -LCUI_API int lcui_continue_timer(int timer_id); -LCUI_API int lcui_reset_timer(int timer_id, long int n_ms); -LCUI_API int lcui_set_timeout(long int n_ms, void (*callback)(void *), void *arg); -LCUI_API int lcui_set_interval(long int n_ms, void (*callback)(void *), void *arg); -LCUI_API size_t lcui_process_timers(void); -LCUI_API void lcui_init_timers(void); -LCUI_API void lcui_destroy_timers(void); +#ifndef LIBTIMER_PUBLIC +#if defined(_MSC_VER) && !defined(LIBTIMER_STATIC_BUILD) +#ifdef LIBTIMER_DLL_EXPORT +#define LIBTIMER_PUBLIC __declspec(dllexport) +#else +#define LIBTIMER_PUBLIC __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LIBTIMER_PUBLIC extern __attribute__((visibility("default"))) +#else +#define LIBTIMER_PUBLIC extern +#endif +#endif + +LIBTIMER_PUBLIC int lcui_destroy_timer(int timer_id); +LIBTIMER_PUBLIC int lcui_pause_timer(int timer_id); +LIBTIMER_PUBLIC int lcui_continue_timer(int timer_id); +LIBTIMER_PUBLIC int lcui_reset_timer(int timer_id, long int n_ms); +LIBTIMER_PUBLIC int lcui_set_timeout(long int n_ms, void (*callback)(void *), void *arg); +LIBTIMER_PUBLIC int lcui_set_interval(long int n_ms, void (*callback)(void *), void *arg); +LIBTIMER_PUBLIC size_t lcui_process_timers(void); +LIBTIMER_PUBLIC void lcui_init_timers(void); +LIBTIMER_PUBLIC void lcui_destroy_timers(void); -LCUI_END_HEADER +#ifdef __cplusplus +} +#endif #endif diff --git a/lib/timer/src/timer.c b/lib/timer/src/timer.c index e85d52505..86c2d8f3b 100644 --- a/lib/timer/src/timer.c +++ b/lib/timer/src/timer.c @@ -1,7 +1,7 @@ #include #include -#include -#include +#include +#include #include static struct lcui_timers_t { diff --git a/lib/timer/src/timer.h.in b/lib/timer/src/timer.h.in new file mode 100644 index 000000000..28b4f36cc --- /dev/null +++ b/lib/timer/src/timer.h.in @@ -0,0 +1,45 @@ + +#ifndef LCUI_TIMER_H +#define LCUI_TIMER_H + +#define LIBTIMER_VERSION "${VERSION}" +#define LIBTIMER_VERSION_MAJOR ${VERSION_MAJOR} +#define LIBTIMER_VERSION_MINOR ${VERSION_MINOR} +#define LIBTIMER_VERSION_ALTER ${VERSION_ALTER} +${define LIBTIMER_STATIC_BUILD} + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifndef LIBTIMER_PUBLIC +#if defined(_MSC_VER) && !defined(LIBTIMER_STATIC_BUILD) +#ifdef LIBTIMER_DLL_EXPORT +#define LIBTIMER_PUBLIC __declspec(dllexport) +#else +#define LIBTIMER_PUBLIC __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LIBTIMER_PUBLIC extern __attribute__((visibility("default"))) +#else +#define LIBTIMER_PUBLIC extern +#endif +#endif + +LIBTIMER_PUBLIC int lcui_destroy_timer(int timer_id); +LIBTIMER_PUBLIC int lcui_pause_timer(int timer_id); +LIBTIMER_PUBLIC int lcui_continue_timer(int timer_id); +LIBTIMER_PUBLIC int lcui_reset_timer(int timer_id, long int n_ms); +LIBTIMER_PUBLIC int lcui_set_timeout(long int n_ms, void (*callback)(void *), void *arg); +LIBTIMER_PUBLIC int lcui_set_interval(long int n_ms, void (*callback)(void *), void *arg); +LIBTIMER_PUBLIC size_t lcui_process_timers(void); +LIBTIMER_PUBLIC void lcui_init_timers(void); +LIBTIMER_PUBLIC void lcui_destroy_timers(void); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/lib/timer/xmake.lua b/lib/timer/xmake.lua index 068318300..26d8141a6 100644 --- a/lib/timer/xmake.lua +++ b/lib/timer/xmake.lua @@ -1,5 +1,12 @@ target("libtimer") - set_default(false) set_kind("$(kind)") add_files("src/*.c") add_deps("yutil", "libthread") + set_configdir("include") + add_configfiles("src/timer.h.in") + add_headerfiles("include/timer.h") + if is_kind("static") then + set_configvar("LIBTIMER_STATIC_BUILD", 1) + elseif is_plat("windows") then + add_defines("LIBTIMER_DLL_EXPORT") + end diff --git a/lib/ui-builder/src/builder.c b/lib/ui-builder/src/builder.c deleted file mode 100644 index 5cf31d6b9..000000000 --- a/lib/ui-builder/src/builder.c +++ /dev/null @@ -1,381 +0,0 @@ -/* *************************************************************************** - * builder.c -- the GUI build module, parse UI config code and build UI. - * - * Copyright (c) 2018-2022, Liu chao All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * * Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * * Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * * Neither the name of LCUI nor the names of its contributors may be used - * to endorse or promote products derived from this software without - * specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#define WARN_TXT "[builder] warning: this module is not enabled before build.\n" - -#ifdef WITH_LIBXML2 -#include -#include - -#define check_prop_name(PROP, NAME) \ - (xmlStrcasecmp(PROP->name, (xmlChar *)NAME) == 0) - -enum ui_xml_parser_id { ID_ROOT, ID_UI, ID_WIDGET, ID_RESOURCE }; - -/** 解析器行为,用于决定解析器在解析完元素后的行为 */ -enum ParserBehavior { - PB_ERROR, /**< 给出错误提示 */ - PB_WARNING, /**< 给出警告提示 */ - PB_NEXT, /**< 处理下个元素 */ - PB_ENTER /**< 进入子元素列表 */ -}; - -typedef struct xml_parser_t xml_parser_t; -typedef int (*xml_parser_method_t)(xml_parser_t *, xmlNodePtr); - -typedef struct xml_node_parser_t { - int id; - const char *name; - xml_parser_method_t parse; -} xml_node_parser_t; - -struct xml_parser_t { - int id; - ui_widget_t *root; - ui_widget_t *widget; - ui_widget_t *parent_widget; - const ui_widget_prototype_t *widget_proto; - xml_node_parser_t *parent_parser; - const char *space; -}; - -#define EXIT(CODE) \ - code = CODE; \ - goto exit; - -static void xmlPrintErrorMessage(xmlErrorPtr err) -{ - logger_error("[builder] %s (%d): error %d: %s\n", - err->file ? err->file : "(memory)", err->line, err->code, - err->message); -} - -/** 解析 元素,根据相关参数载入资源 */ -static int ui_builder_parse_resource_node(xml_parser_t *parser, xmlNodePtr node) -{ - xmlAttrPtr prop; - - int code = PB_NEXT; - char *prop_val, *type = NULL, *src = NULL; - - if (node->type != XML_ELEMENT_NODE) { - return PB_NEXT; - } - prop = node->properties; - while (prop) { - prop_val = (char *)xmlGetProp(node, prop->name); - if (check_prop_name(prop, "type")) { - type = prop_val; - } else if (check_prop_name(prop, "src")) { - src = prop_val; - } else { - xmlFree(prop_val); - } - prop = prop->next; - } - if (!type && !src) { - return PB_WARNING; - } - if (strstr(type, "application/font-")) { - if (pd_font_library_load_file(src) < 1) { - EXIT(PB_WARNING); - } - } else if (strcmp(type, "text/css") == 0) { - if (src) { - if (ui_load_css_file(src) != 0) { - EXIT(PB_WARNING); - } - } - for (node = node->children; node; node = node->next) { - if (node->type != XML_TEXT_NODE) { - continue; - } - ui_load_css_string((char *)node->content, - parser->space); - } - } else if (strcmp(type, "text/xml") == 0) { - ui_widget_t *pack; - if (!src) { - EXIT(PB_WARNING); - } - pack = ui_load_xml_file(src); - if (!pack) { - EXIT(PB_WARNING); - } - if (parser->parent_widget) { - ui_widget_append(parser->parent_widget, pack); - } else if (parser->root) { - ui_widget_append(parser->root, pack); - } else { - ui_widget_remove(pack); - EXIT(PB_WARNING); - } - ui_widget_unwrap(pack); - } -exit: - if (src) { - xmlFree(src); - } - if (type) { - xmlFree(type); - } - return code; -} - -/** 解析 元素,主要作用是创建一个容纳全部部件的根级部件 */ -static int ui_builder_parse_ui_node(xml_parser_t *parser, xmlNodePtr node) -{ - if (node->type != XML_ELEMENT_NODE) { - return PB_NEXT; - } - if (parser->parent_parser && parser->parent_parser->id != ID_ROOT) { - return PB_ERROR; - } - parser->widget = ui_create_widget(NULL); - parser->root = parser->widget; - return PB_ENTER; -} - -/** 解析 元素数据 */ -static int ui_builder_parse_widget_node(xml_parser_t *parser, xmlNodePtr node) -{ - xmlAttrPtr prop; - char *prop_val = NULL, *prop_name, *type = NULL; - ui_widget_t *w = NULL, *parent = parser->widget; - - if (parser->parent_parser && parser->parent_parser->id != ID_UI && - parser->parent_parser->id != ID_WIDGET) { - return PB_ERROR; - } - switch (node->type) { - case XML_ELEMENT_NODE: - break; - case XML_TEXT_NODE: - ui_widget_set_text(parent, (char *)node->content); - DEBUG_MSG("widget: %s, set text: %s\n", parent->type, - (char *)node->content); - return PB_NEXT; - default: - return PB_ERROR; - } - if (parser->widget_proto) { - w = ui_create_widget_with_prototype(parser->widget_proto); - } else { - for (prop = node->properties; prop; prop = prop->next) { - prop_val = (char *)xmlGetProp(node, prop->name); - if (check_prop_name(prop, "type")) { - type = prop_val; - break; - } - if (prop_val) { - xmlFree(prop_val); - } - } - w = ui_create_widget(type); - if (type) { - xmlFree(type); - } - } - if (!w) { - return PB_ERROR; - } - DEBUG_MSG("create widget: %s\n", w->type); - ui_widget_append(parent, w); - parser->widget = w; - for (prop = node->properties; prop; prop = prop->next) { - prop_val = (char *)xmlGetProp(node, prop->name); - if (check_prop_name(prop, "id")) { - DEBUG_MSG("widget: %p, set id: %s\n", w, prop_val); - ui_widget_set_id(w, prop_val); - } else if (check_prop_name(prop, "class")) { - DEBUG_MSG("widget: %p, add class: %s\n", w, prop_val); - ui_widget_add_class(w, prop_val); - } else { - prop_name = strdup2((const char *)prop->name); - strtolower(prop_name, (const char *)prop->name); - ui_widget_set_attribute(w, prop_name, prop_val); - free(prop_name); - } - if (prop_val) { - xmlFree(prop_val); - } - } - return PB_ENTER; -} - -static xml_node_parser_t *ui_builder_get_node_parser(const char *name) -{ - size_t i; - static xml_node_parser_t parsers[] = { - { ID_WIDGET, "w", ui_builder_parse_widget_node }, - { ID_WIDGET, "widget", ui_builder_parse_widget_node }, - { ID_RESOURCE, "resource", ui_builder_parse_resource_node }, - { ID_UI, "ui", ui_builder_parse_ui_node } - }; - - for (i = 0; i < sizeof(parsers) / sizeof(xml_node_parser_t); ++i) { - if (strcmp(parsers[i].name, name) == 0) { - return &parsers[i]; - } - } - return NULL; -} - -/** 解析 xml 文档结点 */ -static void ui_builder_parse_node(xml_parser_t *parser, xmlNodePtr node) -{ - xml_node_parser_t *p; - xml_parser_t cur_parser; - ui_widget_prototype_t *proto; - - for (; node; node = node->next) { - proto = NULL; - if (node->type == XML_COMMENT_NODE) { - continue; - } - if (node->type == XML_ELEMENT_NODE) { - p = ui_builder_get_node_parser((const char*)node->name); - if (!p) { - proto = - ui_get_widget_prototype((char *)node->name); - /* If there is no suitable parser, but a widget - * prototype with the same name already exists, - * use the widget parser - */ - if (proto) { - p = ui_builder_get_node_parser("w"); - } else { - continue; - } - } - } else { - p = parser->parent_parser; - if (!p) { - continue; - } - } - cur_parser = *parser; - cur_parser.parent_widget = parser->widget; - cur_parser.widget_proto = proto; - switch (p->parse(&cur_parser, node)) { - case PB_ENTER: - cur_parser.parent_parser = p; - ui_builder_parse_node(&cur_parser, node->children); - break; - case PB_NEXT: - break; - case PB_WARNING: - logger_warning("[builder] %s (%d): warning: %s node.\n", - node->doc->name, node->line, node->name); - break; - case PB_ERROR: - default: - logger_error("[builder] %s (%d): error: %s node.\n", - node->doc->name, node->line, node->name); - break; - } - if (!parser->root && cur_parser.root) { - parser->root = cur_parser.root; - } - } -} -#endif - -ui_widget_t *ui_load_xml_string(const char *str, int size) -{ -#ifndef WITH_LIBXML2 - logger_warning(WARN_TXT); -#else - xmlDocPtr doc; - xmlNodePtr cur; - xml_parser_t parser; - - memset(&parser, 0, sizeof(parser)); - doc = xmlParseMemory(str, size); - if (!doc) { - xmlPrintErrorMessage(xmlGetLastError()); - logger_error("[builder] failed to parse xml form memory\n"); - goto FAILED; - } - cur = xmlDocGetRootElement(doc); - if (xmlStrcasecmp(cur->name, BAD_CAST "lcui-app")) { - logger_error("[builder] error root node name: %s\n", cur->name); - goto FAILED; - } - ui_builder_parse_node(&parser, cur->children); -FAILED: - if (doc) { - xmlFreeDoc(doc); - } - return parser.root; -#endif - return NULL; -} - -ui_widget_t *ui_load_xml_file(const char *filepath) -{ -#ifndef WITH_LIBXML2 - logger_warning(WARN_TXT); -#else - xmlDocPtr doc; - xmlNodePtr cur; - xml_parser_t parser; - - memset(&parser, 0, sizeof(parser)); - parser.space = filepath; - doc = xmlParseFile(filepath); - if (!doc) { - xmlPrintErrorMessage(xmlGetLastError()); - logger_error("[builder] failed to parse xml form file\n"); - goto FAILED; - } - cur = xmlDocGetRootElement(doc); - if (xmlStrcasecmp(cur->name, BAD_CAST "lcui-app")) { - logger_error("[builder] error root node name: %s\n", cur->name); - goto FAILED; - } - ui_builder_parse_node(&parser, cur->children); -FAILED: - if (doc) { - xmlFreeDoc(doc); - } - return parser.root; -#endif - return NULL; -} diff --git a/lib/ui-cursor/include/ui_cursor.h b/lib/ui-cursor/include/ui_cursor.h index 2ac474297..aae1ab826 100644 --- a/lib/ui-cursor/include/ui_cursor.h +++ b/lib/ui-cursor/include/ui_cursor.h @@ -1,21 +1,24 @@ -// TODO: Reduce dependence on lcui header files +#ifndef LIB_UI_CURSOR_INCLUDE_UI_CURSOR_H +#define LIB_UI_CURSOR_INCLUDE_UI_CURSOR_H -#include +#include "ui_cursor/common.h" #include #include #include -LCUI_BEGIN_HEADER +LIBUI_CURSOR_BEGIN_DECLS -LCUI_API void ui_cursor_refresh(void); -LCUI_API LCUI_BOOL ui_cursor_is_visible(void); -LCUI_API void ui_cursor_show(void); -LCUI_API void ui_cursor_hide(void); -LCUI_API void ui_cursor_set_position(int x, int y); -LCUI_API int ui_cursor_set_image(pd_canvas_t *image); -LCUI_API void ui_cursor_get_position(int *x, int *y); -LCUI_API int ui_cursor_paint(app_window_t *w, app_window_paint_t* paint); -LCUI_API void ui_cursor_init(void); -LCUI_API void ui_cursor_destroy(void); +LIBUI_CURSOR_PUBLIC void ui_cursor_refresh(void); +LIBUI_CURSOR_PUBLIC bool ui_cursor_is_visible(void); +LIBUI_CURSOR_PUBLIC void ui_cursor_show(void); +LIBUI_CURSOR_PUBLIC void ui_cursor_hide(void); +LIBUI_CURSOR_PUBLIC void ui_cursor_set_position(int x, int y); +LIBUI_CURSOR_PUBLIC int ui_cursor_set_image(pd_canvas_t *image); +LIBUI_CURSOR_PUBLIC void ui_cursor_get_position(int *x, int *y); +LIBUI_CURSOR_PUBLIC int ui_cursor_paint(app_window_t *w, app_window_paint_t* paint); +LIBUI_CURSOR_PUBLIC void ui_cursor_init(void); +LIBUI_CURSOR_PUBLIC void ui_cursor_destroy(void); -LCUI_END_HEADER +LIBUI_CURSOR_END_DECLS + +#endif diff --git a/lib/ui-cursor/include/ui_cursor/common.h b/lib/ui-cursor/include/ui_cursor/common.h new file mode 100644 index 000000000..101d3753a --- /dev/null +++ b/lib/ui-cursor/include/ui_cursor/common.h @@ -0,0 +1,22 @@ +#include "config.h" +#ifdef __cplusplus +#define LIBUI_CURSOR_BEGIN_DECLS extern "C" { +#define LIBUI_CURSOR_END_DECLS } +#else +#define LIBUI_CURSOR_BEGIN_DECLS +#define LIBUI_CURSOR_END_DECLS +#endif + +#ifndef LIBUI_CURSOR_PUBLIC +#if defined(_MSC_VER) && !defined(LIBUI_CURSOR_STATIC_BUILD) +#ifdef LIBUI_CURSOR_DLL_EXPORT +#define LIBUI_CURSOR_PUBLIC __declspec(dllexport) +#else +#define LIBUI_CURSOR_PUBLIC __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LIBUI_CURSOR_PUBLIC extern __attribute__((visibility("default"))) +#else +#define LIBUI_CURSOR_PUBLIC extern +#endif +#endif diff --git a/lib/ui-cursor/src/config.h.in b/lib/ui-cursor/src/config.h.in new file mode 100644 index 000000000..6200af206 --- /dev/null +++ b/lib/ui-cursor/src/config.h.in @@ -0,0 +1,5 @@ +#define LIBUI_CURSOR_VERSION "${VERSION}" +#define LIBUI_CURSOR_VERSION_MAJOR ${VERSION_MAJOR} +#define LIBUI_CURSOR_VERSION_MINOR ${VERSION_MINOR} +#define LIBUI_CURSOR_VERSION_ALTER ${VERSION_ALTER} +${define LIBUI_CURSOR_STATIC_BUILD} diff --git a/lib/ui-cursor/src/cursor.c b/lib/ui-cursor/src/cursor.c index 65338beab..c19ad124d 100644 --- a/lib/ui-cursor/src/cursor.c +++ b/lib/ui-cursor/src/cursor.c @@ -2,12 +2,12 @@ static struct ui_cursor_t { int x, y; - LCUI_BOOL visible; + bool visible; pd_canvas_t image; app_window_t *window; } ui_cursor; -static uchar_t ui_cursor_image_data[4][12 * 19] = { +static unsigned char ui_cursor_image_data[4][12 * 19] = { { 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 229, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 3, 255, 229, 3, 3, 0, @@ -138,7 +138,7 @@ void ui_cursor_refresh(void) app_post_event(&e); } -LCUI_BOOL ui_cursor_is_visible(void) +bool ui_cursor_is_visible(void) { return ui_cursor.visible; } @@ -203,8 +203,6 @@ void ui_cursor_init(void) pd_canvas_init(&ui_cursor.image); /* 载入自带的游标的图形数据 */ ui_cursor_load_default_image(&image); - ui_cursor.x = app_get_screen_width() / 2; - ui_cursor.y = app_get_screen_height() / 2; // TODO: 移除 app 依赖 app_on_event(APP_EVENT_MOUSEMOVE, ui_cursor_on_mouse_event, NULL); ui_cursor_set_image(&image); diff --git a/lib/ui-cursor/xmake.lua b/lib/ui-cursor/xmake.lua new file mode 100644 index 000000000..ad7a65303 --- /dev/null +++ b/lib/ui-cursor/xmake.lua @@ -0,0 +1,15 @@ +set_project("libui-cursor") +set_version("0.1.0-a") + +target("libui-cursor") + set_kind("$(kind)") + add_files("src/**.c") + add_deps("yutil", "pandagl", "libplatform") + set_configdir("include/ui_cursor") + add_configfiles("src/config.h.in") + add_headerfiles("include/ui_cursor.h", "include/(ui_cursor/*.h)") + if is_kind("static") then + set_configvar("LIBUI_CURSOR_STATIC_BUILD", 1) + elseif is_plat("windows") then + add_defines("LIBUI_CURSOR_DLL_EXPORT") + end diff --git a/lib/ui-server/include/ui_server.h b/lib/ui-server/include/ui_server.h index a173c8709..255778d04 100644 --- a/lib/ui-server/include/ui_server.h +++ b/lib/ui-server/include/ui_server.h @@ -1,20 +1,23 @@ -// TODO: Reduce dependence on lcui header files +#ifndef LIB_UI_SERVER_INCLUDE_UI_SERVER_H +#define LIB_UI_SERVER_INCLUDE_UI_SERVER_H -#include -#include +#include "ui_server/common.h" #include +#include + +LIBUI_SERVER_BEGIN_DECLS -LCUI_BEGIN_HEADER +LIBUI_SERVER_PUBLIC ui_widget_t *ui_server_get_widget(app_window_t *window); +LIBUI_SERVER_PUBLIC app_window_t *ui_server_get_window(ui_widget_t *widget); +LIBUI_SERVER_PUBLIC int ui_server_disconnect(ui_widget_t *widget, app_window_t *window); +LIBUI_SERVER_PUBLIC void ui_server_connect(ui_widget_t *widget, app_window_t *window); +LIBUI_SERVER_PUBLIC size_t ui_server_render(void); +LIBUI_SERVER_PUBLIC void ui_server_present(void); +LIBUI_SERVER_PUBLIC void ui_server_init(void); +LIBUI_SERVER_PUBLIC void ui_server_set_threads(int threads); +LIBUI_SERVER_PUBLIC void ui_server_set_paint_flashing_enabled(bool enabled); +LIBUI_SERVER_PUBLIC void ui_server_destroy(void); -LCUI_API ui_widget_t *ui_server_get_widget(app_window_t *window); -LCUI_API app_window_t *ui_server_get_window(ui_widget_t *widget); -LCUI_API int ui_server_disconnect(ui_widget_t *widget, app_window_t *window); -LCUI_API void ui_server_connect(ui_widget_t *widget, app_window_t *window); -LCUI_API size_t ui_server_render(void); -LCUI_API void ui_server_present(void); -LCUI_API void ui_server_init(void); -LCUI_API void ui_server_set_threads(int threads); -LCUI_API void ui_server_set_paint_flashing_enabled(LCUI_BOOL enabled); -LCUI_API void ui_server_destroy(void); +LIBUI_SERVER_END_DECLS -LCUI_END_HEADER +#endif diff --git a/lib/ui-server/include/ui_server/common.h b/lib/ui-server/include/ui_server/common.h new file mode 100644 index 000000000..e533a0df9 --- /dev/null +++ b/lib/ui-server/include/ui_server/common.h @@ -0,0 +1,22 @@ +#include "config.h" +#ifdef __cplusplus +#define LIBUI_SERVER_BEGIN_DECLS extern "C" { +#define LIBUI_SERVER_END_DECLS } +#else +#define LIBUI_SERVER_BEGIN_DECLS +#define LIBUI_SERVER_END_DECLS +#endif + +#ifndef LIBUI_SERVER_PUBLIC +#if defined(_MSC_VER) && !defined(LIBUI_SERVER_STATIC_BUILD) +#ifdef LIBUI_SERVER_DLL_EXPORT +#define LIBUI_SERVER_PUBLIC __declspec(dllexport) +#else +#define LIBUI_SERVER_PUBLIC __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LIBUI_SERVER_PUBLIC extern __attribute__((visibility("default"))) +#else +#define LIBUI_SERVER_PUBLIC extern +#endif +#endif diff --git a/lib/ui-server/src/config.h.in b/lib/ui-server/src/config.h.in new file mode 100644 index 000000000..a143bb7d9 --- /dev/null +++ b/lib/ui-server/src/config.h.in @@ -0,0 +1,6 @@ +#define LIBUI_SERVER_VERSION "${VERSION}" +#define LIBUI_SERVER_VERSION_MAJOR ${VERSION_MAJOR} +#define LIBUI_SERVER_VERSION_MINOR ${VERSION_MINOR} +#define LIBUI_SERVER_VERSION_ALTER ${VERSION_ALTER} +${define LIBUI_SERVER_STATIC_BUILD} +${define LIBUI_SERVER_HAS_OPENMP} diff --git a/lib/ui-server/src/server.c b/lib/ui-server/src/server.c index a60f969f4..435c407ea 100644 --- a/lib/ui-server/src/server.c +++ b/lib/ui-server/src/server.c @@ -1,15 +1,12 @@ -// TODO: Reduce dependence on lcui header files - -#include +#include #include #include #include #include #include -#include #include -#ifdef ENABLE_OPENMP +#ifdef LIBUI_SERVER_HAS_OPENMP #include #endif @@ -17,16 +14,16 @@ typedef struct window_mutation_record_t { app_window_t *window; - LCUI_BOOL update_size; - LCUI_BOOL update_position; - LCUI_BOOL update_title; - LCUI_BOOL update_visible; + bool update_size; + bool update_position; + bool update_title; + bool update_visible; int x; int y; int width; int height; wchar_t title[TITLE_MAX_SIZE]; - LCUI_BOOL visible; + bool visible; } window_mutation_record_t; typedef struct ui_flash_rect_t { @@ -42,15 +39,15 @@ typedef struct ui_dirty_layer_t { typedef struct ui_connection_t { /** widget is ready to sync data from window */ - LCUI_BOOL ready; + bool ready; /** whether new content has been rendered */ - LCUI_BOOL rendered; + bool rendered; /** flashing rect list */ list_t flash_rects; - LCUI_BOOL window_visible; + bool window_visible; app_window_t *window; ui_widget_t *widget; } ui_connection_t; @@ -59,11 +56,11 @@ static struct ui_server_t { /** list_t */ list_t connections; ui_mutation_observer_t *observer; - LCUI_BOOL paint_flashing_enabled; + bool paint_flashing_enabled; int num_rendering_threads; } ui_server; -INLINE int is_rect_equals(const pd_rect_t *a, const pd_rect_t *b) +static inline int is_rect_equals(const pd_rect_t *a, const pd_rect_t *b) { return a->x == b->x && a->y == b->y && a->width == b->width && a->height == b->height; @@ -213,7 +210,7 @@ static void ui_server_on_window_resize(app_event_t *e, void *arg) static void ui_server_on_window_minmaxinfo(app_event_t *e, void *arg) { - LCUI_BOOL resizable = FALSE; + bool resizable = FALSE; int width, height; ui_widget_t *widget; css_computed_style_t *style; @@ -690,6 +687,7 @@ static void ui_server_on_widget_mutation(ui_mutation_list_t *mutation_list, void ui_server_init(void) { + ui_cursor_init(); ui_server.observer = ui_mutation_observer_create(ui_server_on_widget_mutation, NULL); app_on_event(APP_EVENT_VISIBILITY_CHANGE, @@ -716,13 +714,14 @@ void ui_server_set_threads(int threads) ui_server.num_rendering_threads = threads; } -void ui_server_set_paint_flashing_enabled(LCUI_BOOL enabled) +void ui_server_set_paint_flashing_enabled(bool enabled) { ui_server.paint_flashing_enabled = enabled; } void ui_server_destroy(void) { + ui_cursor_destroy(); app_off_event(APP_EVENT_MINMAXINFO, ui_server_on_window_minmaxinfo); app_off_event(APP_EVENT_SIZE, ui_server_on_window_resize); app_off_event(APP_EVENT_CLOSE, ui_server_on_window_close); diff --git a/lib/ui-server/xmake.lua b/lib/ui-server/xmake.lua new file mode 100644 index 000000000..f31442eab --- /dev/null +++ b/lib/ui-server/xmake.lua @@ -0,0 +1,23 @@ +set_project("libui-server") +set_version("0.1.0-a") +add_requires("libomp", {optional = true}) + +option("with-openmp", {showmenu = true, default = true}) + +target("libui-server") + set_kind("$(kind)") + add_files("src/**.c") + add_packages("libomp") + add_options("with-openmp") + add_deps("yutil", "pandagl", "libplatform", "libui", "libui-cursor") + set_configdir("include/ui_server") + add_configfiles("src/config.h.in") + add_headerfiles("include/ui_server.h", "include/(ui_server/*.h)") + if is_kind("static") then + set_configvar("LIBUI_SERVER_STATIC_BUILD", 1) + elseif is_plat("windows") then + add_defines("LIBUI_SERVER_DLL_EXPORT") + end + if has_package("libomp") and has_config("with-openmp") then + set_configvar("LIBUI_SERVER_HAS_OPENMP", 1) + end diff --git a/lib/ui-widgets/include/ui_widgets.h b/lib/ui-widgets/include/ui_widgets.h index 45be04be2..2e28e05e5 100644 --- a/lib/ui-widgets/include/ui_widgets.h +++ b/lib/ui-widgets/include/ui_widgets.h @@ -1,8 +1,8 @@ - -#include -#include -#include -#include -#include -#include -#include +#include "ui_widgets/common.h" +#include "ui_widgets/textview.h" +#include "ui_widgets/button.h" +#include "ui_widgets/anchor.h" +#include "ui_widgets/canvas.h" +#include "ui_widgets/scrollbar.h" +#include "ui_widgets/textedit.h" +#include "ui_widgets/textcaret.h" diff --git a/lib/ui-widgets/include/ui_widgets/anchor.h b/lib/ui-widgets/include/ui_widgets/anchor.h index 20dd5a595..e1c6550aa 100644 --- a/lib/ui-widgets/include/ui_widgets/anchor.h +++ b/lib/ui-widgets/include/ui_widgets/anchor.h @@ -32,13 +32,17 @@ #ifndef LIB_UI_WIDGETS_INCLUDE_ANCHOR_H #define LIB_UI_WIDGETS_INCLUDE_ANCHOR_H -#include #include +#include "ui_widgets/common.h" -LCUI_API void ui_anchor_open(ui_widget_t* w); +LIBUI_WIDGETS_BEGIN_DECLS -LCUI_API void ui_register_anchor(void); +LIBUI_WIDGETS_PUBLIC void ui_anchor_open(ui_widget_t* w); -LCUI_API void ui_unregister_anchor(void); +LIBUI_WIDGETS_PUBLIC void ui_register_anchor(void); + +LIBUI_WIDGETS_PUBLIC void ui_unregister_anchor(void); + +LIBUI_WIDGETS_END_DECLS #endif diff --git a/lib/ui-widgets/include/ui_widgets/button.h b/lib/ui-widgets/include/ui_widgets/button.h index 8fc932a6b..c85b625bd 100644 --- a/lib/ui-widgets/include/ui_widgets/button.h +++ b/lib/ui-widgets/include/ui_widgets/button.h @@ -31,17 +31,17 @@ #ifndef LIB_UI_WIDGETS_INCLUDE_BUTTON_H #define LIB_UI_WIDGETS_INCLUDE_BUTTON_H -#include #include +#include "ui_widgets/common.h" -LCUI_BEGIN_HEADER +LIBUI_WIDGETS_BEGIN_DECLS -LCUI_API void ui_button_set_text_w(ui_widget_t* w, const wchar_t *wstr); +LIBUI_WIDGETS_PUBLIC void ui_button_set_text_w(ui_widget_t* w, const wchar_t *wstr); -LCUI_API void ui_button_set_text(ui_widget_t* w, const char *str); +LIBUI_WIDGETS_PUBLIC void ui_button_set_text(ui_widget_t* w, const char *str); -LCUI_API void ui_register_button(void); +LIBUI_WIDGETS_PUBLIC void ui_register_button(void); -LCUI_END_HEADER +LIBUI_WIDGETS_END_DECLS #endif diff --git a/lib/ui-widgets/include/ui_widgets/canvas.h b/lib/ui-widgets/include/ui_widgets/canvas.h index 278b5bde9..94ce12a8e 100644 --- a/lib/ui-widgets/include/ui_widgets/canvas.h +++ b/lib/ui-widgets/include/ui_widgets/canvas.h @@ -31,9 +31,10 @@ #ifndef LIB_UI_WIDGETS_INCLUDE_CANVAS_H #define LIB_UI_WIDGETS_INCLUDE_CANVAS_H -#include #include -LCUI_BEGIN_HEADER +#include "ui_widgets/common.h" + +LIBUI_WIDGETS_BEGIN_DECLS /** @see https://developer.mozilla.org/en-US/docs/Web/HTML/Element/canvas#attributes */ @@ -43,7 +44,7 @@ LCUI_BEGIN_HEADER typedef struct ui_canvas_rendering_context_t ui_canvas_context_t; typedef struct ui_canvas_rendering_context_t { - LCUI_BOOL available; + bool available; pd_color_t fill_color; pd_canvas_t buffer; ui_widget_t* canvas; @@ -73,10 +74,10 @@ typedef struct ui_canvas_rendering_context_t { * Get a drawing context on the canvas * Reference: https://developer.mozilla.org/en-US/docs/Web/API/HTMLCanvasElement/getContext */ -LCUI_API ui_canvas_context_t *ui_canvas_get_context(ui_widget_t* w); +LIBUI_WIDGETS_PUBLIC ui_canvas_context_t *ui_canvas_get_context(ui_widget_t* w); -void ui_register_canvas(void); +LIBUI_WIDGETS_PUBLIC void ui_register_canvas(void); -LCUI_END_HEADER +LIBUI_WIDGETS_END_DECLS #endif diff --git a/lib/ui-widgets/include/ui_widgets/common.h b/lib/ui-widgets/include/ui_widgets/common.h new file mode 100644 index 000000000..2d9bc8cb6 --- /dev/null +++ b/lib/ui-widgets/include/ui_widgets/common.h @@ -0,0 +1,22 @@ +#include "config.h" +#ifdef __cplusplus +#define LIBUI_WIDGETS_BEGIN_DECLS extern "C" { +#define LIBUI_WIDGETS_END_DECLS } +#else +#define LIBUI_WIDGETS_BEGIN_DECLS +#define LIBUI_WIDGETS_END_DECLS +#endif + +#ifndef LIBUI_WIDGETS_PUBLIC +#if defined(_MSC_VER) && !defined(LIBUI_WIDGETS_STATIC_BUILD) +#ifdef LIBUI_WIDGETS_DLL_EXPORT +#define LIBUI_WIDGETS_PUBLIC __declspec(dllexport) +#else +#define LIBUI_WIDGETS_PUBLIC __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LIBUI_WIDGETS_PUBLIC extern __attribute__((visibility("default"))) +#else +#define LIBUI_WIDGETS_PUBLIC extern +#endif +#endif diff --git a/lib/ui-widgets/include/ui_widgets/scrollbar.h b/lib/ui-widgets/include/ui_widgets/scrollbar.h index 872f38564..52d21b503 100644 --- a/lib/ui-widgets/include/ui_widgets/scrollbar.h +++ b/lib/ui-widgets/include/ui_widgets/scrollbar.h @@ -31,33 +31,33 @@ #ifndef LIB_UI_WIDGETS_INCLUDE_SCROLLBAR_H #define LIB_UI_WIDGETS_INCLUDE_SCROLLBAR_H -#include #include +#include "ui_widgets/common.h" -LCUI_BEGIN_HEADER +LIBUI_WIDGETS_BEGIN_DECLS typedef enum ui_scrollbar_direction_t { UI_SCROLLBAR_HORIZONTAL, UI_SCROLLBAR_VERTICAL } ui_scrollbar_direction_t; -LCUI_API void ui_scrollbar_bind_container(ui_widget_t* w, +LIBUI_WIDGETS_PUBLIC void ui_scrollbar_bind_container(ui_widget_t* w, ui_widget_t* container); -LCUI_API void ui_scrollbar_bind_target(ui_widget_t* w, ui_widget_t* target); +LIBUI_WIDGETS_PUBLIC void ui_scrollbar_bind_target(ui_widget_t* w, ui_widget_t* target); /** 获取滚动条的位置 */ -LCUI_API float ui_scrollbar_get_position(ui_widget_t* w); +LIBUI_WIDGETS_PUBLIC float ui_scrollbar_get_position(ui_widget_t* w); /** 将与滚动条绑定的内容滚动至指定位置 */ -LCUI_API float ui_scrollbar_set_position(ui_widget_t* w, float pos); +LIBUI_WIDGETS_PUBLIC float ui_scrollbar_set_position(ui_widget_t* w, float pos); /** 设置滚动条的方向 */ -LCUI_API void ui_scrollbar_set_direction(ui_widget_t* w, +LIBUI_WIDGETS_PUBLIC void ui_scrollbar_set_direction(ui_widget_t* w, ui_scrollbar_direction_t direction); -LCUI_API void ui_register_scrollbar(void); +LIBUI_WIDGETS_PUBLIC void ui_register_scrollbar(void); -LCUI_END_HEADER +LIBUI_WIDGETS_END_DECLS #endif diff --git a/lib/ui-widgets/include/ui_widgets/textcaret.h b/lib/ui-widgets/include/ui_widgets/textcaret.h index 2b18a9d2f..80725f9d4 100644 --- a/lib/ui-widgets/include/ui_widgets/textcaret.h +++ b/lib/ui-widgets/include/ui_widgets/textcaret.h @@ -31,16 +31,16 @@ #ifndef LIB_UI_WIDGETS_INCLUDE_TEXTCARET_H #define LIB_UI_WIDGETS_INCLUDE_TEXTCARET_H -#include #include +#include "ui_widgets/common.h" -LCUI_API void ui_textcaret_refresh(ui_widget_t* widget); +LIBUI_WIDGETS_PUBLIC void ui_textcaret_refresh(ui_widget_t* widget); -LCUI_API void ui_textcaret_set_visible(ui_widget_t* widget, LCUI_BOOL visible); +LIBUI_WIDGETS_PUBLIC void ui_textcaret_set_visible(ui_widget_t* widget, bool visible); /** 设置闪烁的时间间隔 */ -LCUI_API void ui_textcaret_set_blink_time(ui_widget_t* widget, unsigned int n_ms); +LIBUI_WIDGETS_PUBLIC void ui_textcaret_set_blink_time(ui_widget_t* widget, unsigned int n_ms); -LCUI_API void ui_register_textcaret(void); +LIBUI_WIDGETS_PUBLIC void ui_register_textcaret(void); #endif diff --git a/lib/ui-widgets/include/ui_widgets/textedit.h b/lib/ui-widgets/include/ui_widgets/textedit.h index 5b6f513a2..c22a8f7a7 100644 --- a/lib/ui-widgets/include/ui_widgets/textedit.h +++ b/lib/ui-widgets/include/ui_widgets/textedit.h @@ -31,52 +31,52 @@ #ifndef LIB_UI_WIDGETS_INCLUDE_TEXTEDIT_H #define LIB_UI_WIDGETS_INCLUDE_TEXTEDIT_H -#include #include +#include "ui_widgets/common.h" -LCUI_BEGIN_HEADER +LIBUI_WIDGETS_BEGIN_DECLS /** Enable style tag parser */ -LCUI_API void ui_textedit_enable_style_tag(ui_widget_t* widget, LCUI_BOOL enable); +LIBUI_WIDGETS_PUBLIC void ui_textedit_enable_style_tag(ui_widget_t* widget, bool enable); -LCUI_API void ui_textedit_enable_multiline(ui_widget_t* widget, LCUI_BOOL enable); +LIBUI_WIDGETS_PUBLIC void ui_textedit_enable_multiline(ui_widget_t* widget, bool enable); -LCUI_API void ui_textedit_move_caret(ui_widget_t* widget, int row, int col); +LIBUI_WIDGETS_PUBLIC void ui_textedit_move_caret(ui_widget_t* widget, int row, int col); /** 清空文本内容 */ -LCUI_API void ui_textedit_clear_text(ui_widget_t* widget); +LIBUI_WIDGETS_PUBLIC void ui_textedit_clear_text(ui_widget_t* widget); /** 获取文本内容 */ -LCUI_API size_t ui_textedit_get_text_w(ui_widget_t* w, size_t start, +LIBUI_WIDGETS_PUBLIC size_t ui_textedit_get_text_w(ui_widget_t* w, size_t start, size_t max_len, wchar_t *buf); /** 获取文本长度 */ -LCUI_API size_t ui_textedit_get_text_length(ui_widget_t* w); +LIBUI_WIDGETS_PUBLIC size_t ui_textedit_get_text_length(ui_widget_t* w); /** 设置文本编辑框内的光标,指定是否闪烁、闪烁时间间隔 */ -LCUI_API void ui_textedit_set_caret_blink(ui_widget_t* w, LCUI_BOOL visible, int time); +LIBUI_WIDGETS_PUBLIC void ui_textedit_set_caret_blink(ui_widget_t* w, bool visible, int time); /** 为文本框设置文本(宽字符版) */ -LCUI_API int ui_textedit_set_text_w(ui_widget_t* widget, const wchar_t *wstr); +LIBUI_WIDGETS_PUBLIC int ui_textedit_set_text_w(ui_widget_t* widget, const wchar_t *wstr); -LCUI_API int ui_textedit_set_text(ui_widget_t* widget, const char *utf8_str); +LIBUI_WIDGETS_PUBLIC int ui_textedit_set_text(ui_widget_t* widget, const char *utf8_str); /** 为文本框追加文本(宽字符版) */ -LCUI_API int ui_textedit_append_text_w(ui_widget_t* widget, const wchar_t *wstr); +LIBUI_WIDGETS_PUBLIC int ui_textedit_append_text_w(ui_widget_t* widget, const wchar_t *wstr); /** 为文本框插入文本(宽字符版) */ -LCUI_API int ui_textedit_insert_text_w(ui_widget_t* widget, const wchar_t *wstr); +LIBUI_WIDGETS_PUBLIC int ui_textedit_insert_text_w(ui_widget_t* widget, const wchar_t *wstr); /** 设置占位符,当文本编辑框内容为空时显示占位符 */ -LCUI_API int ui_textedit_set_placeholder_w(ui_widget_t* w, const wchar_t *wstr); +LIBUI_WIDGETS_PUBLIC int ui_textedit_set_placeholder_w(ui_widget_t* w, const wchar_t *wstr); -LCUI_API int ui_textedit_set_placeholder(ui_widget_t* w, const char *str); +LIBUI_WIDGETS_PUBLIC int ui_textedit_set_placeholder(ui_widget_t* w, const char *str); /** 设置密码屏蔽符 */ -LCUI_API void ui_textedit_set_passworld_char(ui_widget_t* w, wchar_t ch); +LIBUI_WIDGETS_PUBLIC void ui_textedit_set_password_char(ui_widget_t* w, wchar_t ch); -LCUI_API void ui_register_textedit(void); +LIBUI_WIDGETS_PUBLIC void ui_register_textedit(void); -LCUI_END_HEADER +LIBUI_WIDGETS_END_DECLS #endif diff --git a/lib/ui-widgets/include/ui_widgets/textview.h b/lib/ui-widgets/include/ui_widgets/textview.h index f07f52100..3d7c30bfd 100644 --- a/lib/ui-widgets/include/ui_widgets/textview.h +++ b/lib/ui-widgets/include/ui_widgets/textview.h @@ -31,21 +31,24 @@ #ifndef LIB_UI_WIDGETS_INCLUDE_TEXTVIEW_H #define LIB_UI_WIDGETS_INCLUDE_TEXTVIEW_H -#include #include +#include "ui_widgets/common.h" -LCUI_BEGIN_HEADER +LIBUI_WIDGETS_BEGIN_DECLS -LCUI_API int ui_textview_set_text_w(ui_widget_t* w, const wchar_t *text); +LIBUI_WIDGETS_PUBLIC int ui_textview_set_text_w(ui_widget_t *w, + const wchar_t *text); -LCUI_API int ui_textview_set_text(ui_widget_t* w, const char *utf8_text); +LIBUI_WIDGETS_PUBLIC int ui_textview_set_text(ui_widget_t *w, + const char *utf8_text); -LCUI_API void ui_textview_set_multiline(ui_widget_t* w, LCUI_BOOL enable); +LIBUI_WIDGETS_PUBLIC void ui_textview_set_multiline(ui_widget_t *w, + bool enable); -LCUI_API void ui_register_textview(void); +LIBUI_WIDGETS_PUBLIC void ui_register_textview(void); -LCUI_API void ui_unregister_textview(void); +LIBUI_WIDGETS_PUBLIC void ui_unregister_textview(void); -LCUI_END_HEADER +LIBUI_WIDGETS_END_DECLS #endif diff --git a/lib/ui-widgets/src/anchor.c b/lib/ui-widgets/src/anchor.c index 014b9d051..647cd3d39 100644 --- a/lib/ui-widgets/src/anchor.c +++ b/lib/ui-widgets/src/anchor.c @@ -32,200 +32,200 @@ #include #include #include -#include -#include +#include #include -#include +#include #include typedef struct xml_loader_t { - char* key; /**< 键,作为在视图加载完后传给事件处理器的额外参数 */ - char* filepath; /**< 视图文件路径 */ - char* target_id; /**< 目标容器部件的标识 */ - ui_widget_t* pack; /**< 已经加载的视图内容包 */ - ui_widget_t* widget; /**< 触发视图加载器的部件 */ + /** 键,作为在视图加载完后传给事件处理器的额外参数 */ + char* key; + char* filepath; /**< 视图文件路径 */ + char* target_id; /**< 目标容器部件的标识 */ + ui_widget_t* pack; /**< 已经加载的视图内容包 */ + ui_widget_t* widget; /**< 触发视图加载器的部件 */ } xml_loader_t; static struct ui_anchor_module_t { - ui_widget_prototype_t* proto; - LCUI_Worker worker; + ui_widget_prototype_t* proto; + worker_t * worker; } ui_anchor; static void xml_loader_on_widget_destroy(ui_widget_t* w, ui_event_t* e, - void* arg) + void* arg) { - xml_loader_t* loader = e->data; + xml_loader_t* loader = e->data; - loader->widget = NULL; + loader->widget = NULL; } static void xml_loader_destroy(xml_loader_t* loader) { - if (loader->widget) { - ui_widget_off(loader->widget, "destroy", - xml_loader_on_widget_destroy, NULL); - } - if (loader->key) { - free(loader->key); - } - loader->key = NULL; - loader->pack = NULL; - loader->widget = NULL; - free(loader->target_id); - free(loader->filepath); - free(loader); + if (loader->widget) { + ui_widget_off(loader->widget, "destroy", + xml_loader_on_widget_destroy, NULL); + } + if (loader->key) { + free(loader->key); + } + loader->key = NULL; + loader->pack = NULL; + loader->widget = NULL; + free(loader->target_id); + free(loader->filepath); + free(loader); } static xml_loader_t* xml_loader_create(ui_widget_t* w) { - xml_loader_t* loader; - const char* key = ui_widget_get_attribute_value(w, "key"); - - loader = malloc(sizeof(xml_loader_t)); - if (!loader) { - return NULL; - } - loader->widget = w; - loader->filepath = strdup2(ui_widget_get_attribute_value(w, "href")); - loader->target_id = strdup2(ui_widget_get_attribute_value(w, "target")); - ui_widget_on(w, "destroy", xml_loader_on_widget_destroy, loader, NULL); - if (key) { - loader->key = strdup2(key); - } else { - loader->key = NULL; - } - return loader; + xml_loader_t* loader; + const char* key = ui_widget_get_attribute_value(w, "key"); + + loader = malloc(sizeof(xml_loader_t)); + if (!loader) { + return NULL; + } + loader->widget = w; + loader->filepath = strdup2(ui_widget_get_attribute_value(w, "href")); + loader->target_id = strdup2(ui_widget_get_attribute_value(w, "target")); + ui_widget_on(w, "destroy", xml_loader_on_widget_destroy, loader, NULL); + if (key) { + loader->key = strdup2(key); + } else { + loader->key = NULL; + } + return loader; } static void ui_anchor_on_load(ui_widget_t* w, ui_event_t* e, void* arg) { - xml_loader_t* loader = arg; - ui_widget_t *target, *root; - ui_event_t ev = { 0 }; - - target = ui_get_widget(loader->target_id); - if (!target) { - return; - } - root = ui_root(); - ui_widget_append(target, loader->pack); - ui_widget_unwrap(loader->pack); - ui_event_init(&ev, "loaded.anchor"); - ev.cancel_bubble = TRUE; - ev.target = loader->widget; - ui_widget_emit_event(root, ev, loader->key); + xml_loader_t* loader = arg; + ui_widget_t *target, *root; + ui_event_t ev = { 0 }; + + target = ui_get_widget(loader->target_id); + if (!target) { + return; + } + root = ui_root(); + ui_widget_append(target, loader->pack); + ui_widget_unwrap(loader->pack); + ui_event_init(&ev, "loaded.anchor"); + ev.cancel_bubble = TRUE; + ev.target = loader->widget; + ui_widget_emit_event(root, ev, loader->key); } static void xml_loader_load(xml_loader_t* loader) { - ui_widget_t* pack; - ui_event_t e; - char *path, dirname[] = "assets/views/"; - - if (loader->filepath[0] != '/') { - path = malloc((strlen(loader->filepath) + 1) * sizeof(char) + - sizeof(dirname)); - if (!path) { - logger_error("[anchor] out of memory\n"); - xml_loader_destroy(loader); - return; - } - strcpy(path, dirname); - strcat(path, loader->filepath); - pack = ui_load_xml_file(path); - free(path); - } else { - pack = ui_load_xml_file(loader->filepath); - } - if (!pack) { - logger_error("[anchor] href (%s): cannot load xml resource\n", - loader->filepath); - xml_loader_destroy(loader); - return; - } - ui_event_init(&e, "load.anchor"); - e.target = loader->widget; - e.cancel_bubble = TRUE; - loader->pack = pack; - ui_post_event(&e, loader, - (ui_event_arg_destructor_t)xml_loader_destroy); + ui_widget_t* pack; + ui_event_t e; + char *path, dirname[] = "assets/views/"; + + if (loader->filepath[0] != '/') { + path = malloc((strlen(loader->filepath) + 1) * sizeof(char) + + sizeof(dirname)); + if (!path) { + logger_error("[anchor] out of memory\n"); + xml_loader_destroy(loader); + return; + } + strcpy(path, dirname); + strcat(path, loader->filepath); + pack = ui_load_xml_file(path); + free(path); + } else { + pack = ui_load_xml_file(loader->filepath); + } + if (!pack) { + logger_error("[anchor] href (%s): cannot load xml resource\n", + loader->filepath); + xml_loader_destroy(loader); + return; + } + ui_event_init(&e, "load.anchor"); + e.target = loader->widget; + e.cancel_bubble = TRUE; + loader->pack = pack; + ui_post_event(&e, loader, + (ui_event_arg_destructor_t)xml_loader_destroy); } static void ui_anchor_on_startload(ui_widget_t* w, ui_event_t* e, void* arg) { - ui_widget_t* target; - xml_loader_t* loader = arg; - LCUI_TaskRec task = { 0 }; - - target = ui_get_widget(loader->target_id); - if (!target) { - logger_error("[anchor] target (%s): not found\n", - loader->target_id); - xml_loader_destroy(loader); - return; - } - ui_widget_empty(target); - task.arg[0] = loader; - task.func = (LCUI_TaskFunc)xml_loader_load; - LCUIWorker_PostTask(ui_anchor.worker, &task); + ui_widget_t* target; + xml_loader_t* loader = arg; + worker_task_t task = { 0 }; + + target = ui_get_widget(loader->target_id); + if (!target) { + logger_error("[anchor] target (%s): not found\n", + loader->target_id); + xml_loader_destroy(loader); + return; + } + ui_widget_empty(target); + task.arg[0] = loader; + task.callback = (worker_callback_t)xml_loader_load; + worker_post_task(ui_anchor.worker, &task); } void ui_anchor_open(ui_widget_t* w) { - ui_event_t e; - xml_loader_t* loader; - const char* attr_href = ui_widget_get_attribute_value(w, "href"); - - if (!attr_href) { - logger_error("[anchor] href are required\n"); - return; - } - if (strstr(attr_href, "file:") == attr_href) { - open_uri(attr_href + 5); - return; - } - if (strstr(attr_href, "http://") == attr_href || - strstr(attr_href, "https://") == attr_href) { - open_uri(attr_href); - return; - } - loader = xml_loader_create(w); - if (!loader) { - logger_error("[anchor] out of memory\n"); - return; - } - ui_event_init(&e, "startload.anchor"); - e.cancel_bubble = TRUE; - ui_post_event(&e, loader, NULL); + ui_event_t e; + xml_loader_t* loader; + const char* attr_href = ui_widget_get_attribute_value(w, "href"); + + if (!attr_href) { + logger_error("[anchor] href are required\n"); + return; + } + if (strstr(attr_href, "file:") == attr_href) { + open_uri(attr_href + 5); + return; + } + if (strstr(attr_href, "http://") == attr_href || + strstr(attr_href, "https://") == attr_href) { + open_uri(attr_href); + return; + } + loader = xml_loader_create(w); + if (!loader) { + logger_error("[anchor] out of memory\n"); + return; + } + ui_event_init(&e, "startload.anchor"); + e.cancel_bubble = TRUE; + ui_post_event(&e, loader, NULL); } static void ui_anchor_on_click(ui_widget_t* w, ui_event_t* e, void* arg) { - LCUI_TaskRec task = { 0 }; + worker_task_t task = { 0 }; - task.func = (LCUI_TaskFunc)ui_anchor_open; - task.arg[0] = w; - LCUIWorker_PostTask(ui_anchor.worker, &task); + task.callback = (worker_callback_t)ui_anchor_open; + task.arg[0] = w; + worker_post_task(ui_anchor.worker, &task); } static void ui_anchor_on_init(ui_widget_t* w) { - ui_widget_on(w, "click", ui_anchor_on_click, NULL, NULL); - ui_widget_on(w, "startload.anchor", ui_anchor_on_startload, NULL, NULL); - ui_widget_on(w, "load.anchor", ui_anchor_on_load, NULL, NULL); - ui_anchor.proto->proto->init(w); + ui_widget_on(w, "click", ui_anchor_on_click, NULL, NULL); + ui_widget_on(w, "startload.anchor", ui_anchor_on_startload, NULL, NULL); + ui_widget_on(w, "load.anchor", ui_anchor_on_load, NULL, NULL); + ui_anchor.proto->proto->init(w); } void ui_register_anchor(void) { - ui_anchor.proto = ui_create_widget_prototype("a", "textview"); - ui_anchor.proto->init = ui_anchor_on_init; - ui_anchor.worker = LCUIWorker_New(); - LCUIWorker_RunAsync(ui_anchor.worker); + ui_anchor.proto = ui_create_widget_prototype("a", "textview"); + ui_anchor.proto->init = ui_anchor_on_init; + ui_anchor.worker = worker_create(); + worker_run_async(ui_anchor.worker); } void ui_unregister_anchor(void) { - LCUIWorker_Destroy(ui_anchor.worker); - ui_anchor.worker = NULL; + worker_destroy(ui_anchor.worker); + ui_anchor.worker = NULL; } diff --git a/lib/ui-widgets/src/config.h.in b/lib/ui-widgets/src/config.h.in new file mode 100644 index 000000000..ac2b1fc38 --- /dev/null +++ b/lib/ui-widgets/src/config.h.in @@ -0,0 +1,5 @@ +#define LIBUI_WIDGETS_VERSION "${VERSION}" +#define LIBUI_WIDGETS_VERSION_MAJOR ${VERSION_MAJOR} +#define LIBUI_WIDGETS_VERSION_MINOR ${VERSION_MINOR} +#define LIBUI_WIDGETS_VERSION_ALTER ${VERSION_ALTER} +${define LIBUI_WIDGETS_STATIC_BUILD} diff --git a/lib/ui-widgets/src/scrollbar.c b/lib/ui-widgets/src/scrollbar.c index 666f31931..d59c3831b 100644 --- a/lib/ui-widgets/src/scrollbar.c +++ b/lib/ui-widgets/src/scrollbar.c @@ -34,7 +34,7 @@ #include #include #include -#include +#include /* clang-format off */ @@ -49,7 +49,7 @@ typedef struct ui_scroll_effect_t { float speed; /**< 滚动速度 */ float speed_delta; /**< 速度差(加速度) */ int64_t timestamp; /**< 开始时间 */ - LCUI_BOOL is_running; /**< 当前效果是否正在运行 */ + bool is_running; /**< 当前效果是否正在运行 */ } ui_scroll_effect_t; /** 滚动条的相关数据 */ @@ -57,8 +57,8 @@ typedef struct ui_scrollbar_t_ { ui_widget_t *container; ui_widget_t *target; ui_widget_t *thumb; /**< thumb of scrollbar */ - LCUI_BOOL is_dragging; /**< whether the content is dragged */ - LCUI_BOOL is_draggable; /**< whether the content can be dragged */ + bool is_dragging; /**< whether the content is dragged */ + bool is_draggable; /**< whether the content can be dragged */ ui_scrollbar_direction_t direction; /**< 滚动条的方向(垂直或水平) */ float thumb_x, thumb_y; /**< 拖拽开始时的滑块位置 */ float mouse_x, mouse_y; /**< 拖拽开始时的鼠标坐标 */ diff --git a/lib/ui-widgets/src/textcaret.c b/lib/ui-widgets/src/textcaret.c index d90fa30a1..4b3899fa6 100644 --- a/lib/ui-widgets/src/textcaret.c +++ b/lib/ui-widgets/src/textcaret.c @@ -32,12 +32,13 @@ #include #include #include -#include +#include +#include #include #include typedef struct ui_textcaret_task_t { - LCUI_BOOL active; + bool active; ui_widget_t *widget; } ui_textcaret_task_t; @@ -45,7 +46,7 @@ typedef struct ui_textcaret_task_t { typedef struct ui_textcaret_t { int timer_id; int blink_interval; - LCUI_BOOL visible; + bool visible; ui_textcaret_task_t *task; } ui_textcaret_t; @@ -99,7 +100,7 @@ static void ui_textcaret_on_blink(void *arg) } } -void ui_textcaret_set_visible(ui_widget_t *widget, LCUI_BOOL visible) +void ui_textcaret_set_visible(ui_widget_t *widget, bool visible) { ui_textcaret_t *caret; diff --git a/lib/ui-widgets/src/textedit.c b/lib/ui-widgets/src/textedit.c index 2f9a6e48c..d7f31143d 100644 --- a/lib/ui-widgets/src/textedit.c +++ b/lib/ui-widgets/src/textedit.c @@ -31,7 +31,7 @@ #include #include #include -#include +#include #include #include #include @@ -47,21 +47,21 @@ enum task_type_t { TASK_SET_TEXT, TASK_UPDATE, TASK_TOTAL }; typedef struct ui_textedit_t { ui_text_style_t style; /**< 字体样式 */ - pd_text_t* layer_source; /**< 实际文本层 */ - pd_text_t* layer_mask; /**< 屏蔽后的文本层 */ - pd_text_t* layer_placeholder; /**< 占位符的文本层 */ - pd_text_t* layer; /**< 当前使用的文本层 */ - ui_widget_t* scrollbars[2]; /**< 两个滚动条 */ - ui_widget_t* caret; /**< 文本插入符 */ - LCUI_BOOL is_read_only; /**< 是否只读 */ - LCUI_BOOL is_multiline_mode; /**< 是否为多行模式 */ - LCUI_BOOL is_placeholder_shown; /**< 是否已经显示占位符 */ - wchar_t* allow_input_char; /**< 允许输入的字符 */ + pd_text_t *layer_source; /**< 实际文本层 */ + pd_text_t *layer_mask; /**< 屏蔽后的文本层 */ + pd_text_t *layer_placeholder; /**< 占位符的文本层 */ + pd_text_t *layer; /**< 当前使用的文本层 */ + ui_widget_t *scrollbars[2]; /**< 两个滚动条 */ + ui_widget_t *caret; /**< 文本插入符 */ + bool is_read_only; /**< 是否只读 */ + bool is_multiline_mode; /**< 是否为多行模式 */ + bool is_placeholder_shown; /**< 是否已经显示占位符 */ + wchar_t *allow_input_char; /**< 允许输入的字符 */ wchar_t password_char; /**< 屏蔽符的副本 */ size_t text_block_size; /**< 块大小 */ list_t text_blocks; /**< 文本块缓冲区 */ list_t text_tags; /**< 当前处理的标签列表 */ - LCUI_BOOL tasks[TASK_TOTAL]; /**< 待处理的任务 */ + bool tasks[TASK_TOTAL]; /**< 待处理的任务 */ thread_mutex_t mutex; /**< 互斥锁 */ } ui_textedit_t; @@ -86,11 +86,11 @@ typedef struct textblock_t { textblock_type_t type; /**< 文本块类型 */ textblock_owner_t owner; /**< 所属的文本层 */ textblock_action_t action; /**< 指定该文本块的添加方式 */ - wchar_t* text; /**< 文本块(段) */ + wchar_t *text; /**< 文本块(段) */ size_t length; /**< 文本块的长度 */ } textblock_t; -static ui_widget_prototype_t* ui_textedit_proto; +static ui_widget_prototype_t *ui_textedit_proto; static const char *ui_textedit_css = css_string( @@ -113,19 +113,19 @@ textedit:disabled { ); -static void fillchar(wchar_t* str, wchar_t ch) +static void fillchar(wchar_t *str, wchar_t ch) { if (str) { - wchar_t* p; + wchar_t *p; for (p = str; *p; ++p) { *p = ch; } } } -static void ui_textedit_update_caret(ui_widget_t* widget) +static void ui_textedit_update_caret(ui_widget_t *widget) { - ui_textedit_t* edit = ui_widget_get_data(widget, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(widget, ui_textedit_proto); int row = edit->layer->insert_y; int offset_x, offset_y; @@ -187,9 +187,9 @@ static void ui_textedit_update_caret(ui_widget_t* widget) } } -void ui_textedit_move_caret(ui_widget_t* widget, int row, int col) +void ui_textedit_move_caret(ui_widget_t *widget, int row, int col) { - ui_textedit_t* edit = ui_widget_get_data(widget, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(widget, ui_textedit_proto); if (edit->is_placeholder_shown) { row = col = 0; } @@ -197,20 +197,20 @@ void ui_textedit_move_caret(ui_widget_t* widget, int row, int col) ui_textedit_update_caret(widget); } -static void textblock_destroy(textblock_t* blk) +static void textblock_destroy(textblock_t *blk) { free(blk->text); blk->text = NULL; free(blk); } -static int ui_textedit_add_textblock(ui_widget_t* widget, const wchar_t* wtext, +static int ui_textedit_add_textblock(ui_widget_t *widget, const wchar_t *wtext, textblock_action_t action, textblock_owner_t owner) { - const wchar_t* p; - ui_textedit_t* edit; - textblock_t* block; + const wchar_t *p; + ui_textedit_t *edit; + textblock_t *block; size_t i, j, len, tag_len, size; if (!wtext) { @@ -250,7 +250,7 @@ static int ui_textedit_add_textblock(ui_widget_t* widget, const wchar_t* wtext, continue; } for (j = 0; i < len && j < size - 1; ++j, ++i) { - wchar_t* text; + wchar_t *text; block->text[j] = wtext[i]; /* 检测是否有样式标签 */ p = pd_scan_style_open_tag(wtext + i, NULL, 0, NULL); @@ -286,11 +286,11 @@ static int ui_textedit_add_textblock(ui_widget_t* widget, const wchar_t* wtext, } /** 更新文本框内的字体位图 */ -static void TextEdit_ProcTextBlock(ui_widget_t* widget, textblock_t* txtblk) +static void TextEdit_ProcTextBlock(ui_widget_t *widget, textblock_t *txtblk) { - list_t* tags; - ui_textedit_t* edit; - pd_text_t* layer; + list_t *tags; + ui_textedit_t *edit; + pd_text_t *layer; edit = ui_widget_get_data(widget, ui_textedit_proto); switch (txtblk->owner) { @@ -317,7 +317,7 @@ static void TextEdit_ProcTextBlock(ui_widget_t* widget, textblock_t* txtblk) break; } if (edit->password_char && txtblk->owner == TEXTBLOCK_OWNER_SOURCE) { - wchar_t* text = malloc(sizeof(wchar_t) * txtblk->length + 1); + wchar_t *text = malloc(sizeof(wchar_t) * txtblk->length + 1); wcsncpy(text, txtblk->text, txtblk->length + 1); fillchar(text, edit->password_char); layer = edit->layer_mask; @@ -331,14 +331,14 @@ static void TextEdit_ProcTextBlock(ui_widget_t* widget, textblock_t* txtblk) } /** 更新文本框的文本图层 */ -static void TextEdit_UpdateTextLayer(ui_widget_t* w) +static void TextEdit_UpdateTextLayer(ui_widget_t *w) { float scale; list_t rects; ui_rect_t rect; - ui_textedit_t* edit; + ui_textedit_t *edit; pd_text_style_t style; - list_node_t* node; + list_node_t *node; list_create(&rects); scale = ui_metrics.scale; @@ -359,13 +359,13 @@ static void TextEdit_UpdateTextLayer(ui_widget_t* w) pd_rects_clear(&rects); } -static void ui_textedit_on_task(ui_widget_t* widget, int task) +static void ui_textedit_on_task(ui_widget_t *widget, int task) { - ui_textedit_t* edit = ui_widget_get_data(widget, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(widget, ui_textedit_proto); if (edit->tasks[TASK_SET_TEXT]) { list_t blocks; - list_node_t* node; + list_node_t *node; ui_event_t ev; list_create(&blocks); @@ -383,7 +383,7 @@ static void ui_textedit_on_task(ui_widget_t* widget, int task) edit->tasks[TASK_UPDATE] = TRUE; } if (edit->tasks[TASK_UPDATE]) { - LCUI_BOOL is_shown; + bool is_shown; is_shown = edit->layer_source->length == 0; if (is_shown) { edit->layer = edit->layer_placeholder; @@ -403,15 +403,15 @@ static void ui_textedit_on_task(ui_widget_t* widget, int task) } } -static void ui_textedit_on_resize(ui_widget_t* w, float width, float height) +static void ui_textedit_on_resize(ui_widget_t *w, float width, float height) { float scale = ui_metrics.scale; list_t rects; - list_node_t* node; + list_node_t *node; ui_rect_t rect; - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); list_create(&rects); pd_text_set_fixed_size(edit->layer, (int)(width * scale), @@ -426,14 +426,14 @@ static void ui_textedit_on_resize(ui_widget_t* w, float width, float height) pd_rects_clear(&rects); } -static void ui_textedit_on_auto_size(ui_widget_t* w, float* width, - float* height, ui_layout_rule_t rule) +static void ui_textedit_on_auto_size(ui_widget_t *w, float *width, + float *height, ui_layout_rule_t rule) { int i, n; int max_width = 0, max_height = 0; float scale = ui_metrics.scale; - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); switch (rule) { case UI_LAYOUT_RULE_FIXED_WIDTH: @@ -473,9 +473,9 @@ static void ui_textedit_on_auto_size(ui_widget_t* w, float* width, *width = max_width / scale; } -void ui_textedit_enable_style_tag(ui_widget_t* widget, LCUI_BOOL enable) +void ui_textedit_enable_style_tag(ui_widget_t *widget, bool enable) { - ui_textedit_t* edit = ui_widget_get_data(widget, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(widget, ui_textedit_proto); pd_text_set_style_tag(edit->layer, enable); } @@ -484,7 +484,7 @@ void ui_textedit_enable_style_tag(ui_widget_t* widget, LCUI_BOOL enable) * tested, it may have many problems. */ -void ui_textedit_enable_multiline(ui_widget_t* w, LCUI_BOOL enable) +void ui_textedit_enable_multiline(ui_widget_t *w, bool enable) { if (enable) { ui_widget_set_style_keyword_value(w, css_key_white_space, @@ -495,10 +495,10 @@ void ui_textedit_enable_multiline(ui_widget_t* w, LCUI_BOOL enable) } } -void ui_textedit_clear_text(ui_widget_t* widget) +void ui_textedit_clear_text(ui_widget_t *widget) { - ui_textedit_t* edit; - textblock_t* block; + ui_textedit_t *edit; + textblock_t *block; list_node_t *node, *prev; edit = ui_widget_get_data(widget, ui_textedit_proto); @@ -520,31 +520,31 @@ void ui_textedit_clear_text(ui_widget_t* widget) ui_widget_mark_dirty_rect(widget, NULL, UI_BOX_TYPE_PADDING_BOX); } -size_t ui_textedit_get_text_w(ui_widget_t* w, size_t start, size_t max_len, - wchar_t* buf) +size_t ui_textedit_get_text_w(ui_widget_t *w, size_t start, size_t max_len, + wchar_t *buf) { - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); return pd_text_dump(edit->layer_source, start, max_len, buf); } -size_t ui_textedit_get_text_length(ui_widget_t* w) +size_t ui_textedit_get_text_length(ui_widget_t *w) { - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); return edit->layer_source->length; } -int ui_textedit_set_text_w(ui_widget_t* w, const wchar_t* wstr) +int ui_textedit_set_text_w(ui_widget_t *w, const wchar_t *wstr) { ui_textedit_clear_text(w); return ui_textedit_add_textblock(w, wstr, TEXTBLOCK_ACTION_APPEND, TEXTBLOCK_OWNER_SOURCE); } -int ui_textedit_set_text(ui_widget_t* widget, const char* utf8_str) +int ui_textedit_set_text(ui_widget_t *widget, const char* utf8_str) { int ret; size_t len = strlen(utf8_str) + 1; - wchar_t* wstr = malloc(len * sizeof(wchar_t)); + wchar_t *wstr = malloc(len * sizeof(wchar_t)); if (!wstr) { return -ENOMEM; @@ -556,11 +556,11 @@ int ui_textedit_set_text(ui_widget_t* widget, const char* utf8_str) return ret; } -void ui_textedit_set_passworld_char(ui_widget_t* w, wchar_t ch) +void ui_textedit_set_password_char(ui_widget_t *w, wchar_t ch) { size_t i, len; wchar_t text[256]; - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); edit->password_char = ch; edit->tasks[TASK_UPDATE] = TRUE; @@ -579,21 +579,21 @@ void ui_textedit_set_passworld_char(ui_widget_t* w, wchar_t ch) } } -int ui_textedit_append_text_w(ui_widget_t* w, const wchar_t* wstr) +int ui_textedit_append_text_w(ui_widget_t *w, const wchar_t *wstr) { return ui_textedit_add_textblock(w, wstr, TEXTBLOCK_ACTION_APPEND, TEXTBLOCK_OWNER_SOURCE); } -int ui_textedit_insert_text_w(ui_widget_t* w, const wchar_t* wstr) +int ui_textedit_insert_text_w(ui_widget_t *w, const wchar_t *wstr) { return ui_textedit_add_textblock(w, wstr, TEXTBLOCK_ACTION_INSERT, TEXTBLOCK_OWNER_SOURCE); } -int ui_textedit_set_placeholder_w(ui_widget_t* w, const wchar_t* wstr) +int ui_textedit_set_placeholder_w(ui_widget_t *w, const wchar_t *wstr) { - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); thread_mutex_lock(&edit->mutex); pd_text_empty(edit->layer_placeholder); thread_mutex_unlock(&edit->mutex); @@ -604,11 +604,11 @@ int ui_textedit_set_placeholder_w(ui_widget_t* w, const wchar_t* wstr) TEXTBLOCK_OWNER_PLACEHOLDER); } -int ui_textedit_set_placeholder(ui_widget_t* w, const char* str) +int ui_textedit_set_placeholder(ui_widget_t *w, const char* str) { int ret; size_t len = strlen(str) + 1; - wchar_t* wstr = malloc(len * sizeof(wchar_t)); + wchar_t *wstr = malloc(len * sizeof(wchar_t)); if (!wstr) { return -ENOMEM; @@ -620,30 +620,30 @@ int ui_textedit_set_placeholder(ui_widget_t* w, const char* str) return ret; } -void ui_textedit_set_caret_blink(ui_widget_t* w, LCUI_BOOL visible, int time) +void ui_textedit_set_caret_blink(ui_widget_t *w, bool visible, int time) { - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); ui_textcaret_set_visible(edit->caret, visible); ui_textcaret_set_blink_time(edit->caret, time); } -static void ui_textedit_on_parse_text(ui_widget_t* w, const char* text) +static void ui_textedit_on_parse_text(ui_widget_t *w, const char* text) { ui_textedit_set_text(w, text); } -static void ui_textedit_on_focus(ui_widget_t* widget, ui_event_t* e, void* arg) +static void ui_textedit_on_focus(ui_widget_t *widget, ui_event_t *e, void* arg) { - ui_textedit_t* edit; + ui_textedit_t *edit; edit = ui_widget_get_data(widget, ui_textedit_proto); ui_textcaret_set_visible(edit->caret, TRUE); ui_textedit_update_caret(widget); } -static void ui_textedit_on_blur(ui_widget_t* widget, ui_event_t* e, void* arg) +static void ui_textedit_on_blur(ui_widget_t *widget, ui_event_t *e, void* arg) { - ui_textedit_t* edit; + ui_textedit_t *edit; edit = ui_widget_get_data(widget, ui_textedit_proto); ui_textcaret_set_visible(edit->caret, FALSE); @@ -655,9 +655,9 @@ static void ui_textedit_on_blur(ui_widget_t* widget, ui_event_t* e, void* arg) } } -static void ui_textedit_on_press_backspace_key(ui_widget_t* widget, int n_ch) +static void ui_textedit_on_press_backspace_key(ui_widget_t *widget, int n_ch) { - ui_textedit_t* edit; + ui_textedit_t *edit; ui_event_t ev; edit = ui_widget_get_data(widget, ui_textedit_proto); @@ -674,9 +674,9 @@ static void ui_textedit_on_press_backspace_key(ui_widget_t* widget, int n_ch) ui_widget_emit_event(widget, ev, NULL); } -static void ui_textedit_on_press_delete_key(ui_widget_t* widget, int n_ch) +static void ui_textedit_on_press_delete_key(ui_widget_t *widget, int n_ch) { - ui_textedit_t* edit; + ui_textedit_t *edit; ui_event_t ev; edit = ui_widget_get_data(widget, ui_textedit_proto); @@ -693,17 +693,17 @@ static void ui_textedit_on_press_delete_key(ui_widget_t* widget, int n_ch) ui_widget_emit_event(widget, ev, NULL); } -static void ui_textedit_on_paste(ui_widget_t* w, ui_event_t* e, void* arg) +static void ui_textedit_on_paste(ui_widget_t *w, ui_event_t *e, void* arg) { - clipboard_t* clipboard = arg; + clipboard_t *clipboard = arg; if (clipboard) { ui_textedit_insert_text_w(w, clipboard->text); } } -static void ui_textedit_on_clipboard_ready(void* arg, ui_widget_t* widget) +static void ui_textedit_on_clipboard_ready(void* arg, ui_widget_t *widget) { - clipboard_t* clipboard = arg; + clipboard_t *clipboard = arg; ui_event_t e = { 0 }; ui_event_init(&e, "paste"); @@ -711,12 +711,12 @@ static void ui_textedit_on_clipboard_ready(void* arg, ui_widget_t* widget) } /** 处理按键事件 */ -static void ui_textedit_on_keydown(ui_widget_t* widget, ui_event_t* e, +static void ui_textedit_on_keydown(ui_widget_t *widget, ui_event_t *e, void* arg) { int cols, rows; int cur_col, cur_row; - ui_textedit_t* edit = ui_widget_get_data(widget, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(widget, ui_textedit_proto); cur_row = edit->layer->insert_y; cur_col = edit->layer->insert_x; @@ -780,7 +780,7 @@ static void ui_textedit_on_keydown(ui_widget_t* widget, ui_event_t* e, // Currently copies internal widget text // once selection is implemented, it would copy that instead size_t len = ui_textedit_get_text_length(widget); - wchar_t* wcs = malloc((len + 1) * sizeof(wchar_t)); + wchar_t *wcs = malloc((len + 1) * sizeof(wchar_t)); ui_textedit_get_text_w(widget, 0, len, wcs); clipboard_set_text(wcs, len); free(wcs); @@ -788,12 +788,12 @@ static void ui_textedit_on_keydown(ui_widget_t* widget, ui_event_t* e, } /** 处理输入法对文本框输入的内容 */ -static void ui_textedit_on_textinput(ui_widget_t* widget, ui_event_t* e, +static void ui_textedit_on_textinput(ui_widget_t *widget, ui_event_t *e, void* arg) { unsigned i, j, k; wchar_t ch, *text, excludes[8] = L"\b\r\t\x1b"; - ui_textedit_t* edit = ui_widget_get_data(widget, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(widget, ui_textedit_proto); /* 如果不是多行文本编辑模式则删除换行符 */ if (!edit->is_multiline_mode) { @@ -839,10 +839,10 @@ static void ui_textedit_on_textinput(ui_widget_t* widget, ui_event_t* e, free(text); } -static void ui_textedit_on_mousemove(ui_widget_t* w, ui_event_t* e, void* arg) +static void ui_textedit_on_mousemove(ui_widget_t *w, ui_event_t *e, void* arg) { float offset_x, offset_y; - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); if (edit->is_placeholder_shown) { ui_textedit_update_caret(w); @@ -856,16 +856,16 @@ static void ui_textedit_on_mousemove(ui_widget_t* w, ui_event_t* e, void* arg) ui_textedit_update_caret(w); } -static void ui_textedit_on_mouseup(ui_widget_t* w, ui_event_t* e, void* arg) +static void ui_textedit_on_mouseup(ui_widget_t *w, ui_event_t *e, void* arg) { ui_widget_release_mouse_capture(w); ui_widget_off(w, "mousemove", ui_textedit_on_mousemove, w); } -static void ui_textedit_on_mousedown(ui_widget_t* w, ui_event_t* e, void* arg) +static void ui_textedit_on_mousedown(ui_widget_t *w, ui_event_t *e, void* arg) { float offset_x, offset_y; - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); ui_widget_get_offset(w, NULL, &offset_x, &offset_y); pd_text_set_insert_pixel_position( @@ -874,15 +874,15 @@ static void ui_textedit_on_mousedown(ui_widget_t* w, ui_event_t* e, void* arg) ui_compute(e->mouse.y - offset_y - w->computed_style.padding_top)); ui_textedit_update_caret(w); ui_widget_set_mouse_capture(w); - ui_widget_on(w, "mousemove", ui_textedit_on_mousemove, NULL, NULL); + ui_widget_on(w, "mousemove", ui_textedit_on_mousemove, w, NULL); } -static void ui_textedit_on_ready(ui_widget_t* w, ui_event_t* e, void* arg) +static void ui_textedit_on_ready(ui_widget_t *w, ui_event_t *e, void* arg) { ui_textedit_update_caret(w); } -static void ui_textedit_on_set_attr(ui_widget_t* w, const char* name, +static void ui_textedit_on_set_attr(ui_widget_t *w, const char* name, const char* val) { if (strcmp(name, "placeholder") == 0) { @@ -890,9 +890,9 @@ static void ui_textedit_on_set_attr(ui_widget_t* w, const char* name, } } -static void ui_textedit_on_init(ui_widget_t* w) +static void ui_textedit_on_init(ui_widget_t *w) { - ui_textedit_t* edit; + ui_textedit_t *edit; edit = ui_widget_add_data(w, ui_textedit_proto, sizeof(ui_textedit_t)); edit->is_read_only = FALSE; @@ -928,9 +928,9 @@ static void ui_textedit_on_init(ui_widget_t* w) ui_text_style_init(&edit->style); } -static void ui_textedit_on_destroy(ui_widget_t* widget) +static void ui_textedit_on_destroy(ui_widget_t *widget) { - ui_textedit_t* edit = ui_widget_get_data(widget, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(widget, ui_textedit_proto); edit->layer = NULL; pd_text_destroy(edit->layer_source); @@ -942,13 +942,13 @@ static void ui_textedit_on_destroy(ui_widget_t* widget) (list_item_destructor_t)textblock_destroy); } -static void ui_textedit_on_paint(ui_widget_t* w, pd_context_t* paint, - ui_widget_actual_style_t* style) +static void ui_textedit_on_paint(ui_widget_t *w, pd_context_t *paint, + ui_widget_actual_style_t *style) { pd_pos_t pos; pd_canvas_t canvas; pd_rect_t content_rect, rect; - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); content_rect.width = style->content_box.width; content_rect.height = style->content_box.height; @@ -968,14 +968,14 @@ static void ui_textedit_on_paint(ui_widget_t* w, pd_context_t* paint, pd_text_render_to(edit->layer, rect, pos, &canvas); } -static void ui_textedit_on_update_style(ui_widget_t* w) +static void ui_textedit_on_update_style(ui_widget_t *w) { int i; - ui_textedit_t* edit = ui_widget_get_data(w, ui_textedit_proto); + ui_textedit_t *edit = ui_widget_get_data(w, ui_textedit_proto); pd_text_style_t text_style; ui_text_style_t style; - pd_text_t* layers[3] = { edit->layer_mask, edit->layer_placeholder, + pd_text_t *layers[3] = { edit->layer_mask, edit->layer_placeholder, edit->layer_source }; ui_text_style_init(&style); diff --git a/lib/ui-widgets/src/textview.c b/lib/ui-widgets/src/textview.c index 35662b70a..32be1952f 100644 --- a/lib/ui-widgets/src/textview.c +++ b/lib/ui-widgets/src/textview.c @@ -39,12 +39,12 @@ typedef struct ui_textview_task_t { wchar_t *content; - LCUI_BOOL update_content; + bool update_content; } ui_textview_task_t; typedef struct ui_textview_t_ { wchar_t *content; - LCUI_BOOL trimming; + bool trimming; ui_widget_t *widget; pd_text_t *layer; ui_text_style_t style; @@ -57,7 +57,7 @@ static struct ui_textview_module_t { ui_widget_prototype_t *prototype; } ui_textview; -static LCUI_BOOL parse_boolean(const char *str) +static bool parse_boolean(const char *str) { if (strcmp(str, "on") == 0 && strcmp(str, "true") == 0 && strcmp(str, "yes") == 0 && strcmp(str, "1") == 0) { @@ -79,7 +79,7 @@ static void ui_textview_on_parse_attr(ui_widget_t *w, const char *name, return; } if (strcmp(name, "multiline") == 0) { - LCUI_BOOL enable = parse_boolean(value); + bool enable = parse_boolean(value); if (enable != txt->layer->mulitiline_enabled) { ui_textview_set_multiline(w, enable); } @@ -322,7 +322,7 @@ int ui_textview_set_text(ui_widget_t *w, const char *utf8_text) return ret; } -void ui_textview_set_multiline(ui_widget_t *w, LCUI_BOOL enable) +void ui_textview_set_multiline(ui_widget_t *w, bool enable) { ui_textview_t *txt = ui_widget_get_data(w, ui_textview.prototype); diff --git a/lib/ui-widgets/xmake.lua b/lib/ui-widgets/xmake.lua new file mode 100644 index 000000000..e4f295f82 --- /dev/null +++ b/lib/ui-widgets/xmake.lua @@ -0,0 +1,15 @@ +set_project("libui-widgets") +set_version("0.1.0-a") + +target("libui-widgets") + set_kind("$(kind)") + add_files("src/**.c") + add_deps("yutil", "libcss", "pandagl", "libthread", "libui", "libui-xml", "libworker", "libplatform", "libtimer") + set_configdir("include/ui_widgets") + add_configfiles("src/config.h.in") + add_headerfiles("include/ui_widgets.h", "include/(ui_widgets/*.h)") + if is_kind("static") then + set_configvar("LIBUI_WIDGETS_STATIC_BUILD", 1) + elseif is_plat("windows") then + add_defines("LIBUI_WIDGETS_DLL_EXPORT") + end diff --git a/lib/ui-builder/include/ui_builder.h b/lib/ui-xml/include/ui_xml.h similarity index 85% rename from lib/ui-builder/include/ui_builder.h rename to lib/ui-xml/include/ui_xml.h index d2b548ed5..24e406efa 100644 --- a/lib/ui-builder/include/ui_builder.h +++ b/lib/ui-xml/include/ui_xml.h @@ -1,5 +1,5 @@ /* *************************************************************************** - * builder.h -- The GUI build module, parse UI config code and build UI. + * XML.h -- The GUI build module, parse UI config code and build UI. * * Copyright (c) 2018-2022, Liu chao All rights reserved. * @@ -28,28 +28,28 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LIB_UI_BUILDER_INCLUDE_BUILDER_H -#define LIB_UI_BUILDER_INCLUDE_BUILDER_H +#ifndef LIB_UI_XML_INCLUDE_XML_H +#define LIB_UI_XML_INCLUDE_XML_H -#include +#include "ui_xml/common.h" #include -LCUI_BEGIN_HEADER +LIBUI_XML_BEGIN_DECLS /** * 从字符串中载入界面配置代码,解析并生成相应的图形界面(元素) * @param[in] str 包含界面配置代码的字符串 * @return 正常解析会返回一个部件,出现错误则返回 NULL */ -LCUI_API ui_widget_t* ui_load_xml_string(const char *str, int size); +LIBUI_XML_PUBLIC ui_widget_t* ui_load_xml_string(const char *str, int size); /** * 从文件中载入界面配置代码,解析并生成相应的图形界面(元素) * @param[in] filepath 文件路径 * @return 正常解析会返回一个部件,出现错误则返回 NULL */ -LCUI_API ui_widget_t* ui_load_xml_file(const char *filepath); +LIBUI_XML_PUBLIC ui_widget_t* ui_load_xml_file(const char *filepath); -LCUI_END_HEADER +LIBUI_XML_END_DECLS #endif diff --git a/lib/ui-xml/include/ui_xml/common.h b/lib/ui-xml/include/ui_xml/common.h new file mode 100644 index 000000000..c58d79a71 --- /dev/null +++ b/lib/ui-xml/include/ui_xml/common.h @@ -0,0 +1,22 @@ +#include "config.h" +#ifdef __cplusplus +#define LIBUI_XML_BEGIN_DECLS extern "C" { +#define LIBUI_XML_END_DECLS } +#else +#define LIBUI_XML_BEGIN_DECLS +#define LIBUI_XML_END_DECLS +#endif + +#ifndef LIBUI_XML_PUBLIC +#if defined(_MSC_VER) && !defined(LIBUI_XML_STATIC_BUILD) +#ifdef LIBUI_XML_DLL_EXPORT +#define LIBUI_XML_PUBLIC __declspec(dllexport) +#else +#define LIBUI_XML_PUBLIC __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LIBUI_XML_PUBLIC extern __attribute__((visibility("default"))) +#else +#define LIBUI_XML_PUBLIC extern +#endif +#endif diff --git a/lib/ui-xml/src/config.h.in b/lib/ui-xml/src/config.h.in new file mode 100644 index 000000000..3aac61f45 --- /dev/null +++ b/lib/ui-xml/src/config.h.in @@ -0,0 +1,6 @@ +#define LIBUI_XML_VERSION "${VERSION}" +#define LIBUI_XML_VERSION_MAJOR ${VERSION_MAJOR} +#define LIBUI_XML_VERSION_MINOR ${VERSION_MINOR} +#define LIBUI_XML_VERSION_ALTER ${VERSION_ALTER} +${define LIBUI_XML_STATIC_BUILD} +${define LIBUI_XML_HAS_LIBXML2} diff --git a/lib/ui-xml/src/ui_xml.c b/lib/ui-xml/src/ui_xml.c new file mode 100644 index 000000000..f3122c145 --- /dev/null +++ b/lib/ui-xml/src/ui_xml.c @@ -0,0 +1,381 @@ +/* *************************************************************************** + * builder.c -- the GUI build module, parse UI config code and build UI. + * + * Copyright (c) 2018-2022, Liu chao All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * * Neither the name of LCUI nor the names of its contributors may be used + * to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + */ + +#include +#include +#include +#include +#include +#include + +#define WARN_TXT "[builder] warning: this module is not enabled before build.\n" + +#ifdef LIBUI_XML_HAS_LIBXML2 +#include +#include + +#define check_prop_name(PROP, NAME) \ + (xmlStrcasecmp(PROP->name, (xmlChar *)NAME) == 0) + +enum ui_xml_parser_id { ID_ROOT, ID_UI, ID_WIDGET, ID_RESOURCE }; + +/** 解析器行为,用于决定解析器在解析完元素后的行为 */ +enum ParserBehavior { + PB_ERROR, /**< 给出错误提示 */ + PB_WARNING, /**< 给出警告提示 */ + PB_NEXT, /**< 处理下个元素 */ + PB_ENTER /**< 进入子元素列表 */ +}; + +typedef struct xml_parser_t xml_parser_t; +typedef int (*xml_parser_method_t)(xml_parser_t *, xmlNodePtr); + +typedef struct xml_node_parser_t { + int id; + const char *name; + xml_parser_method_t parse; +} xml_node_parser_t; + +struct xml_parser_t { + int id; + ui_widget_t *root; + ui_widget_t *widget; + ui_widget_t *parent_widget; + const ui_widget_prototype_t *widget_proto; + xml_node_parser_t *parent_parser; + const char *space; +}; + +#define EXIT(CODE) \ + code = CODE; \ + goto exit; + +static void xmlPrintErrorMessage(xmlErrorPtr err) +{ + logger_error("[builder] %s (%d): error %d: %s\n", + err->file ? err->file : "(memory)", err->line, err->code, + err->message); +} + +/** 解析 元素,根据相关参数载入资源 */ +static int ui_builder_parse_resource_node(xml_parser_t *parser, xmlNodePtr node) +{ + xmlAttrPtr prop; + + int code = PB_NEXT; + char *prop_val, *type = NULL, *src = NULL; + + if (node->type != XML_ELEMENT_NODE) { + return PB_NEXT; + } + prop = node->properties; + while (prop) { + prop_val = (char *)xmlGetProp(node, prop->name); + if (check_prop_name(prop, "type")) { + type = prop_val; + } else if (check_prop_name(prop, "src")) { + src = prop_val; + } else { + xmlFree(prop_val); + } + prop = prop->next; + } + if (!type && !src) { + return PB_WARNING; + } + if (strstr(type, "application/font-")) { + if (pd_font_library_load_file(src) < 1) { + EXIT(PB_WARNING); + } + } else if (strcmp(type, "text/css") == 0) { + if (src) { + if (ui_load_css_file(src) != 0) { + EXIT(PB_WARNING); + } + } + for (node = node->children; node; node = node->next) { + if (node->type != XML_TEXT_NODE) { + continue; + } + ui_load_css_string((char *)node->content, + parser->space); + } + } else if (strcmp(type, "text/xml") == 0) { + ui_widget_t *pack; + if (!src) { + EXIT(PB_WARNING); + } + pack = ui_load_xml_file(src); + if (!pack) { + EXIT(PB_WARNING); + } + if (parser->parent_widget) { + ui_widget_append(parser->parent_widget, pack); + } else if (parser->root) { + ui_widget_append(parser->root, pack); + } else { + ui_widget_remove(pack); + EXIT(PB_WARNING); + } + ui_widget_unwrap(pack); + } +exit: + if (src) { + xmlFree(src); + } + if (type) { + xmlFree(type); + } + return code; +} + +/** 解析 元素,主要作用是创建一个容纳全部部件的根级部件 */ +static int ui_builder_parse_ui_node(xml_parser_t *parser, xmlNodePtr node) +{ + if (node->type != XML_ELEMENT_NODE) { + return PB_NEXT; + } + if (parser->parent_parser && parser->parent_parser->id != ID_ROOT) { + return PB_ERROR; + } + parser->widget = ui_create_widget(NULL); + parser->root = parser->widget; + return PB_ENTER; +} + +/** 解析 元素数据 */ +static int ui_builder_parse_widget_node(xml_parser_t *parser, xmlNodePtr node) +{ + xmlAttrPtr prop; + char *prop_val = NULL, *prop_name, *type = NULL; + ui_widget_t *w = NULL, *parent = parser->widget; + + if (parser->parent_parser && parser->parent_parser->id != ID_UI && + parser->parent_parser->id != ID_WIDGET) { + return PB_ERROR; + } + switch (node->type) { + case XML_ELEMENT_NODE: + break; + case XML_TEXT_NODE: + ui_widget_set_text(parent, (char *)node->content); + DEBUG_MSG("widget: %s, set text: %s\n", parent->type, + (char *)node->content); + return PB_NEXT; + default: + return PB_ERROR; + } + if (parser->widget_proto) { + w = ui_create_widget_with_prototype(parser->widget_proto); + } else { + for (prop = node->properties; prop; prop = prop->next) { + prop_val = (char *)xmlGetProp(node, prop->name); + if (check_prop_name(prop, "type")) { + type = prop_val; + break; + } + if (prop_val) { + xmlFree(prop_val); + } + } + w = ui_create_widget(type); + if (type) { + xmlFree(type); + } + } + if (!w) { + return PB_ERROR; + } + DEBUG_MSG("create widget: %s\n", w->type); + ui_widget_append(parent, w); + parser->widget = w; + for (prop = node->properties; prop; prop = prop->next) { + prop_val = (char *)xmlGetProp(node, prop->name); + if (check_prop_name(prop, "id")) { + DEBUG_MSG("widget: %p, set id: %s\n", w, prop_val); + ui_widget_set_id(w, prop_val); + } else if (check_prop_name(prop, "class")) { + DEBUG_MSG("widget: %p, add class: %s\n", w, prop_val); + ui_widget_add_class(w, prop_val); + } else { + prop_name = strdup2((const char *)prop->name); + strtolower(prop_name, (const char *)prop->name); + ui_widget_set_attribute(w, prop_name, prop_val); + free(prop_name); + } + if (prop_val) { + xmlFree(prop_val); + } + } + return PB_ENTER; +} + +static xml_node_parser_t *ui_builder_get_node_parser(const char *name) +{ + size_t i; + static xml_node_parser_t parsers[] = { + { ID_WIDGET, "w", ui_builder_parse_widget_node }, + { ID_WIDGET, "widget", ui_builder_parse_widget_node }, + { ID_RESOURCE, "resource", ui_builder_parse_resource_node }, + { ID_UI, "ui", ui_builder_parse_ui_node } + }; + + for (i = 0; i < sizeof(parsers) / sizeof(xml_node_parser_t); ++i) { + if (strcmp(parsers[i].name, name) == 0) { + return &parsers[i]; + } + } + return NULL; +} + +/** 解析 xml 文档结点 */ +static void ui_builder_parse_node(xml_parser_t *parser, xmlNodePtr node) +{ + xml_node_parser_t *p; + xml_parser_t cur_parser; + ui_widget_prototype_t *proto; + + for (; node; node = node->next) { + proto = NULL; + if (node->type == XML_COMMENT_NODE) { + continue; + } + if (node->type == XML_ELEMENT_NODE) { + p = ui_builder_get_node_parser( + (const char *)node->name); + if (!p) { + proto = + ui_get_widget_prototype((char *)node->name); + /* If there is no suitable parser, but a widget + * prototype with the same name already exists, + * use the widget parser + */ + if (proto) { + p = ui_builder_get_node_parser("w"); + } else { + continue; + } + } + } else { + p = parser->parent_parser; + if (!p) { + continue; + } + } + cur_parser = *parser; + cur_parser.parent_widget = parser->widget; + cur_parser.widget_proto = proto; + switch (p->parse(&cur_parser, node)) { + case PB_ENTER: + cur_parser.parent_parser = p; + ui_builder_parse_node(&cur_parser, node->children); + break; + case PB_NEXT: + break; + case PB_WARNING: + logger_warning("[builder] %s (%d): warning: %s node.\n", + node->doc->name, node->line, node->name); + break; + case PB_ERROR: + default: + logger_error("[builder] %s (%d): error: %s node.\n", + node->doc->name, node->line, node->name); + break; + } + if (!parser->root && cur_parser.root) { + parser->root = cur_parser.root; + } + } +} +#endif + +ui_widget_t *ui_load_xml_string(const char *str, int size) +{ +#ifndef LIBUI_XML_HAS_LIBXML2 + logger_warning(WARN_TXT); +#else + xmlDocPtr doc; + xmlNodePtr cur; + xml_parser_t parser; + + memset(&parser, 0, sizeof(parser)); + doc = xmlParseMemory(str, size); + if (!doc) { + xmlPrintErrorMessage(xmlGetLastError()); + logger_error("[builder] %s\n", + "failed to parse xml form memory"); + goto FAILED; + } + cur = xmlDocGetRootElement(doc); + if (xmlStrcasecmp(cur->name, BAD_CAST "lcui-app")) { + logger_error("[builder] error root node name: %s\n", cur->name); + goto FAILED; + } + ui_builder_parse_node(&parser, cur->children); +FAILED: + if (doc) { + xmlFreeDoc(doc); + } + return parser.root; +#endif + return NULL; +} + +ui_widget_t *ui_load_xml_file(const char *filepath) +{ +#ifndef LIBUI_XML_HAS_LIBXML2 + logger_warning(WARN_TXT); +#else + xmlDocPtr doc; + xmlNodePtr cur; + xml_parser_t parser; + + memset(&parser, 0, sizeof(parser)); + parser.space = filepath; + doc = xmlParseFile(filepath); + if (!doc) { + xmlPrintErrorMessage(xmlGetLastError()); + logger_error("[builder] %s\n", "failed to parse xml form file"); + goto FAILED; + } + cur = xmlDocGetRootElement(doc); + if (xmlStrcasecmp(cur->name, BAD_CAST "lcui-app")) { + logger_error("[builder] error root node name: %s\n", cur->name); + goto FAILED; + } + ui_builder_parse_node(&parser, cur->children); +FAILED: + if (doc) { + xmlFreeDoc(doc); + } + return parser.root; +#endif + return NULL; +} diff --git a/lib/ui-xml/xmake.lua b/lib/ui-xml/xmake.lua new file mode 100644 index 000000000..fd39c3be0 --- /dev/null +++ b/lib/ui-xml/xmake.lua @@ -0,0 +1,20 @@ +set_project("libui-xml") +set_version("0.1.0-a") +add_requires("libxml2", {optional = true}) + +target("libui-xml") + add_packages("libxml2") + if has_package("libxml2") then + set_configvar("LIBUI_XML_HAS_LIBXML2", 1) + end + set_kind("$(kind)") + add_files("src/**.c") + add_deps("yutil", "libui", "libcss", "pandagl") + set_configdir("include/ui_xml") + add_configfiles("src/config.h.in") + add_headerfiles("include/ui_xml.h", "include/(ui_xml/*.h)") + if is_kind("static") then + set_configvar("LIBUI_XML_STATIC_BUILD", 1) + elseif is_plat("windows") then + add_defines("LIBUI_XML_DLL_EXPORT") + end diff --git a/lib/ui/include/ui/metrics.h b/lib/ui/include/ui/metrics.h index fd5d07dfd..dec833f49 100644 --- a/lib/ui/include/ui/metrics.h +++ b/lib/ui/include/ui/metrics.h @@ -4,10 +4,10 @@ #include "common.h" #include "types.h" -LIBUI_BEGIN_DECLS - LIBUI_PUBLIC ui_metrics_t ui_metrics; +LIBUI_BEGIN_DECLS + LIBUI_INLINE int ui_compute(float value) { return (int)(ui_metrics.scale * value); diff --git a/lib/ui/src/ui.c b/lib/ui/src/ui.c index d07f28ffb..a9e9c2b80 100644 --- a/lib/ui/src/ui.c +++ b/lib/ui/src/ui.c @@ -1,5 +1,6 @@ #include #include +#include "ui/base.h" #include "ui_trash.h" #include "ui_root.h" #include "ui_events.h" diff --git a/lib/ui/src/ui_events.c b/lib/ui/src/ui_events.c index 0607a5777..8c616987c 100644 --- a/lib/ui/src/ui_events.c +++ b/lib/ui/src/ui_events.c @@ -2,7 +2,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/lib/ui/src/ui_image.c b/lib/ui/src/ui_image.c index 1507f29a7..2ee6a8bca 100644 --- a/lib/ui/src/ui_image.c +++ b/lib/ui/src/ui_image.c @@ -52,7 +52,7 @@ static void ui_image_force_destroy(void *privdata, void *data) free(image); } -static void ui_image_load(ui_image_t *image) +static void ui_image_dispatch_events(ui_image_t *image) { list_t events; list_node_t *node; @@ -60,12 +60,6 @@ static void ui_image_load(ui_image_t *image) ui_image_event_listener_t *listener; list_create(&events); - if (!image->loaded) { - if (pd_read_image_from_file(image->path, &image->data) != 0) { - return; - } - image->loaded = true; - } for (list_each(node, &image->listeners)) { listener = node->data; if (!listener->is_fresh) { @@ -75,7 +69,10 @@ static void ui_image_load(ui_image_t *image) if (!e) { return; } - e->image = image; + e->image = NULL; + if (pd_canvas_is_valid(&image->data)) { + e->image = image; + } e->data = listener->data; e->handler = listener->handler; list_append_node(&events, &e->node); @@ -84,12 +81,24 @@ static void ui_image_load(ui_image_t *image) list_concat(&ui_image_loader.events, &events); } +static void ui_image_load(ui_image_t *image) +{ + if (!image->loaded) { + if (pd_read_image_from_file(image->path, &image->data) != 0) { + pd_canvas_init(&image->data); + } + image->loaded = true; + } + ui_image_dispatch_events(image); +} + ui_image_t *ui_image_create(const char *path) { ui_image_t *image; image = dict_fetch_value(ui_image_loader.dict, path); if (image) { + ui_image_dispatch_events(image); image->refs_count++; return image; } diff --git a/lib/ui/src/ui_mutation_oberver.c b/lib/ui/src/ui_mutation_observer.c similarity index 100% rename from lib/ui/src/ui_mutation_oberver.c rename to lib/ui/src/ui_mutation_observer.c diff --git a/lib/ui/src/ui_widget_id.c b/lib/ui/src/ui_widget_id.c index a775f8a15..9436cd9c2 100644 --- a/lib/ui/src/ui_widget_id.c +++ b/lib/ui/src/ui_widget_id.c @@ -1,6 +1,6 @@ #include -#include +#include #include #include "ui_widget_id.h" diff --git a/lib/ui/xmake.lua b/lib/ui/xmake.lua index 32da0e053..e5b4d62bd 100644 --- a/lib/ui/xmake.lua +++ b/lib/ui/xmake.lua @@ -2,12 +2,12 @@ set_project("libui") set_version("0.1.0-a") target("libui") - set_default(false) set_kind("$(kind)") add_files("src/**.c") add_deps("yutil", "pandagl", "libcss") set_configdir("include/ui") add_configfiles("src/config.h.in") + add_headerfiles("include/ui.h", "include/(ui/*.h)") if is_kind("static") then set_configvar("LIBUI_STATIC_BUILD", 1) elseif is_plat("windows") then diff --git a/lib/worker/include/worker.h b/lib/worker/include/worker.h index b87e64aa4..401b206b7 100644 --- a/lib/worker/include/worker.h +++ b/lib/worker/include/worker.h @@ -28,31 +28,34 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#ifndef LCUI_WORKER_H -#define LCUI_WORKER_H +#ifndef LIB_WORKER_INCLULDE_WORKER_H +#define LIB_WORKER_INCLULDE_WORKER_H -LCUI_BEGIN_HEADER +#include +#include "worker/common.h" -typedef void(*LCUI_TaskFunc)(void*, void*); +LIBWORKER_BEGIN_DECLS -typedef struct LCUI_TaskRec_ { - LCUI_TaskFunc func; /**< 任务处理函数 */ - void *arg[2]; /**< 两个参数 */ - void(*destroy_arg[2])(void*); /**< 参数的销毁函数 */ -} LCUI_TaskRec, *LCUI_Task; +typedef void (*worker_callback_t)(void *, void *); -typedef struct LCUI_WorkerRec_ *LCUI_Worker; +typedef struct worker_task_t { + worker_callback_t callback; /**< 任务处理函数 */ + void *arg[2]; /**< 两个参数 */ + void (*destroy_arg[2])(void *); /**< 参数的销毁函数 */ +} worker_task_t; -LCUI_API LCUI_Worker LCUIWorker_New(void); +typedef struct worker_t worker_t; -LCUI_API void LCUIWorker_PostTask(LCUI_Worker worker, LCUI_Task task); +LIBWORKER_PUBLIC worker_t *worker_create(void); -LCUI_API LCUI_BOOL LCUIWorker_RunTask(LCUI_Worker worker); +LIBWORKER_PUBLIC void worker_post_task(worker_t *worker, worker_task_t *task); -LCUI_API int LCUIWorker_RunAsync(LCUI_Worker worker); +LIBWORKER_PUBLIC bool worker_run_task(worker_t *worker); -LCUI_API void LCUIWorker_Destroy(LCUI_Worker worker); +LIBWORKER_PUBLIC int worker_run_async(worker_t *worker); -LCUI_END_HEADER +LIBWORKER_PUBLIC void worker_destroy(worker_t *worker); + +LIBWORKER_END_DECLS #endif diff --git a/lib/worker/include/worker/common.h b/lib/worker/include/worker/common.h new file mode 100644 index 000000000..0ca42f8e6 --- /dev/null +++ b/lib/worker/include/worker/common.h @@ -0,0 +1,22 @@ +#include "config.h" +#ifdef __cplusplus +#define LIBWORKER_BEGIN_DECLS extern "C" { +#define LIBWORKER_END_DECLS } +#else +#define LIBWORKER_BEGIN_DECLS +#define LIBWORKER_END_DECLS +#endif + +#ifndef LIBWORKER_PUBLIC +#if defined(_MSC_VER) && !defined(LIBWORKER_STATIC_BUILD) +#ifdef LIBWORKER_DLL_EXPORT +#define LIBWORKER_PUBLIC __declspec(dllexport) +#else +#define LIBWORKER_PUBLIC __declspec(dllimport) +#endif +#elif __GNUC__ >= 4 +#define LIBWORKER_PUBLIC extern __attribute__((visibility("default"))) +#else +#define LIBWORKER_PUBLIC extern +#endif +#endif diff --git a/lib/worker/src/config.h.in b/lib/worker/src/config.h.in new file mode 100644 index 000000000..ab8659236 --- /dev/null +++ b/lib/worker/src/config.h.in @@ -0,0 +1,5 @@ +#define LIBWORKER_VERSION "${VERSION}" +#define LIBWORKER_VERSION_MAJOR ${VERSION_MAJOR} +#define LIBWORKER_VERSION_MINOR ${VERSION_MINOR} +#define LIBWORKER_VERSION_ALTER ${VERSION_ALTER} +${define LIBWORKER_STATIC_BUILD} diff --git a/lib/worker/src/worker.c b/lib/worker/src/worker.c index d340afc70..2ef029102 100644 --- a/lib/worker/src/worker.c +++ b/lib/worker/src/worker.c @@ -27,158 +27,155 @@ * POSSIBILITY OF SUCH DAMAGE. */ -#define LCUI_WORKER_C - #include #include -#include -#include "../include/worker.h" +#include #include -#include +#include -typedef struct LCUI_WorkerRec_ { - LCUI_BOOL active; /**< 是否处于活动状态 */ - list_t tasks; /**< 任务队列 */ - thread_mutex_t mutex; /**< 互斥锁 */ - thread_cond_t cond; /**< 条件变量 */ - thread_t thread; /**< 所在的线程 */ -} LCUI_WorkerRec; +struct worker_t { + bool active; /**< 是否处于活动状态 */ + list_t tasks; /**< 任务队列 */ + thread_mutex_t mutex; /**< 互斥锁 */ + thread_cond_t cond; /**< 条件变量 */ + thread_t thread; /**< 所在的线程 */ +}; -void LCUITask_Destroy(LCUI_Task task) +static void worker_task_destroy(worker_task_t *task) { - if (task->destroy_arg[0] && task->arg[0]) { - task->destroy_arg[0](task->arg[0]); - } - if (task->destroy_arg[1] && task->arg[1]) { - task->destroy_arg[1](task->arg[1]); - } + if (task->destroy_arg[0] && task->arg[0]) { + task->destroy_arg[0](task->arg[0]); + } + if (task->destroy_arg[1] && task->arg[1]) { + task->destroy_arg[1](task->arg[1]); + } } -int LCUITask_Run(LCUI_Task task) +static int worker_task_run(worker_task_t *task) { - if (task && task->func) { - task->func(task->arg[0], task->arg[1]); - return 0; - } - return -1; + if (task && task->callback) { + task->callback(task->arg[0], task->arg[1]); + return 0; + } + return -1; } -LCUI_Worker LCUIWorker_New(void) +worker_t *worker_create(void) { - LCUI_Worker worker = malloc(sizeof(LCUI_WorkerRec)); - thread_mutex_init(&worker->mutex); - thread_cond_init(&worker->cond); - list_create(&worker->tasks); - worker->active = FALSE; - worker->thread = 0; - return worker; + worker_t *worker = malloc(sizeof(worker_t)); + thread_mutex_init(&worker->mutex); + thread_cond_init(&worker->cond); + list_create(&worker->tasks); + worker->active = FALSE; + worker->thread = 0; + return worker; } -void LCUIWorker_PostTask(LCUI_Worker worker, LCUI_Task task) +void worker_post_task(worker_t *worker, worker_task_t *task) { - LCUI_Task newtask; - newtask = malloc(sizeof(LCUI_TaskRec)); - *newtask = *task; - thread_mutex_lock(&worker->mutex); - list_append(&worker->tasks, newtask); - thread_cond_signal(&worker->cond); - thread_mutex_unlock(&worker->mutex); + worker_task_t *newtask; + newtask = malloc(sizeof(worker_task_t)); + *newtask = *task; + thread_mutex_lock(&worker->mutex); + list_append(&worker->tasks, newtask); + thread_cond_signal(&worker->cond); + thread_mutex_unlock(&worker->mutex); } -LCUI_Task LCUIWorker_GetTask(LCUI_Worker worker) +worker_task_t *worker_get_task(worker_t *worker) { - LCUI_Task task; - list_node_t *node; - - node = list_get_node(&worker->tasks, 0); - if (!node) { - return NULL; - } - task = node->data; - list_unlink(&worker->tasks, node); - free(node); - return task; + worker_task_t *task; + list_node_t *node; + + node = list_get_node(&worker->tasks, 0); + if (!node) { + return NULL; + } + task = node->data; + list_unlink(&worker->tasks, node); + free(node); + return task; } -LCUI_BOOL LCUIWorker_RunTask(LCUI_Worker worker) +bool worker_run_task(worker_t *worker) { - LCUI_Task task; - - thread_mutex_lock(&worker->mutex); - task = LCUIWorker_GetTask(worker); - thread_mutex_unlock(&worker->mutex); - if (!task) { - return FALSE; - } - LCUITask_Run(task); - LCUITask_Destroy(task); - free(task); - return TRUE; + worker_task_t *task; + + thread_mutex_lock(&worker->mutex); + task = worker_get_task(worker); + thread_mutex_unlock(&worker->mutex); + if (!task) { + return FALSE; + } + worker_task_run(task); + worker_task_destroy(task); + free(task); + return TRUE; } -static void OnDeleteTask(void *arg) +static void worker_on_destroy_task(void *arg) { - LCUITask_Destroy(arg); - free(arg); + worker_task_destroy(arg); + free(arg); } -static void LCUIWorker_ExecDestroy(LCUI_Worker worker) +static void worker_do_destroy(worker_t *worker) { - list_destroy(&worker->tasks, OnDeleteTask); - thread_mutex_unlock(&worker->mutex); - thread_mutex_destroy(&worker->mutex); - thread_cond_destroy(&worker->cond); - free(worker); + list_destroy(&worker->tasks, worker_on_destroy_task); + thread_mutex_unlock(&worker->mutex); + thread_mutex_destroy(&worker->mutex); + thread_cond_destroy(&worker->cond); + free(worker); } -static void LCUIWorker_Thread(void *arg) +static void worker_thread(void *arg) { - LCUI_Task task; - LCUI_Worker worker = arg; - - thread_mutex_lock(&worker->mutex); - while (worker->active) { - task = LCUIWorker_GetTask(worker); - if (task) { - thread_mutex_unlock(&worker->mutex); - LCUITask_Run(task); - LCUITask_Destroy(task); - free(task); - thread_mutex_lock(&worker->mutex); - continue; - } - if (worker->active) { - thread_cond_wait(&worker->cond, &worker->mutex); - } - } - LCUIWorker_ExecDestroy(worker); - thread_exit(NULL); + worker_task_t *task; + worker_t *worker = arg; + + thread_mutex_lock(&worker->mutex); + while (worker->active) { + task = worker_get_task(worker); + if (task) { + thread_mutex_unlock(&worker->mutex); + worker_task_run(task); + worker_task_destroy(task); + free(task); + thread_mutex_lock(&worker->mutex); + continue; + } + if (worker->active) { + thread_cond_wait(&worker->cond, &worker->mutex); + } + } + worker_do_destroy(worker); + thread_exit(NULL); } -int LCUIWorker_RunAsync(LCUI_Worker worker) +int worker_run_async(worker_t *worker) { - if (worker->thread != 0) { - return -EEXIST; - } - worker->active = TRUE; - thread_create(&worker->thread, LCUIWorker_Thread, worker); - logger_debug("[worker] worker %u is running\n", worker->thread); - return 0; + if (worker->thread != 0) { + return -EEXIST; + } + worker->active = TRUE; + thread_create(&worker->thread, worker_thread, worker); + logger_debug("[worker] worker %u is running\n", worker->thread); + return 0; } -void LCUIWorker_Destroy(LCUI_Worker worker) +void worker_destroy(worker_t *worker) { - thread_t thread = worker->thread; - - if (worker->active) { - logger_debug("[worker] worker %u is stopping...\n", thread); - thread_mutex_lock(&worker->mutex); - worker->active = FALSE; - thread_cond_signal(&worker->cond); - thread_mutex_unlock(&worker->mutex); - thread_join(thread, NULL); - logger_debug("[worker] worker %u has stopped\n", thread); - return; - } - LCUIWorker_ExecDestroy(worker); + thread_t thread = worker->thread; + + if (worker->active) { + logger_debug("[worker] worker %u is stopping...\n", thread); + thread_mutex_lock(&worker->mutex); + worker->active = FALSE; + thread_cond_signal(&worker->cond); + thread_mutex_unlock(&worker->mutex); + thread_join(thread, NULL); + logger_debug("[worker] worker %u has stopped\n", thread); + return; + } + worker_do_destroy(worker); } diff --git a/lib/worker/xmake.lua b/lib/worker/xmake.lua index 10ead5a60..174254ed1 100644 --- a/lib/worker/xmake.lua +++ b/lib/worker/xmake.lua @@ -1,5 +1,12 @@ target("libworker") - set_default(false) set_kind("$(kind)") add_files("src/**.c") add_deps("yutil", "libthread") + set_configdir("include/worker") + add_configfiles("src/config.h.in") + add_headerfiles("include/worker.h", "include/(worker/*.h)") + if is_kind("static") then + set_configvar("LIBWORKER_STATIC_BUILD", 1) + elseif is_plat("windows") then + add_defines("LIBWORKER_DLL_EXPORT") + end diff --git a/src/config.h.in b/src/config.h.in index bcbd17306..e3cb20ba4 100644 --- a/src/config.h.in +++ b/src/config.h.in @@ -1,4 +1,2 @@ #define PACKAGE_VERSION "${VERSION}-${GIT_COMMIT}" - -${define WITH_LIBXML2} -${define ENABLE_OPENMP} +${define LCUI_STATIC_BUILD} diff --git a/src/lcui.c b/src/lcui.c index 5dcc7c821..fda8421d8 100644 --- a/src/lcui.c +++ b/src/lcui.c @@ -7,188 +7,178 @@ #include #include #include -#include -#include -#include +#include +#include +#include #define LCUI_WORKER_NUM 4 /** LCUI 应用程序数据 */ static struct lcui_app_t { - step_timer_t timer; - LCUI_Worker main_worker; - LCUI_Worker workers[LCUI_WORKER_NUM]; - int worker_next; + step_timer_t timer; + worker_t *main_worker; + worker_t *workers[LCUI_WORKER_NUM]; + int worker_next; } lcui_app; const char *lcui_get_version(void) { - return PACKAGE_VERSION; + return PACKAGE_VERSION; } -LCUI_BOOL lcui_post_task(LCUI_Task task) +bool lcui_post_task(worker_task_t *task) { - if (!lcui_app.main_worker) { - return FALSE; - } - LCUIWorker_PostTask(lcui_app.main_worker, task); - return TRUE; + if (!lcui_app.main_worker) { + return FALSE; + } + worker_post_task(lcui_app.main_worker, task); + return TRUE; } -void lcui_post_async_task(LCUI_Task task, int worker_id) +bool lcui_post_simple_task(worker_callback_t callback, void *arg1, void *arg2) { - if (worker_id < 0) { - if (lcui_app.worker_next >= LCUI_WORKER_NUM) { - lcui_app.worker_next = 0; - } - worker_id = lcui_app.worker_next; - lcui_app.worker_next += 1; - } - if (worker_id >= LCUI_WORKER_NUM) { - worker_id = 0; - } - LCUIWorker_PostTask(lcui_app.workers[worker_id], task); + worker_task_t task = { 0 }; + task.arg[0] = arg1; + task.arg[1] = arg2; + task.callback = callback; + return lcui_post_task(&task); +} + +void lcui_post_async_task(worker_task_t *task, int worker_id) +{ + if (worker_id < 0) { + if (lcui_app.worker_next >= LCUI_WORKER_NUM) { + lcui_app.worker_next = 0; + } + worker_id = lcui_app.worker_next; + lcui_app.worker_next += 1; + } + if (worker_id >= LCUI_WORKER_NUM) { + worker_id = 0; + } + worker_post_task(lcui_app.workers[worker_id], task); } uint32_t lcui_get_fps(void) { - return lcui_app.timer.frames_per_second; + return lcui_app.timer.frames_per_second; } void lcui_init_app(void) { - int i; - step_timer_init(&lcui_app.timer); - lcui_app.main_worker = LCUIWorker_New(); - for (i = 0; i < LCUI_WORKER_NUM; ++i) { - lcui_app.workers[i] = LCUIWorker_New(); - LCUIWorker_RunAsync(lcui_app.workers[i]); - } - lcui_app.timer.target_elapsed_time = 0; + int i; + step_timer_init(&lcui_app.timer); + lcui_app.main_worker = worker_create(); + for (i = 0; i < LCUI_WORKER_NUM; ++i) { + lcui_app.workers[i] = worker_create(); + worker_run_async(lcui_app.workers[i]); + } + lcui_app.timer.target_elapsed_time = 0; } void lcui_set_frame_rate_cap(unsigned rate_cap) { - if (rate_cap > 0) { - lcui_app.timer.target_elapsed_time = 1000 / rate_cap; - lcui_app.timer.is_fixed_time_step = TRUE; - } else { - lcui_app.timer.is_fixed_time_step = FALSE; - } + if (rate_cap > 0) { + lcui_app.timer.target_elapsed_time = 1000 / rate_cap; + lcui_app.timer.is_fixed_time_step = TRUE; + } else { + lcui_app.timer.is_fixed_time_step = FALSE; + } } static void lcui_destroy_app(void) { - int i; + int i; - for (i = 0; i < LCUI_WORKER_NUM; ++i) { - LCUIWorker_Destroy(lcui_app.workers[i]); - lcui_app.workers[i] = NULL; - } - LCUIWorker_Destroy(lcui_app.main_worker); - lcui_app.main_worker = NULL; + for (i = 0; i < LCUI_WORKER_NUM; ++i) { + worker_destroy(lcui_app.workers[i]); + lcui_app.workers[i] = NULL; + } + worker_destroy(lcui_app.main_worker); + lcui_app.main_worker = NULL; } static void lcui_print_info(void) { - logger_log(LOGGER_LEVEL_INFO, - "LCUI (LC's UI) version " PACKAGE_VERSION "\n" -#ifdef _MSC_VER - "Build tool: " -#if (_MSC_VER > 1912) - "MS VC++ (higher version)" -#elif (_MSC_VER >= 1910 && _MSC_VER <= 1912) - "MS VC++ 14.1 (VisualStudio 2017)" -#elif (_MSC_VER == 1900) - "MS VC++ 14.0 (VisualStudio 2015)" -#elif (_MSC_VER == 1800) - "MS VC++ 12.0 (VisualStudio 2013)" -#elif (_MSC_VER == 1700) - "MS VC++ 11.0 (VisualStudio 2012)" -#elif (_MSC_VER == 1600) - "MS VC++ 10.0 (VisualStudio 2010)" -#else - "MS VC++ (older version)" -#endif - "\n" -#endif - "Build at "__DATE__ - " - "__TIME__ - "\n" - "Copyright (C) 2012-2021 Liu Chao .\n" - "This is open source software, licensed under MIT. \n" - "See source distribution for detailed copyright notices.\n" - "To learn more, visit http://www.lcui.org.\n\n"); + logger_log(LOGGER_LEVEL_INFO, + "LCUI (LC's UI) version " PACKAGE_VERSION "\n" + "Build at "__DATE__ + " - "__TIME__ + "\n" + "Copyright (C) 2012-2023 Liu Chao .\n" + "This is open source software, licensed under MIT. \n" + "See source distribution for detailed copyright notices.\n" + "To learn more, visit http://www.lcui.org.\n\n"); } static void lcui_app_on_tick(step_timer_t *timer, void *data) { - lcui_render_ui(); - app_present(); + lcui_render_ui(); + app_present(); } static int lcui_dispatch_app_event(app_event_t *e) { - if (e->type == APP_EVENT_QUIT) { - return 0; - } - LCUIWorker_RunTask(lcui_app.main_worker); - lcui_process_timers(); - lcui_dispatch_ui_event(e); - lcui_update_ui(); - step_timer_tick(&lcui_app.timer, lcui_app_on_tick, NULL); - return 0; + if (e->type == APP_EVENT_QUIT) { + return 0; + } + worker_run_task(lcui_app.main_worker); + lcui_process_timers(); + lcui_dispatch_ui_event(e); + lcui_update_ui(); + step_timer_tick(&lcui_app.timer, lcui_app_on_tick, NULL); + return 0; } int lcui_process_events(app_process_events_option_t option) { - return app_process_native_events(option); + return app_process_native_events(option); } void lcui_init_base(void) { - lcui_init_timers(); - lcui_reset_settings(); + lcui_init_timers(); + lcui_reset_settings(); } void lcui_init(void) { - lcui_print_info(); - lcui_init_base(); - lcui_init_app(); - if (app_init(L"LCUI Application") != 0) { - abort(); - } - app_set_event_dispatcher(lcui_dispatch_app_event); - lcui_init_ui(); + lcui_print_info(); + lcui_init_base(); + lcui_init_app(); + if (app_init(L"LCUI Application") != 0) { + abort(); + } + app_set_event_dispatcher(lcui_dispatch_app_event); + lcui_init_ui(); } void lcui_destroy(void) { - lcui_destroy_ui(); - lcui_destroy_app(); - lcui_destroy_timers(); - app_destroy(); + lcui_destroy_ui(); + lcui_destroy_app(); + lcui_destroy_timers(); + app_destroy(); } void lcui_exit(int code) { - app_exit(code); + app_exit(code); } void lcui_quit(void) { - lcui_exit(0); + lcui_exit(0); } int lcui_run(void) { - return lcui_process_events(APP_PROCESS_EVENTS_UNTIL_QUIT); + return lcui_process_events(APP_PROCESS_EVENTS_UNTIL_QUIT); } int lcui_main(void) { - int exit_code = lcui_run(); - lcui_destroy(); - return exit_code; + int exit_code = lcui_run(); + lcui_destroy(); + return exit_code; } diff --git a/src/lcui_ui.c b/src/lcui_ui.c index 2b8186510..ed99190f0 100644 --- a/src/lcui_ui.c +++ b/src/lcui_ui.c @@ -1,6 +1,8 @@ #include #include #include +#include +#include #include #include #include diff --git a/tests/cases/test_block_layout.c b/tests/cases/test_block_layout.c index a78799e14..751ff81d4 100644 --- a/tests/cases/test_block_layout.c +++ b/tests/cases/test_block_layout.c @@ -1,6 +1,6 @@ #include "ctest.h" #include -#include +#include #include static void test_dropdown(void) diff --git a/tests/cases/test_clipboard.c b/tests/cases/test_clipboard.c index c18668b2f..a4c343141 100644 --- a/tests/cases/test_clipboard.c +++ b/tests/cases/test_clipboard.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "ctest.h" static void paste_text(void *arg) diff --git a/tests/cases/test_flex_layout.c b/tests/cases/test_flex_layout.c index 5838b4841..ebeb47cdf 100644 --- a/tests/cases/test_flex_layout.c +++ b/tests/cases/test_flex_layout.c @@ -1,7 +1,7 @@ #include "ctest.h" #include #include -#include +#include static void test_flex_layout_with_content_width(float width) { diff --git a/tests/cases/test_mainloop.c b/tests/cases/test_mainloop.c index 01ed1a509..e64d7bc65 100644 --- a/tests/cases/test_mainloop.c +++ b/tests/cases/test_mainloop.c @@ -1,9 +1,9 @@ #include #include #include -#include +#include #include -#include +#include #include "ctest.h" static void OnRefreshScreen(void *arg) diff --git a/tests/cases/test_scrollbar.c b/tests/cases/test_scrollbar.c index 2d33cd375..cebdf83e2 100644 --- a/tests/cases/test_scrollbar.c +++ b/tests/cases/test_scrollbar.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include #include #include "ctest.h" diff --git a/tests/cases/test_settings.c b/tests/cases/test_settings.c index b36a6f1df..b345addeb 100644 --- a/tests/cases/test_settings.c +++ b/tests/cases/test_settings.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "ctest.h" static void check_settings_frame_rate_cap(void *arg) diff --git a/tests/cases/test_thread.c b/tests/cases/test_thread.c index 90603f8fa..6d8ab088a 100644 --- a/tests/cases/test_thread.c +++ b/tests/cases/test_thread.c @@ -1,7 +1,7 @@ #include #include #include -#include +#include #include "ctest.h" typedef struct TestWorkerRec_ { diff --git a/tests/cases/test_xml_parser.c b/tests/cases/test_xml_parser.c index c939395e8..ac301ab16 100644 --- a/tests/cases/test_xml_parser.c +++ b/tests/cases/test_xml_parser.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include "ctest.h" static void check_widget_attribute(void) diff --git a/tests/helloworld_uwp/App.cpp b/tests/helloworld_uwp/App.cpp index b7d1eacd8..76803eee4 100644 --- a/tests/helloworld_uwp/App.cpp +++ b/tests/helloworld_uwp/App.cpp @@ -4,7 +4,7 @@ #include #include #include -#include +#include #include LCUI_APP_H class App : public LCUI::Application diff --git a/tests/test_border.c b/tests/test_border.c index 14a8eafe6..7a7328293 100644 --- a/tests/test_border.c +++ b/tests/test_border.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include int main(void) diff --git a/tests/test_box_shadow.c b/tests/test_box_shadow.c index 764e9ab39..9cc1c2839 100644 --- a/tests/test_box_shadow.c +++ b/tests/test_box_shadow.c @@ -1,5 +1,5 @@ #include -#include +#include #include int main(void) diff --git a/tests/test_image_scaling_bench.c b/tests/test_image_scaling_bench.c index da844b321..de1c93499 100644 --- a/tests/test_image_scaling_bench.c +++ b/tests/test_image_scaling_bench.c @@ -2,9 +2,9 @@ #include #include #include -#include +#include #include -#include +#include #include int main(int argc, char **argv) diff --git a/tests/test_scaling_support.c b/tests/test_scaling_support.c index b6d9fb163..c35a81e89 100644 --- a/tests/test_scaling_support.c +++ b/tests/test_scaling_support.c @@ -1,6 +1,6 @@ #include #include -#include +#include #include enum { TYPE_DENSITY, TYPE_SCALED_DENSITY, TYPE_SCALE }; diff --git a/tests/test_widget.c b/tests/test_widget.c index e84cc3238..342a63508 100644 --- a/tests/test_widget.c +++ b/tests/test_widget.c @@ -11,7 +11,6 @@ int main(void) ui_widget_t *box, *w; - pd_font_library_init(); ui_init(); box = ui_create_widget(NULL); @@ -51,6 +50,5 @@ int main(void) logger_debug("it should take less than 1s\n"); ui_destroy(); - pd_font_library_destroy(); return 0; } diff --git a/xmake.lua b/xmake.lua index 3ae2416cf..d126c988b 100644 --- a/xmake.lua +++ b/xmake.lua @@ -3,29 +3,28 @@ set_version("3.0.0-a") set_warnings("all") add_rules("mode.debug", "mode.release", "mode.coverage") add_rpathdirs("@loader_path/lib", "@loader_path") -add_requires("libomp", "libxml2", {optional = true}) -add_defines("LCUI_EXPORTS", "YUTIL_EXPORTS", "UNICODE", "_CRT_SECURE_NO_WARNINGS") +add_defines("UNICODE", "_CRT_SECURE_NO_WARNINGS", "YUTIL_EXPORTS") add_includedirs( "lib/ctest/include", "lib/yutil/include", "lib/pandagl/include", + "lib/timer/include", + "lib/thread/include", "lib/css/include", "lib/platform/include", + "lib/worker/include", "lib/ui/include", "lib/ui-server/include", "lib/ui-widgets/include", "lib/ui-cursor/include", - "lib/ui-builder/include", + "lib/ui-xml/include", "include" ) includes("lib/*/xmake.lua") -includes("examples/*/xmake.lua") includes("tests/xmake.lua") option("ci-env", {showmenu = true, default = false}) -option("enable-openmp", {showmenu = true, default = true}) - if has_config("ci-env") then add_defines("CI_ENV") end @@ -69,34 +68,26 @@ target("lcui_tests") target("lcui") set_kind("$(kind)") - add_files( - "src/*.c", - "lib/worker/src/**.c", - "lib/ui-builder/src/**.c", - "lib/ui-cursor/src/**.c", - "lib/ui-server/src/**.c", - "lib/ui-widgets/src/**.c" - ) + add_files("src/*.c") + if is_kind("static") then + set_configvar("LCUI_STATIC_BUILD", 1) + elseif is_plat("windows") then + add_defines("LCUI_DLL_EXPORT") + end add_configfiles("src/config.h.in") set_configdir("include/LCUI") - add_packages("libomp", "libxml2") - add_options("enable-openmp") - add_deps("yutil", "pandagl", "libcss", "libui", "libthread", "libtimer", "libplatform") - - if has_package("libomp") and has_config("enable-openmp") then - set_configvar("ENABLE_OPENMP", 1) - end - - if has_package("libxml2") then - set_configvar("WITH_LIBXML2", 1) - end - -target("headers") - set_kind("phony") - set_default(false) - before_build(function (target) - -- Copy the header file of the internal library to the LCUI header file directory - os.cp("$(projectdir)/lib/thread/include/*.h", "$(projectdir)/include/LCUI/") - os.cp("$(projectdir)/lib/timer/include/*.h", "$(projectdir)/include/LCUI/") - os.cp("$(projectdir)/lib/worker/include/*.h", "$(projectdir)/include/LCUI/") - end) + add_deps( + "yutil", + "libthread", + "libplatform", + "libworker", + "libtimer", + "pandagl", + "libcss", + "libui", + "libui-widgets", + "libui-cursor", + "libui-server", + "libui-xml" + ) + add_headerfiles("include/LCUI.h", "include/(LCUI/*.h)")