<!--
 * 【界面概述】
 * 展示MetroWidget控件的用法
 *
 * 【控件介绍】
 * MetroWidget:
 *      top {int} 控件的y，默认为0
 *      left {int} 控件的x， 默认为0
 *      width {int} (必选)控件的宽
 *      height {int} (必选)控件的高
 *
 *      name {string} (必选)用于设置焦点的名称
 *      padding {object} 控件内边距， 默认为{left: 0, right: 0, top: 0, bottom: 0}
 *      direction {enum} (必选)控件方向 HROIZONTAL/VERTICAL
 *      loopFocus {boolean} 焦点到边界后自动转到下一行，默认false
 *      initFocusId {int} 初始焦点，默认为0
 *      slideStyle {SlideStyle} 页面滑动类型 seamless/wholepage
 *      slideSpeed {float} 页面滑动速度，默认为1.5
 *      slideEasing {string} 页面滑动动画easing

 *      data {array} (必选)数据列表
 *      dispatcher {SWidgetDispatcher} 用于设置MetroWidget控件内部的状态，默认为null
 *      measures {function} (必选)返回item的模板信息的回调,
 *                              @params item {object} data中的数据
 *                              @return 模板信息，
                                        {
                                          width: item的宽,
                                          height: item的高,
                                          focusable: item是否可以获得焦点,
                                        }
 *
 *      onClick {function} item点击回调
 *                @params item data中的数据
 *      onFocus {function} 控件获取焦点的回调
 *      onBlur {function} 控件失去焦点的回调
 *      onEdge {function} 焦点移动到边缘时的回调
 *              @params {"direction": {EdgeDirection}边缘方向, "rect": 到达边缘时的区域{x: 0, y: 0, width: 0,height: 0}}
 *
 *      enableTouch {boolean} 支持触控
 *      loadAll {boolean} 加载不显示的view，触控场景使用
 *
 * 【技巧说明】
 * Q: 插槽props如何使用？
 * A: data: 当前item的数据
 *    query: 获取一些额外信息的对象
                { 
                  id: {int} item的id,
                  position: {Function} 获取item坐标的函数
                                            @params id {int} item的id
                                            @return {object} item的位置 {xPos, yPos, width, height}
                }
 *    onEdge: 若单元格内另有可接管按键的控件（如MetroWidget），该控件到达边缘需要通知MetroWidget时的回调
 *    onAction: 单元格内控件需要通过onAction.register方法向MetroWidget注册onFocus， onBlur， onClick
 * 
 * Q: 如何进行布局，定制每个格的尺寸？
 * A: 首先选定一个布局的方式，一列列地横向布局(HROIZONTAL)还是一行行地纵向(VERTICAL)布局，设置给属性direction
 *    然后将单元格尺寸反馈器(函数)设置到measures中，进行布局时，组件会回调measures函数获得每个单元格的尺寸，
 *    当一列放满单元格后(如果是纵向布局，则是一行放满后)，自动换列去布局下一列。
 *
 * Q: 单元格的普通状态，焦点状态，失焦状态如何渲染？
 * A: 在单元的控件中通过往onAction注册的onFocus，onBlur控制显示
 *
 * Q: 控件中的导航处理(上下左右，OK键)需要什么响应的开发？
 * A: 上下左右键已经由控件接管，不需要开发者额外处理，上下左右键会触发翻页时间，翻页的形式由属性slideStyle来定制。
 *    另外，通过OnClick属性可以注册按键回调函数，来处理用户的OK键动作。
 *
 * Q: 边缘格获取焦点放大后显示不全？
 * A: 设置padding，注意item的排布范围是控件的宽高减去对应的padding
 *
 * Q: 焦点怎么移出控件？
 * A: 当焦点移动到控件边缘时，会调用onEdge回调。在回调中通过参数传递的值来决定焦点转移的行为
-->

<script setup>
import { data1, data2, data3 } from "./data";
import Item from "./components/ContentItem.vue";
import MyTab from "./components/MyTab.vue";
import { shallowRef, onMounted, onBeforeUnmount } from "vue";
import { useRouter } from "vue-router";
import {
  VERTICAL,
  MetroWidget,
  EdgeDirection,
  jJsvRuntimeBridge,
  useFocusHub,
} from "jsview";

const router = useRouter();
const focusHub = useFocusHub();
let contentData = data1;
let requestDataTime = 0;
const mwRef = shallowRef(null);

const onKeyDown = (ev) => {
  // 8:Backspace, 27:Escape, 10000:盒子返回键
  if (ev.keyCode == 8 || ev.keyCode == 27 || ev.keyCode == 10000) {
    router.go(-1); // 有router时，是从DemoHomepage进入，回退
    return true;
  }
  return false;
};

const provideData = () => {
  return contentData;
};
const measures = () => {
  return {
    width: 227,
    height: 351,
    focusable: true,
  };
};
const onFocus = () => {
  focusHub.setFocus("mw");
};
const onWidgetEdge = (edge) => {
  if (edge.direction === EdgeDirection.top) {
    focusHub.setFocus("tab");
  }
};
const onTabEdge = () => {
  focusHub.setFocus("mw");
};
const onItemFocus = (id) => {
  if (requestDataTime != 0) {
    clearTimeout(requestDataTime);
    requestDataTime = 0;
  }
  // requestDataTime = setTimeout(() => {
    switch (id) {
      case 0:
        contentData = data1;
        break;
      case 1:
        contentData = data2;
        break;
      case 2:
        contentData = data3;
        break;
    }
    mwRef.value?.refreshData(true);
  // }, 0);
};

onBeforeUnmount(() => {
  if (requestDataTime != 0) {
    clearTimeout(requestDataTime);
    requestDataTime = 0;
  }
});

onMounted(() => {
  jJsvRuntimeBridge.notifyPageLoaded();
});
</script>

<template>
  <jsv-focus-block
    ref="rootNode"
    autoFocus
    :onKeyDown="onKeyDown"
    :onFocus="onFocus"
  >
    <div class="rootSize">
      <div :style="{ left: 50, top: 50 }">
        <my-tab name="tab" :onEdgeDown="onTabEdge" :onItemFocus="onItemFocus" />
      </div>

      <div class="widgetPos">
        <metro-widget
          name="mw"
          ref="mwRef"
          :provideData="provideData"
          :width="1253"
          :height="600"
          :padding="{ left: 26, top: 36, right: 26, bottom: 36 }"
          :direction="VERTICAL"
          :measures="measures"
          :onEdge="onWidgetEdge"
        >
          <template #renderItem="{ data, query, onEdge, onAction }">
            <Item
              :data="data"
              :query="query"
              :onEdge="onEdge"
              :onAction="onAction"
            />
          </template>
        </metro-widget>
      </div>
    </div>
  </jsv-focus-block>
</template>

<style scoped>
.rootSize {
  top: 0;
}

.widgetPos {
  top: 120;
  left: 50;
}

.focusPos {
  top: 10;
  left: 10;
}
</style>