- 浏览: 9123 次
- 性别:
- 来自: 杭州
最新评论
lis
- 博客分类:
- erlang
%%%-------------------------------------------------------------------
%%% @author Jack Tang <jack@taodinet.com>
%%% @copyright (C) 2014, Jack Tang
%%% @doc
%%%
%%% Conf = [{height, 100}, {width, 200}, {stripe_rows, true}, {id_field, uid}],
%%% ListView = ux_list_view:new(Parent, Conf),
%%% ux_list_view:columns(ListView,
%%% [ #col_def{text = "第一列", data_index = uid, sortable = true, align = right},
%%% #col_def{text = "姓名", data_index = uname} ]),
%%% ux_list_view:tbar([Item1, {Item2, left}, {Item3, right}]),
%%% ux_list_view:bbar([Item1, Item2]),
%%% ux_list_view:reg_handler s([{E1, Fun1}, {E2, Fun2}]),
%%% ux_list_view:load_data(ListView, Data),
%%% ux_list_view:update(ListView).
%%%
%%% @end
%%% Created : 6 Nov 2014 by Jack Tang <jack@taodinet.com>
%%%-------------------------------------------------------------------
-module(ux_list_view).
-behaviour(wx_object).
%% API
-export([new/2,
columns/2,
tbar/2,
bbar/2]).
-export([reg_handlers/2,
load_data/2,
update/1,
clear/1,
destroy/1]).
-export([init/1,
terminate/2,
code_change/3,
handle_info/2,
handle_call/3,
handle_cast/2,
handle_event/2]).
-include_lib("wx/include/wx.hrl").
-include("wxclient.hrl").
-record(state, { parent,
panel,
config,
columns,
id_field,
header_pos,
list_view,
tbar,
bbar,
callbacks,
store }).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% ux_list_view:new(Parent, [{items, Items},{id, ?wxID_ANY},
%% {height, 550}, {width, 600},
%% {stripe_rows, true}, {style, ?wxLC_REPORT bor ?wxLC_SINGLE_SEL}]),
%% @spec
%% @end
%%--------------------------------------------------------------------
new(Parent, Config) ->
NConfig = tuple_list_utils:update({parent, Parent}, Config),
start(NConfig).
start(Config) ->
wx_object:start_link(?MODULE, Config, []).
tbar(This, Items) ->
wx_object:call(This, {tbar, Items}).
bbar(This, Items) ->
wx_object:call(This, {bbar, Items}).
reg_handlers(This, EventAndHandlers) ->
wx_object:call(This, {reg_handlers, EventAndHandlers}).
row_value(This, RowId) ->
wx_object:call(This, {row_value, RowId}).
%%--------------------------------------------------------------------
%% @doc
%% Columns =
%% [#col_def{text = "第1列", data_index = currency, sortable = false, align = right},
%% #col_def{text = "第2列", data_index = uid, sortable = false, align = right},
%% #col_def{text = "第3列", data_index = instrument_id, sortable = false, align = right}],
%% ux_list_view:columns(ListView, Columns),
%% @spec
%% @end
%%--------------------------------------------------------------------
columns(This, Columns) ->
wx_object:call(This, {columns, Columns}).
%%--------------------------------------------------------------------
%% @doc
%% ux_list_view:load_data(Report, Data),
%% @spec
%% @end
%%--------------------------------------------------------------------
load_data(This, Data) ->
wx_object:call(This, {load_data, Data}).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
update(This) ->
wx_object:call(This, update).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
clear(This) ->
wx_object:call(This, clear).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
destroy(This) ->
wx_object:call(This, destroy).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
init(Config) ->
wx:batch(fun() -> do_init(Config) end).
handle_event(#wx{id = Id, event = Event}, #state{store = Store} = State) ->
#state{callbacks = Callbacks, list_view = ListView} = State,
EventSrc = case Event of
#wxCommand{type = Type} -> {Id, Type};
#wxList{type = Type} -> {Id, Type};
_ -> not_supported
end,
case maps:get(EventSrc, Callbacks, undefined) of
undefined -> ok;
Fun ->
Selections = selections(ListView, Store),
Fun(Selections)
end,
{noreply, State}.
handle_call({tbar, TbarItems}, _From, #state{panel = Panel} = State) ->
Tbar = create_bar(Panel, TbarItems),
{reply, ok, State#state{tbar = Tbar}};
handle_call({bbar, BbarItems}, _From, #state{panel = Panel} = State) ->
Bbar = create_bar(Panel, BbarItems),
{reply, ok, State#state{bbar = Bbar}};
handle_call({row_value, RowId}, _From, #state{store = Store} = State) ->
Reply = maps:get(RowId, Store, undefined),
{reply, Reply, State};
handle_call({reg_handlers, EventHandlerMappings}, _From, #state{} = State) ->
Callbacks = lists:foldl(fun({Event, Fun}, Map) ->
maps:put(Event, Fun, Map)
end, #{}, EventHandlerMappings),
{reply, ok, State#state{callbacks = Callbacks}};
handle_call(update, _From, #state{panel = Panel} = State) ->
#state{tbar = Tbar, bbar = Bbar, list_view = ListView} = State,
MainSizer = wxBoxSizer:new(?wxVERTICAL),
case Tbar of
undefined -> ok;
_ -> wxSizer:add(MainSizer, Tbar, [{flag, ?wxEXPAND}])
end,
wxSizer:add(MainSizer, ListView, [{flag, ?wxEXPAND}, {proportion, 1}]),
case Bbar of
undefined -> ok;
_ -> wxSizer:add(MainSizer, Bbar, [{flag, ?wxEXPAND}])
end,
wxPanel:setSizer(Panel, MainSizer),
wxSizer:fit(MainSizer, Panel),
{reply, ok, State};
handle_call({columns, Columns}, _From, State) ->
#state{list_view = ListView, id_field = IdField} = State,
HeaderPos = set_headers(ListView, Columns, IdField),
{reply, ok, State#state{columns = Columns, header_pos = HeaderPos}};
handle_call({load_data, Data}, _From, #state{store = Store} = State) ->
#state{header_pos = HeaderPos, list_view = ListView,
id_field = IdField, store = Store} = State,
[HeaderPosMap, NStore] = insert_rows(ListView, HeaderPos, Data, IdField, Store),
{reply, ok, State#state{header_pos = HeaderPosMap, store = NStore}};
handle_call(clear, _From, #state{list_view = ListView } = State) ->
wxListCtrl:clearAll(ListView),
wxListCtrl:refresh(ListView),
{reply, ok, State#state{header_pos = undefined}};
handle_call(destroy, _From, #state{} = State) ->
{stop, normal, ok, State};
handle_call(_Req, _From, State) ->
lager:error("Can't handle request: ~p", [_Req]),
{reply, {error, invalid_request},State}.
handle_cast(_Msg, State) ->
lager:error("Can't handle msg: ~p", [_Msg]),
{noreply, State}.
handle_info(_Info, State) ->
lager:error("Can't handle info: ~p", [_Info]),
{noreply, State}.
code_change(_, _, State) ->
{stop, ignore, State}.
terminate(_Reason, _State) ->
ok.
%%%===================================================================
%%% Internal functions
%%%===================================================================
do_init(Config) ->
{_, Parent} = tuple_list_utils:keyfind(parent, wx:null(), Config),
{_, IdField} = tuple_list_utils:keyfind(id_field, id, Config),
Style = tuple_list_utils:keyfind(style, ?wxLC_REPORT, Config),
Panel = wxPanel:new(Parent, [{size, wxWindow:getSize(Parent)}, {style, ?wxEXPAND}]),
ListView = wxListCtrl:new(Panel, [Style]),
% add listener
wxListCtrl:connect(ListView, command_list_item_selected, []),
process_flag(trap_exit, true),
{Panel, #state{parent = Parent, config = Config,
id_field = IdField, panel = Panel,
list_view = ListView, store = maps:new()}}.
insert_rows(ListView, undefined, [FirstRow | _] = Data, IdField, Store) ->
HeaderPos =
case FirstRow of
{struct, RowData} when is_list(RowData)->
set_headers(ListView, RowData, IdField);
{obj, RowData} when is_list(RowData)->
set_headers(ListView, RowData, IdField);
Row when is_list(Row) ->
set_headers(ListView, Row, IdField);
_Row ->
#{}
end,
insert_rows(ListView, HeaderPos, Data, IdField, Store);
insert_rows(ListView, HeaderPos, Data, IdField, Store) ->
LastRowNo = wxListCtrl:getItemCount(ListView),
[_, NDStore2] =
lists:foldl(
fun(Row, [RIndex, DStore]) ->
% fill up cells
[RIndex2, RData] = case Row of
{struct, RowData} when is_list(RowData)->
insert_one_row(ListView, HeaderPos, RIndex, RowData),
[RIndex + 1, RowData];
{obj, RowData} when is_list(RowData)->
insert_one_row(ListView, HeaderPos, RIndex, RowData),
[RIndex + 1, RowData];
Row when is_list(Row) ->
insert_one_row(ListView, HeaderPos, RIndex, Row),
[RIndex + 1, Row];
_Row ->
[RIndex, undefined]
end,
NDStore = case RData of
undefined -> DStore;
_ ->
case tuple_list_utils:keyfind(IdField, RData) of
{_, undefined} -> DStore;
{_, IdVal} ->
IdValStr = type_utils:any_to_list(IdVal),
maps:put(IdValStr, RData, DStore)
end
end,
[RIndex2, NDStore]
end, [LastRowNo, Store], Data),
[HeaderPos, NDStore2].
create_bar(Panel, Items) ->
ItemNumber = length(lists:flatten(Items)),
LeftSizer = wxFlexGridSizer:new(1, ItemNumber, 0, 0),
RightSizer = wxFlexGridSizer:new(1, ItemNumber, 0, 0),
lists:foreach(
fun(Item) ->
Wx2 = case Item of
{Wx, left} ->
wxWindow:reparent(Wx, Panel),
wxSizer:add(LeftSizer, Wx, [{proportion, 0}, {flag, ?wxALIGN_CENTER}]),
Wx;
{Wx, right} ->
wxWindow:reparent(Wx, Panel),
wxSizer:add(RightSizer, Wx, [{proportion, 0}, {flag, ?wxALIGN_CENTER}]),
Wx;
Wx ->
wxWindow:reparent(Wx, Panel),
wxSizer:add(LeftSizer, Wx, [{proportion, 0}, {flag, ?wxALIGN_CENTER}]),
Wx
end,
wxWindow:connect(Wx2, command_button_clicked)
end, Items),
MainSizer = wxBoxSizer:new(?wxHORIZONTAL),
wxSizer:add(MainSizer, LeftSizer),
wxSizer:add(MainSizer, 60 ,20, [{proportion, 1}, {flag, ?wxEXPAND}]),
wxSizer:add(MainSizer, RightSizer),
MainSizer.
set_headers(Report, Columns, IdField) ->
HeaderPosMap = maps:new(),
% setup id cell
IdHeaderCell = set_header_cell([{width, 0}, {text, "ID"}]),
wxListCtrl:insertColumn(Report, 0, IdHeaderCell),
NHeaderPosMap = map_utils:append(IdField, [0], HeaderPosMap),
[HeaderPosMap2, _] =
lists:foldl(
fun(Column, [HeaderPos, Index]) ->
[HeaderCol, DIndex] =
case Column of
#col_def{} ->
#col_def{text = Text, data_index = DataIndex,
sortable = Sortable, align = Align,
width = Width} = Column,
% validate DataIndex, it should exist!
[set_header_cell([{align, Align}, {width, Width}, {text, Text}]),
DataIndex];
{Field, _} ->
[set_header_cell([{text, type_utils:any_to_list(Field)}]), Field]
end,
wxListCtrl:insertColumn(Report, Index, HeaderCol),
[map_utils:append(DIndex, [Index], HeaderPos), Index + 1]
end, [NHeaderPosMap, 1], Columns),
HeaderPosMap2.
set_header_cell(Props) ->
HeaderCol = wxListItem:new(),
{align, Align} = tuple_list_utils:keyfind(align, ?wxLIST_FORMAT_LEFT, Props),
{text, Text} = tuple_list_utils:keyfind(text, "", Props),
wxListItem:setAlign(HeaderCol, Align),
% case tuple_list_utils:keyfind(width, undefined, Props) of
case tuple_list_utils:keyfind(width, 50, Props) of
{_, undefined} ->
ok;
{_, Width} ->
wxListItem:setWidth(HeaderCol, Width)
end,
wxListItem:setText(HeaderCol, Text),
HeaderCol.
insert_one_row(ListView, HeaderPos, RIndex, RowData) ->
% wxListCtrl:insertItem(ListView, RIndex),
wxListCtrl:insertItem(ListView, RIndex, ""),
maps:fold(fun(DIndex, CIndexList, Acc) ->
lists:foreach(
fun(CIndex) ->
{_, Val} = tuple_list_utils:keyfind(DIndex, "N/A", RowData),
Cell = wxListItem:new(),
wxListItem:setId(Cell, RIndex),
wxListItem:setColumn(Cell, CIndex),
wxListItem:setText(Cell, type_utils:any_to_list(Val)),
wxListCtrl:setItem(ListView, Cell)
end, CIndexList)
end, [], HeaderPos).
selections(ListView, Store) ->
SelectedCount = wxListCtrl:getSelectedItemCount(ListView),
Cell = wxListItem:new(),
{Selections, _LastSelected} =
lists:foldl(
fun(_Seq, {Sel, NextItem}) ->
NextSelectedItem = wxListCtrl:getNextItem(ListView, NextItem,
[{state, ?wxLIST_STATE_SELECTED}]),
wxListItem:setId(Cell, NextSelectedItem),
wxListCtrl:getItem(ListView, Cell),
SelectedId = wxListItem:getText(Cell),
Selected = maps:get(SelectedId, Store, undefined),
{lists:append(Sel, [Selected]), NextSelectedItem}
end, {[], -1}, lists:seq(1, SelectedCount)),
Selections.
%%% @author Jack Tang <jack@taodinet.com>
%%% @copyright (C) 2014, Jack Tang
%%% @doc
%%%
%%% Conf = [{height, 100}, {width, 200}, {stripe_rows, true}, {id_field, uid}],
%%% ListView = ux_list_view:new(Parent, Conf),
%%% ux_list_view:columns(ListView,
%%% [ #col_def{text = "第一列", data_index = uid, sortable = true, align = right},
%%% #col_def{text = "姓名", data_index = uname} ]),
%%% ux_list_view:tbar([Item1, {Item2, left}, {Item3, right}]),
%%% ux_list_view:bbar([Item1, Item2]),
%%% ux_list_view:reg_handler s([{E1, Fun1}, {E2, Fun2}]),
%%% ux_list_view:load_data(ListView, Data),
%%% ux_list_view:update(ListView).
%%%
%%% @end
%%% Created : 6 Nov 2014 by Jack Tang <jack@taodinet.com>
%%%-------------------------------------------------------------------
-module(ux_list_view).
-behaviour(wx_object).
%% API
-export([new/2,
columns/2,
tbar/2,
bbar/2]).
-export([reg_handlers/2,
load_data/2,
update/1,
clear/1,
destroy/1]).
-export([init/1,
terminate/2,
code_change/3,
handle_info/2,
handle_call/3,
handle_cast/2,
handle_event/2]).
-include_lib("wx/include/wx.hrl").
-include("wxclient.hrl").
-record(state, { parent,
panel,
config,
columns,
id_field,
header_pos,
list_view,
tbar,
bbar,
callbacks,
store }).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% ux_list_view:new(Parent, [{items, Items},{id, ?wxID_ANY},
%% {height, 550}, {width, 600},
%% {stripe_rows, true}, {style, ?wxLC_REPORT bor ?wxLC_SINGLE_SEL}]),
%% @spec
%% @end
%%--------------------------------------------------------------------
new(Parent, Config) ->
NConfig = tuple_list_utils:update({parent, Parent}, Config),
start(NConfig).
start(Config) ->
wx_object:start_link(?MODULE, Config, []).
tbar(This, Items) ->
wx_object:call(This, {tbar, Items}).
bbar(This, Items) ->
wx_object:call(This, {bbar, Items}).
reg_handlers(This, EventAndHandlers) ->
wx_object:call(This, {reg_handlers, EventAndHandlers}).
row_value(This, RowId) ->
wx_object:call(This, {row_value, RowId}).
%%--------------------------------------------------------------------
%% @doc
%% Columns =
%% [#col_def{text = "第1列", data_index = currency, sortable = false, align = right},
%% #col_def{text = "第2列", data_index = uid, sortable = false, align = right},
%% #col_def{text = "第3列", data_index = instrument_id, sortable = false, align = right}],
%% ux_list_view:columns(ListView, Columns),
%% @spec
%% @end
%%--------------------------------------------------------------------
columns(This, Columns) ->
wx_object:call(This, {columns, Columns}).
%%--------------------------------------------------------------------
%% @doc
%% ux_list_view:load_data(Report, Data),
%% @spec
%% @end
%%--------------------------------------------------------------------
load_data(This, Data) ->
wx_object:call(This, {load_data, Data}).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
update(This) ->
wx_object:call(This, update).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
clear(This) ->
wx_object:call(This, clear).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
destroy(This) ->
wx_object:call(This, destroy).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
init(Config) ->
wx:batch(fun() -> do_init(Config) end).
handle_event(#wx{id = Id, event = Event}, #state{store = Store} = State) ->
#state{callbacks = Callbacks, list_view = ListView} = State,
EventSrc = case Event of
#wxCommand{type = Type} -> {Id, Type};
#wxList{type = Type} -> {Id, Type};
_ -> not_supported
end,
case maps:get(EventSrc, Callbacks, undefined) of
undefined -> ok;
Fun ->
Selections = selections(ListView, Store),
Fun(Selections)
end,
{noreply, State}.
handle_call({tbar, TbarItems}, _From, #state{panel = Panel} = State) ->
Tbar = create_bar(Panel, TbarItems),
{reply, ok, State#state{tbar = Tbar}};
handle_call({bbar, BbarItems}, _From, #state{panel = Panel} = State) ->
Bbar = create_bar(Panel, BbarItems),
{reply, ok, State#state{bbar = Bbar}};
handle_call({row_value, RowId}, _From, #state{store = Store} = State) ->
Reply = maps:get(RowId, Store, undefined),
{reply, Reply, State};
handle_call({reg_handlers, EventHandlerMappings}, _From, #state{} = State) ->
Callbacks = lists:foldl(fun({Event, Fun}, Map) ->
maps:put(Event, Fun, Map)
end, #{}, EventHandlerMappings),
{reply, ok, State#state{callbacks = Callbacks}};
handle_call(update, _From, #state{panel = Panel} = State) ->
#state{tbar = Tbar, bbar = Bbar, list_view = ListView} = State,
MainSizer = wxBoxSizer:new(?wxVERTICAL),
case Tbar of
undefined -> ok;
_ -> wxSizer:add(MainSizer, Tbar, [{flag, ?wxEXPAND}])
end,
wxSizer:add(MainSizer, ListView, [{flag, ?wxEXPAND}, {proportion, 1}]),
case Bbar of
undefined -> ok;
_ -> wxSizer:add(MainSizer, Bbar, [{flag, ?wxEXPAND}])
end,
wxPanel:setSizer(Panel, MainSizer),
wxSizer:fit(MainSizer, Panel),
{reply, ok, State};
handle_call({columns, Columns}, _From, State) ->
#state{list_view = ListView, id_field = IdField} = State,
HeaderPos = set_headers(ListView, Columns, IdField),
{reply, ok, State#state{columns = Columns, header_pos = HeaderPos}};
handle_call({load_data, Data}, _From, #state{store = Store} = State) ->
#state{header_pos = HeaderPos, list_view = ListView,
id_field = IdField, store = Store} = State,
[HeaderPosMap, NStore] = insert_rows(ListView, HeaderPos, Data, IdField, Store),
{reply, ok, State#state{header_pos = HeaderPosMap, store = NStore}};
handle_call(clear, _From, #state{list_view = ListView } = State) ->
wxListCtrl:clearAll(ListView),
wxListCtrl:refresh(ListView),
{reply, ok, State#state{header_pos = undefined}};
handle_call(destroy, _From, #state{} = State) ->
{stop, normal, ok, State};
handle_call(_Req, _From, State) ->
lager:error("Can't handle request: ~p", [_Req]),
{reply, {error, invalid_request},State}.
handle_cast(_Msg, State) ->
lager:error("Can't handle msg: ~p", [_Msg]),
{noreply, State}.
handle_info(_Info, State) ->
lager:error("Can't handle info: ~p", [_Info]),
{noreply, State}.
code_change(_, _, State) ->
{stop, ignore, State}.
terminate(_Reason, _State) ->
ok.
%%%===================================================================
%%% Internal functions
%%%===================================================================
do_init(Config) ->
{_, Parent} = tuple_list_utils:keyfind(parent, wx:null(), Config),
{_, IdField} = tuple_list_utils:keyfind(id_field, id, Config),
Style = tuple_list_utils:keyfind(style, ?wxLC_REPORT, Config),
Panel = wxPanel:new(Parent, [{size, wxWindow:getSize(Parent)}, {style, ?wxEXPAND}]),
ListView = wxListCtrl:new(Panel, [Style]),
% add listener
wxListCtrl:connect(ListView, command_list_item_selected, []),
process_flag(trap_exit, true),
{Panel, #state{parent = Parent, config = Config,
id_field = IdField, panel = Panel,
list_view = ListView, store = maps:new()}}.
insert_rows(ListView, undefined, [FirstRow | _] = Data, IdField, Store) ->
HeaderPos =
case FirstRow of
{struct, RowData} when is_list(RowData)->
set_headers(ListView, RowData, IdField);
{obj, RowData} when is_list(RowData)->
set_headers(ListView, RowData, IdField);
Row when is_list(Row) ->
set_headers(ListView, Row, IdField);
_Row ->
#{}
end,
insert_rows(ListView, HeaderPos, Data, IdField, Store);
insert_rows(ListView, HeaderPos, Data, IdField, Store) ->
LastRowNo = wxListCtrl:getItemCount(ListView),
[_, NDStore2] =
lists:foldl(
fun(Row, [RIndex, DStore]) ->
% fill up cells
[RIndex2, RData] = case Row of
{struct, RowData} when is_list(RowData)->
insert_one_row(ListView, HeaderPos, RIndex, RowData),
[RIndex + 1, RowData];
{obj, RowData} when is_list(RowData)->
insert_one_row(ListView, HeaderPos, RIndex, RowData),
[RIndex + 1, RowData];
Row when is_list(Row) ->
insert_one_row(ListView, HeaderPos, RIndex, Row),
[RIndex + 1, Row];
_Row ->
[RIndex, undefined]
end,
NDStore = case RData of
undefined -> DStore;
_ ->
case tuple_list_utils:keyfind(IdField, RData) of
{_, undefined} -> DStore;
{_, IdVal} ->
IdValStr = type_utils:any_to_list(IdVal),
maps:put(IdValStr, RData, DStore)
end
end,
[RIndex2, NDStore]
end, [LastRowNo, Store], Data),
[HeaderPos, NDStore2].
create_bar(Panel, Items) ->
ItemNumber = length(lists:flatten(Items)),
LeftSizer = wxFlexGridSizer:new(1, ItemNumber, 0, 0),
RightSizer = wxFlexGridSizer:new(1, ItemNumber, 0, 0),
lists:foreach(
fun(Item) ->
Wx2 = case Item of
{Wx, left} ->
wxWindow:reparent(Wx, Panel),
wxSizer:add(LeftSizer, Wx, [{proportion, 0}, {flag, ?wxALIGN_CENTER}]),
Wx;
{Wx, right} ->
wxWindow:reparent(Wx, Panel),
wxSizer:add(RightSizer, Wx, [{proportion, 0}, {flag, ?wxALIGN_CENTER}]),
Wx;
Wx ->
wxWindow:reparent(Wx, Panel),
wxSizer:add(LeftSizer, Wx, [{proportion, 0}, {flag, ?wxALIGN_CENTER}]),
Wx
end,
wxWindow:connect(Wx2, command_button_clicked)
end, Items),
MainSizer = wxBoxSizer:new(?wxHORIZONTAL),
wxSizer:add(MainSizer, LeftSizer),
wxSizer:add(MainSizer, 60 ,20, [{proportion, 1}, {flag, ?wxEXPAND}]),
wxSizer:add(MainSizer, RightSizer),
MainSizer.
set_headers(Report, Columns, IdField) ->
HeaderPosMap = maps:new(),
% setup id cell
IdHeaderCell = set_header_cell([{width, 0}, {text, "ID"}]),
wxListCtrl:insertColumn(Report, 0, IdHeaderCell),
NHeaderPosMap = map_utils:append(IdField, [0], HeaderPosMap),
[HeaderPosMap2, _] =
lists:foldl(
fun(Column, [HeaderPos, Index]) ->
[HeaderCol, DIndex] =
case Column of
#col_def{} ->
#col_def{text = Text, data_index = DataIndex,
sortable = Sortable, align = Align,
width = Width} = Column,
% validate DataIndex, it should exist!
[set_header_cell([{align, Align}, {width, Width}, {text, Text}]),
DataIndex];
{Field, _} ->
[set_header_cell([{text, type_utils:any_to_list(Field)}]), Field]
end,
wxListCtrl:insertColumn(Report, Index, HeaderCol),
[map_utils:append(DIndex, [Index], HeaderPos), Index + 1]
end, [NHeaderPosMap, 1], Columns),
HeaderPosMap2.
set_header_cell(Props) ->
HeaderCol = wxListItem:new(),
{align, Align} = tuple_list_utils:keyfind(align, ?wxLIST_FORMAT_LEFT, Props),
{text, Text} = tuple_list_utils:keyfind(text, "", Props),
wxListItem:setAlign(HeaderCol, Align),
% case tuple_list_utils:keyfind(width, undefined, Props) of
case tuple_list_utils:keyfind(width, 50, Props) of
{_, undefined} ->
ok;
{_, Width} ->
wxListItem:setWidth(HeaderCol, Width)
end,
wxListItem:setText(HeaderCol, Text),
HeaderCol.
insert_one_row(ListView, HeaderPos, RIndex, RowData) ->
% wxListCtrl:insertItem(ListView, RIndex),
wxListCtrl:insertItem(ListView, RIndex, ""),
maps:fold(fun(DIndex, CIndexList, Acc) ->
lists:foreach(
fun(CIndex) ->
{_, Val} = tuple_list_utils:keyfind(DIndex, "N/A", RowData),
Cell = wxListItem:new(),
wxListItem:setId(Cell, RIndex),
wxListItem:setColumn(Cell, CIndex),
wxListItem:setText(Cell, type_utils:any_to_list(Val)),
wxListCtrl:setItem(ListView, Cell)
end, CIndexList)
end, [], HeaderPos).
selections(ListView, Store) ->
SelectedCount = wxListCtrl:getSelectedItemCount(ListView),
Cell = wxListItem:new(),
{Selections, _LastSelected} =
lists:foldl(
fun(_Seq, {Sel, NextItem}) ->
NextSelectedItem = wxListCtrl:getNextItem(ListView, NextItem,
[{state, ?wxLIST_STATE_SELECTED}]),
wxListItem:setId(Cell, NextSelectedItem),
wxListCtrl:getItem(ListView, Cell),
SelectedId = wxListItem:getText(Cell),
Selected = maps:get(SelectedId, Store, undefined),
{lists:append(Sel, [Selected]), NextSelectedItem}
end, {[], -1}, lists:seq(1, SelectedCount)),
Selections.
相关推荐
LIS3DH是一种超低功耗的三轴线性加速度计,属于“nano”系列。本文档提供了详实的数据参数,特性,应用以及封装信息。带有数字I2C / SPI串行接口标准输出, 装置具有超低功耗运行模式允许先进的节电和智能嵌入式功能...
LIS2DH12TR,LIS3DH应用笔记,lis3dhrt,3axis
单片机驱动LIS3DH,很详细的源码文档。
陀螺仪LIS3DH驱动程序,没有工程,LIS3DH驱动程序,使用都可以根据例程来写,只要再写两条程序就行了,在驱动程序中的读与写程序。
LIS接口:接收仪器的请求(query);在LIS系统中检索该条码的测试项目(item);将测试的item转化为仪器的通道号(code)。这种通道号在不同的仪器中是不同定义的,所以LIS中一定会有一个相关仪器的通道与测试项目的...
lis串口通讯工具,用于lis调试接口时通讯使用,简单方便高效!
LIS3DH 资料_完整例程_手册_电路等
本资源为ST公司官方LIS3DH 、LIS3DSH驱动及例子。资源解压后的driver文件夹可直接在你的工程中应用:The driver is platform independent, you need only to complete the two functions for write and read from ...
ST的三轴传感器 LIS2DH12和LIS2DW12的单双击 配置代码,寄存器配置,以及ODR的设置,还有阈值配置的算法,双击的中间间隔的算法
PB版LIS系统,数据库是oracle,源码+数据库,分享给大家
lis3mdl参考手册 介绍了lis3mdl芯片的使用指南 包括寄存器的用途和使用规则
LIS2DW12应用手册
使用LIS3DH的高通滤波器过滤重力加速度,产生阈值中断。代码基于华大单片机HC32L110C6PA,使用时只要移植source目录中的LIS3DH文件夹
accelerometer lis3dh datasheet
LIS3DH中文应用文档.zip
之前使用STM32的硬件IIC(基于HAL库)调试了ST的LIS2MDL磁力计,现将写的驱动文件分享给有需要的同学。
LIS3DH具有超低功耗工作模式,可实现高级节能,智能睡眠唤醒以及恢复睡眠功能。
LIS系统逐步采用了智能辅助功能来处理大信息量的检验工作,即LIS系统不仅是自动接收检验数据,打印检验报告,系统保存检验信息的工具,而且可根据实验室的需要实现智能辅助功能。随着IT技术的不断发展,人工智能在...
LIS与ISO 15189 早期的LIS侧重于对检验数据的处理,和实验室管理者的关系不大,但实验室在经历了检验设备不断更新、试剂耗材商品化、质量管理制度化的过程后,公众对检验质量及服务质量的要求也越来越高,这使得...
迈瑞BS系列 LIS协议接口