-module(list_ctrl).
-behaviour(wx_object).
%% wx_object callbacks
-export([new/0, start/1, destroy/0]).
-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").
-define(FIRST_COL, 0).
-define(SECOND_COL, 1).
-define(THIRD_COL, 2).
-record(state, {frame,
panel,
list
}).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
new() ->
_WX = wx:new(),
Size = {size, {400, 600}},
Pos = {pos, {200, 300}},
Style = {style, ?wxDEFAULT_FRAME_STYLE bor ?wxMAXIMIZE},
NOptions = [Pos, Size, Style],
Frame = makeFrame("wxListCtrl 总结", NOptions),
start([{parent, Frame}]).
start(Config) ->
wx_object:start_link({local, ?MODULE}, ?MODULE, Config, []).
destroy() ->
wx_object:call(?MODULE, shutdown).
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
init(Config) ->
wx:batch(fun() -> do_init(Config) end).
handle_info(_Msg, State) ->
{noreply, State}.
handle_call(shutdown, _From, #state{panel = Panel} = State) ->
wxFrame:destroy(Panel),
{stop, normal, ok, State};
handle_call(_Msg, _From, State) ->
{reply, {error, ?MODULE},State}.
handle_cast(_Msg, State) ->
{noreply,State}.
%%单击选中某一行,默认情况下可以多选
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_item_selected}}, State) ->
io:format("Item ~p selected.\n",[Item]),
{noreply, State};
%%windows下单击第二次是编辑状态,但Linux下是dselect,而且即使有图标window下是可以编辑的
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_item_deselected}}, State) ->
io:format("Item ~p command_list_item_deselected.\n",[Item]),
{noreply, State};
%%双击左键
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_item_activated}}, State) ->
io:format("Item ~p command_list_item_activated.\n",[Item]),
{noreply, State};
%%单击右键,事件处理首先获取编辑前的item的label
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_item_right_click}},
#state{list = ListCtrl2} = State) ->
io:format("Item ~p, Text = ~p, command_list_item_right_click.\n",
[Item, wxListCtrl:getItemText(ListCtrl2, Item)]),
{noreply, State};
%%开始用左键拖拽item
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_begin_drag}}, State) ->
io:format("Item ~p command_list_begin_drag.\n",[Item]),
{noreply, State};
%%开始用右键拖拽item,事件处理:删除拖拽的item
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_begin_rdrag}},
#state{list = ListCtrl2} = State) ->
io:format("Item ~p command_list_begin_rrrrrdrag.\n",[Item]),
wxListCtrl:deleteItem(ListCtrl2, Item),
{noreply, State};
%%删除item
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_delete_item}}, State) ->
io:format("Item ~p command_list_delete_item.\n",[Item]),
{noreply, State};
%%开始编辑某个item的labl
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_begin_label_edit}}, State) ->
io:format("Item ~p command_list_begin_label_edit.\n",[Item]),
{noreply, State};
%%item的label编辑完成,点击Enter之后
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_end_label_edit}},
#state{list = ListCtrl2} = State) ->
io:format("the Item data now is ~p~n", [wxListCtrl:getItemData(ListCtrl2, Item)]),
io:format("Item ~p command_list_end_label_edit.\n",[Item]),
{noreply, State};
%%插入item
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_insert_item}},
#state{list = ListCtrl2} = State) ->
io:format("Item ~p command_list_insert_item.\n",[Item]),
{noreply, State};
%%左键选择某一列
handle_event(#wx{event = #wxList{itemIndex = Item, col = Col, type = command_list_col_click}}, State) ->
io:format("Item ~p, Col = ~p command_list_col_click.\n",[Item, Col]),
{noreply, State};
%%右键选择某一列
handle_event(#wx{event = #wxList{itemIndex = Item, type = command_list_col_right_click}}, State) ->
io:format("Item ~p command_list_col_right_click.\n",[Item]),
{noreply, State};
%%在list中按下按键,并捕获按键
handle_event(#wx{event = #wxList{itemIndex = Item, code = Code, type = command_list_key_down}},
#state{list = ListCtrl2} = State) ->
io:format("Item ~p ,Text = ~p, Code = ~p.\n", [Item, Code, wxListCtrl:getItemText(ListCtrl2, Item)]),
case Code of
%%重新按照item关联的数据排序
$a ->
io:format("begin resort_accord_to_integer_item~n"),
resort_accord_to_integer_item(ListCtrl2);
$d ->
io:format("delete allItems~n"),
%%删除所有的item
% wxListCtrl:deleteAllItems(ListCtrl2);
% wxListCtrl:deleteColumn(ListCtrl2, 1);
%%删除item
% wxListCtrl:deleteItem (ListCtrl2, 1);
%%给第五行item重新设置label
wxListCtrl:clearAll(ListCtrl2),
wxListCtrl:insertColumn(ListCtrl2, ?FIRST_COL, "First New", []),
wxListCtrl:insertColumn(ListCtrl2, ?SECOND_COL, "Second New", []),
wxListCtrl:insertColumn(ListCtrl2, ?THIRD_COL, "Third New", []);
$i ->
io:format("setLabel"),
wxListCtrl:setItemText(ListCtrl2, 5, "setItemText");
%%给所选择行,第一列设置关联图标列表中第二个图标
$s ->
io:format("setItemColumnImage"),
wxListCtrl:setItemColumnImage(ListCtrl2, Item, 1, 2);
%%新加入一行和一列
$n ->
ListItem = wxListItem:new(),
wxListItem:setId(ListItem, wxListCtrl:getItemCount(ListCtrl2)),
wxListItem:setBackgroundColour(ListItem, {0, 0, 0, 255}),
wxListItem:setText(ListItem, "wxListItem"),
wxListCtrl:insertItem (ListCtrl2, ListItem),
ListColumn = wxListItem:new(),
wxListItem:setText (ListColumn, "wxListItem:setText"),
io:format("getColumnCount = ~p~n", [wxListCtrl:getColumnCount(ListCtrl2)]),
wxListCtrl:insertColumn(ListCtrl2, wxListCtrl:getColumnCount(ListCtrl2), "NewColumn", []),
wxListCtrl:setColumn(ListCtrl2, wxListCtrl:getColumnCount(ListCtrl2), ListColumn);
%%获取每一页中item个数,以及给list设置为黑色
$c ->
Re = wxListCtrl:getCountPerPage(ListCtrl2),
io:format("getCountPerPage = ~p~n", [Re]),
wxListCtrl:setBackgroundColour(ListCtrl2, {0,0,0,255});
%%从第三个item开始查找label为“4”的item
$f ->
Result = wxListCtrl:findItem(ListCtrl2, 3, "4", [{partial, true}]),
io:format("find Result = ~p~n", [Result]);
%5设置第三个item可以编辑
$e ->
io:format("Editable~n"),
wxListCtrl:editLabel(ListCtrl2, 3);
%%获取item空间大小,并设置第一个item的label为蓝色
$p ->
io:format("Rect = ~p~n", [wxListCtrl:getItemRect(ListCtrl2, 1)]),
io:format("getColumnWidth = ~p~n", [wxListCtrl:getColumnWidth(ListCtrl2, 1)]),
io:format("getColumnCount = ~p~n", [wxListCtrl:getColumnCount(ListCtrl2)]),
io:format("Spacing = ~p~n", [wxListCtrl:getItemSpacing(ListCtrl2)]),
wxListCtrl:setItemTextColour(ListCtrl2, 1, ?wxBLUE),
io:format("position = ~p~n", [wxListCtrl:getItemPosition(ListCtrl2, 1)]);
_ ->
ok
end,
{noreply, State};
handle_event(#wx{}, #state{} = State) ->
{noreply, State}.
code_change(_, _, State) ->
{stop, ignore, State}.
terminate(_Reason, _State) ->
ok.
%%%===================================================================
%%% Internal functions
%%%===================================================================
do_init(Config) ->
Parent = proplists:get_value(parent, Config),
Panel = wxPanel:new(Parent, []),
MainSizer = wxStaticBoxSizer:new(?wxVERTICAL, Panel,
[{label, "wxListCtrl "}]),
Notebook = wxNotebook:new(Panel, 1, [{style, ?wxBK_DEFAULT}]),
%% style 1: wxLC_LIST风格的wxListCtrl,
ListCtrl1 = wxListCtrl:new(Notebook, [{style, ?wxLC_LIST bor ?wxLC_EDIT_LABELS}]),
[wxListCtrl:insertItem(ListCtrl1, Int, "Item "++integer_to_list(Int)) ||
Int
ListCtrl = wxListCtrl:new(Win, Options),
wxListCtrl:insertColumn(ListCtrl, ?FIRST_COL, "First Col", []),
wxListCtrl:insertColumn(ListCtrl, ?SECOND_COL, "Second Col", []),
wxListCtrl:insertColumn(ListCtrl, ?THIRD_COL, "Third Col", []),
Fun =
fun(Int) ->
Name = integer_to_list(Int),
wxListCtrl:insertItem(ListCtrl, Int, ""),
wxListCtrl:setItem(ListCtrl, Int, ?FIRST_COL, Name),
wxListCtrl:setItem(ListCtrl, Int, ?SECOND_COL, "Second "++Name),
wxListCtrl:setItem(ListCtrl, Int, ?THIRD_COL, "Third "++Name),
wxListCtrl:setItemData(ListCtrl, Int, Int + 10)
end,
wx:foreach(Fun, lists:seq(0, 50)),
ListCtrl.
get_image_list() ->
ImageList = wxImageList:new(16,16),
wxImageList:add(ImageList, wxArtProvider:getBitmap("wxART_COPY", [{size, {16,16}}])),
wxImageList:add(ImageList, wxArtProvider:getBitmap("wxART_MISSING_IMAGE", [{size, {16,16}}])),
wxImageList:add(ImageList, wxArtProvider:getBitmap("wxART_QUESTION", [{size, {16,16}}])),
wxImageList:add(ImageList, wxArtProvider:getBitmap("wxART_WARNING", [{size, {16,16}}])),
ImageList.
insert_image(ListCtrl) ->
ImageList = get_image_list(),
wxListCtrl:assignImageList(ListCtrl, ImageList, ?wxIMAGE_LIST_SMALL),
Fun =
fun(Item) ->
case Item rem 4 of
0 ->
wxListCtrl:setItemBackgroundColour(ListCtrl, Item, {240,240,240,255}),
wxListCtrl:setItemImage(ListCtrl, Item, 0);
1 ->
wxListCtrl:setItemImage(ListCtrl, Item, 1);
2 ->
wxListCtrl:setItemImage(ListCtrl, Item, 2),
wxListCtrl:setItemBackgroundColour(ListCtrl, Item, {240,240,240,255});
_ ->
wxListCtrl:setItemImage(ListCtrl, Item, 3)
end
end,
wx:foreach(Fun, lists:seq(0, wxListCtrl:getItemCount(ListCtrl) -1)),
ListCtrl.
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
resort_accord_to_integer_item(ListCtrl) ->
Fun =
fun(Int) ->
Id = list_to_integer(wxListCtrl:getItemText(ListCtrl, Int)),
io:format("Id = ~p~n", [Id]),
wxListCtrl:setItemData(ListCtrl, Int, 100 - Id)
end,
wx:foreach(Fun, lists:seq(0, wxListCtrl:getItemCount(ListCtrl) -1)),
wxListCtrl:sortItems(ListCtrl, fun(Item1, Item2) ->
case Item1 - Item2 < 0 of
false ->
1;
true ->
-1
end
end).
virtual_control_options() ->
ImageAttr = wxListItemAttr:new(),
wxListItemAttr:setTextColour(ImageAttr, {190, 25, 25}),
ListCtrlOpts = [{style, ?wxLC_REPORT bor ?wxLC_VIRTUAL },
{onGetItemText, fun(_This, Item, 0) ->
"Row " ++ integer_to_list(Item);
(_, Item, 1) when Item rem 5 == 0 ->
"Column 2";
(_, _, _) ->
""
end},
{onGetItemAttr, fun(_This, Item) when Item rem 3 == 0 ->
ImageAttr;
(_This, _Item) ->
wx:typeCast(wx:null(), wxListItemAttr)
end},
{onGetItemColumnImage, fun(_This, Item, 1) ->
Item rem 4;
(_, _, _) ->
-1
end}
],
ListCtrlOpts.
makeFrame(Title, Options) ->
Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, Options),
MenuSet = wxMenu:new(),
MenuHelp = wxMenu:new(),
wxMenu:append(MenuHelp, 1, "关于..."),
MenuBar = wxMenuBar:new(),
wxMenuBar:append(MenuBar, MenuSet, "设置"),
wxMenuBar:append(MenuBar, MenuHelp, "帮助"),
wxFrame:setMenuBar(Frame, MenuBar),
wxFrame:createStatusBar(Frame),
wxFrame:setStatusText(Frame,"Erlang wxListCtrl"),
wxFrame:connect(Frame, command_menu_selected),
Frame.
获取某一行某一列的cell数据方法(因为在wxErlang 中获取某一列的参数默认是0, 不能直接获取任意一行一列的Cell数据):
Cell = wxListItem:new(),
wxListItem:setId(Cell, Index),
wxListItem:setColumn(Cell, Column),
wxListItem:setMask(Cell, ?wxLIST_MASK_TEXT),
wxListCtrl:getItem(ListView, Cell),
N = wxListItem:getText(Cell),