zlgopen / awtk-web

在浏览器中运行AWTK应用程序
GNU Lesser General Public License v2.1
23 stars 9 forks source link

awtk c程序移植到web发现ui逻辑无法正常执行 #9

Closed Tracker647 closed 2 months ago

Tracker647 commented 3 months ago

这个例子是一个setting box, 按下两边的按钮,或者拉动滑条,box的label都能有对应的状态显示,这个例子在桌面上运行正常,但是移植到web之后发现滑条滑动正常,按钮就点不了。

桌面端,正常情况: GIF 2024-6-6 22-16-14

到了浏览器就变成: GIF 2024-6-6 22-23-46

示例xml和c home_page.xml

<window name="home_page">
  <view name="v_setting" x="10" y="10" w="530" h="75" style:normal:border_color="#00000000" style:focused:border_color="#3FC5C3" widget_type="select" val_list="Auto;1;2;3;4;5;6;7;8;9" select_index="0">
    <view name="setting_container" x="0" y="28" w="530" h="46" style:normal:bg_color="#15263E" style:normal:round_radius="5" style:focused:border_color="#4ADDD5" style:focused:round_radius="5">
      <view name="select_box" x="10" y="10" w="174" h="26">
        <button name="sbox_left_btn" x="0" y="0" w="18" h="26" style="default" style:normal:bg_image="arrow_left_n"/>
        <label name="sbox_label" x="28" y="0" w="118" h="26" style:normal:border_color="#34445D" style:normal:text_color="#FFFFFF" style:normal:font_size="25" text="Label"/>
        <button name="sbox_right_btn" x="157" y="0" w="17" h="26" style="default" style:normal:bg_image="arrow_right_n"/>
      </view>
      <slider name="slider" x="194" y="15" w="312" h="16" style:normal:icon="rounded_n" vertical="false" dragger_adapt_to_icon="true" slide_with_bar="false" style:normal:fg_color="#0082D5" style:normal:round_radius="5" style:normal:x_offset="0" style:normal:fg_image_draw_type="default" sensitive="true"/>
    </view>
  </view>
</window>

home_page.c

#include "awtk.h"
#include "../common/navigator.h"

int32_t setting_box_get_current_index(widget_t *setting)
{
  value_t v;
  widget_get_prop(setting, "select_index", &v);
  return value_int32(&v);
}

const char *setting_box_get_type(widget_t *setting)
{
  value_t v;
  widget_get_prop(setting, "widget_type", &v);
  return value_str(&v);
}

int32_t setting_box_get_select_count(widget_t *setting)
{
  const char *type = setting_box_get_type(setting);
  if (0 != strcmp("select", type))
  {
    // printf("only select type have count\r\n");
    return 0;
  }
  value_t v;
  widget_get_prop(setting, "select_count", &v);
  return value_int32(&v);
}

const char *setting_box_get_current_value(widget_t *setting)
{
  value_t v;
  widget_get_prop(setting, "select_value", &v);
  return value_str(&v);
}

ret_t setting_box_setting_index(widget_t *setting, int32_t target_index)
{
  if (target_index < 0)
  {
    printf("index need to be not negative!\r\n");
    return RET_FAIL;
  }
  value_t val_list = {0};
  widget_get_prop(setting, "val_list", &val_list);
  const char *val_list_str = value_str(&val_list);
  const char *p1 = val_list_str, *p2 = val_list_str;

  int32_t index = 0;
  char set_value[32] = {0};
  value_t v_set_value = {0}, v_target_index = {0};
  while (p2)
  {
    /* 寻找符合target_index的[p1, p2)子字符串 */
    if (';' == *p2 || '\0' == *p2)
    {
      if (index == target_index)
      {
        strncpy(set_value, p1, p2 - p1);

        widget_t *sbox_label = widget_lookup(setting, "sbox_label", TRUE);
        value_set_str(&v_set_value, set_value);
        value_set_int32(&v_target_index, index);
        widget_set_text_utf8(sbox_label, set_value);
        widget_set_prop(setting, "select_index", &v_target_index);
        widget_set_prop(setting, "select_value", &v_set_value);

        return RET_OK;
      }

      /* 到底了还没找到,返回fail */
      if ('\0' == *p2)
        return RET_FAIL;
      index++;
      p1 = p2 + 1;
      p2 = p1;
    }
    else
    {
      p2++;
    }
  }

  return RET_FAIL;
}

ret_t setting_box_init(widget_t *setting)
{
  int32_t len = 0;
  int32_t setting_index = 0;
  value_t widget_type = {0};
  widget_get_prop(setting, "widget_type", &widget_type);
  if (tk_str_eq(value_str(&widget_type), "select"))
  {
    value_t val_list = {0};
    widget_get_prop(setting, "val_list", &val_list);
    const char *val_list_str = value_str(&val_list);
    /* 获取val_list长度 */
    const char *p = val_list_str;
    while (p)
    {
      if (';' == *p || '\0' == *p)
        len++;
      if ('\0' == *p)
        break;
      p++;
    }
    value_t v_select_count = {0};
    value_set_int32(&v_select_count, len);
    widget_set_prop(setting, "select_count", &v_select_count);

    widget_t *slider = widget_lookup(setting, "slider", TRUE);
    if (NULL != slider)
    {
      slider_set_min(slider, 0);
      slider_set_max(slider, setting_box_get_select_count(setting) - 1);
      setting_box_setting_index(setting, setting_index);
    }
  }

  /* 调试用 */
  value_t setting_name = {0};
  widget_get_prop(setting, "name", &setting_name);
  printf("setting loaded: %s, len = %d\r\n", value_str(&setting_name), setting_box_get_select_count(setting));
  return RET_OK;
}

static ret_t on_sbox_left_btn_click(void *ctx, event_t *e)
{
  // 定位所在的setting box
  widget_t *sbox_btn_left = WIDGET(e->target);
  widget_t *sbox = sbox_btn_left->parent;
  widget_t *sbox_label = widget_lookup(sbox, "sbox_label", FALSE);
  assert(sbox_label != NULL);

  /* 设置label内容 */
  widget_t *setting = sbox->parent->parent;
  int32_t index = setting_box_get_current_index(setting);
  int32_t len = setting_box_get_select_count(setting);
  index = (index - 1 >= 0) ? index - 1 : len - 1;
  assert(RET_OK == setting_box_setting_index(setting, index));

  /* 同步滑动条信息 */
  widget_t *slider = widget_lookup(setting, "slider", TRUE);
  if (slider != NULL)
  {
    /* 有些带select box的setting(如languages)是没有slider的, 需要判断 */
    slider_set_value(slider, index);
  }
  return RET_OK;
}

static ret_t on_slider_value_changing(void* ctx, event_t* e) {
  value_change_event_t* evt = value_change_event_cast(e);
  // TODO: 在此添加控件事件处理程序代码
  widget_t *slider = WIDGET(e->target);
  widget_t *setting = slider->parent->parent;
  value_t value = {0};
  widget_get_prop(slider, "value", &value);
  setting_box_setting_index(setting, value_int32(&value));
  return RET_OK;
}

static ret_t on_sbox_right_btn_click(void *ctx, event_t *e)
{
  /* 定位setting box */
  widget_t *sbox_btn_right = WIDGET(e->target);
  widget_t *sbox = sbox_btn_right->parent;
  widget_t *sbox_label = widget_lookup(sbox, "sbox_label", FALSE);
  assert(sbox_label != NULL);

  widget_t *setting = sbox->parent->parent;
  int32_t index = setting_box_get_current_index(setting);
  int32_t len = setting_box_get_select_count(setting);
  index = (index + 1) % len;
  assert(RET_OK == setting_box_setting_index(setting, index));

  /* 同步滑动条信息 */
  widget_t *slider = widget_lookup(setting, "slider", TRUE);
  if (slider != NULL)
  {
    /* 有些带select box的setting(如languages)是没有slider的, 需要判断 */
    slider_set_value(slider, index);
  }
  return RET_OK;
}

/**
 * 初始化窗口的子控件
 */
static ret_t visit_init_child(void *ctx, const void *iter)
{
  widget_t *win = WIDGET(ctx);
  widget_t *widget = WIDGET(iter);
  const char *name = widget->name;

  // 初始化指定名称的控件(设置属性或注册事件),请保证控件名称在窗口上唯一
  if (name != NULL && *name != '\0')
  {
    if (tk_str_eq(name, "sbox_right_btn"))
    {
      widget_on(widget, EVT_CLICK, on_sbox_right_btn_click, win);
    }
    else if (tk_str_eq(name, "sbox_left_btn"))
    {
      widget_on(widget, EVT_CLICK, on_sbox_left_btn_click, win);
    } else if (tk_str_eq(name, "slider")) {
      widget_on(widget, EVT_VALUE_CHANGING, on_slider_value_changing, win);
    }
  }

  return RET_OK;
}

/**
 * 初始化窗口
 */
ret_t home_page_init(widget_t *win, void *ctx)
{
  (void)ctx;
  return_value_if_fail(win != NULL, RET_BAD_PARAMS);

  widget_foreach(win, visit_init_child, win);
  widget_t *setting = widget_lookup(win, "v_setting", TRUE);
  assert(setting != NULL);
  setting_box_init(setting);
  return RET_OK;
}

编译环境: 桌面端是awtk designer生成的项目,用的designer自带的sdk,designer是最新版本1.2.2 web端编译部署是用的git上下的awtk,用的6月4号的版本,awtk-web是最新的5月26号版本,不知是不是sdk不一致的缘故

Tracker647 commented 3 months ago

add:label显示的字体偏大偏上 预览: image web: image xml:

  <label name="lbl_depth" x="10" y="125" w="94" h="33" style:normal:border_color="#1a2f4a00" style:normal:icon="cross" style:normal:text_color="#FFFFFF" style:normal:bg_color="#002B6B" style:normal:round_radius="5" style:normal:margin="5" style:normal:font_size="25" style:normal:text_align_v="none" text="10.0m"/>
Tracker647 commented 3 months ago

add:问下桌面端的按键响应在web平台上支持吗,之前有给项目的xml的windows弄key_up和key_down属性,桌面端能切换焦点,但到了浏览器好像就不能

xianjimli commented 3 months ago

你把整个demo压缩后发给我看看。

Tracker647 commented 3 months ago

原c文件: AwtkApplication4.zip awtk-web的webroot对应文件: AwtkApplication4.zip

xianjimli commented 2 months ago
144   assert(RET_OK == setting_box_setting_index(setting, index));

to

144   ENSURE(RET_OK == setting_box_setting_index(setting, index));

可以用 assert 检查函数的返回值,但不要把函数放到 assert 里,否则定义了NDEBUG 时函数就被去掉了。要么就用 AWTK 里的 ENSURE 宏。

xianjimli commented 2 months ago
web_debug

把源代码放到webroot下对应的位置,就可以在浏览器中调试。

Tracker647 commented 2 months ago

解决了 原来是NDEBUG 问题,多谢

Tracker647 commented 2 months ago
web_debug

把源代码放到webroot下对应的位置,就可以在浏览器中调试。

在浏览器上有办法看c/c++文件的变量显示吗,看着默认好像是没有的: image