%%
%% %CopyrightBegin%
%%
%% Copyright Ericsson AB 2009-2018. All Rights Reserved.
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at
%%
%% http://www.apache.org/licenses/LICENSE-2.0
%%
%% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
%% See the License for the specific language governing permissions and
%% limitations under the License.
%%
%% %CopyrightEnd%
%%%
%%% Description : Testing and demo xrc's
%%% This mimics the xrc demo from wxwidgets.
%%% Created : 4 Dec 2007 by Dan Gudmundsson <[email protected]>
%%%-------------------------------------------------------------------
-module(xrc).
-export([start/0]).
-include("../../include/wx.hrl").
%% I've put all "classes" in the same file, but you can see the follow
%% the code in xrcdemo from the samples directory in wxWidgets src package
start() ->
%% Starts wxwidgets
WX = wx:new(),
%% In erlang wx, all image handlers are initilized already.
%% wxImage::AddHandler(new wxXPMHandler);
%% Initialize all the XRC handlers. Always required (unless you feel like
%% going through and initializing a handler of each control type you will
%% be using (ie initialize the spinctrl handler, initialize the textctrl
%% handler). However, if you are only using a few control types, it will
%% save some space to only initialize the ones you will be using. See
%% wxXRC docs for details.
Xrc = wxXmlResource:get(),
wxXmlResource:initAllHandlers(Xrc),
true = wxXmlResource:load(Xrc, rc_dir("menu.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("toolbar.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("basicdlg.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("derivdlg.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("controls.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("frame.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("uncenter.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("custclas.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("artprov.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("platform.xrc")),
true = wxXmlResource:load(Xrc, rc_dir("variable.xrc")),
Frame = wxFrame:new(),
myframe(WX,Frame),
wxFrame:show(Frame),
loop(Frame),
wx:destroy().
rc_dir(File) ->
SelfDir = filename:dirname(code:which(?MODULE)),
filename:join([SelfDir,rc,File]).
loop(Frame) ->
receive
#wx{id=Id, event=#wxCommand{}} ->
handle_cmd(get(Id), Id, Frame),
loop(Frame);
#wx{event=#wxClose{}} ->
catch wxWindows:'Destroy'(Frame),
ok;
Ev = #wx{} ->
io:format("Got ~p ~n", [Ev]),
loop(Frame)
end.
myframe(Parent, Frame) ->
Xrc = wxXmlResource:get(),
wxXmlResource:loadFrame(Xrc, Frame, Parent, "main_frame"),
%% wxTopLevelWindow:setIcon(Frame, wxXmlResource:loadIcon(Xrc,"appicon")),
%% Load and setup menubar
wxFrame:setMenuBar(Frame, wxXmlResource:loadMenuBar(Xrc, "main_menu")),
%% hmm wxSystemOptions::SetOption ( wxT("msw.remap"), 0 );
wxFrame:setToolBar(Frame, wxXmlResource:loadToolBar(Xrc, Frame, "main_toolbar")),
wxFrame:createStatusBar(Frame, [{number,1}]),
ok = wxFrame:connect(Frame, close_window),
connect(Frame).
connect(Frame) ->
Menues = [unload_resource_menuitem, reload_resource_menuitem,
non_derived_dialog_tool_or_menuitem, derived_tool_or_menuitem,
controls_tool_or_menuitem, uncentered_tool_or_menuitem,
custom_class_tool_or_menuitem, platform_property_tool_or_menuitem,
art_provider_tool_or_menuitem, variable_expansion_tool_or_menuitem
],
wxFrame:connect(Frame,command_menu_selected, [{id, ?wxID_EXIT}]),
wxFrame:connect(Frame,command_menu_selected, [{id, ?wxID_ABOUT}]),
[connect_xrcid(Str,Frame) || Str <- Menues],
ok.
connect_xrcid(Name,Frame) ->
ID = wxXmlResource:getXRCID(atom_to_list(Name)),
put(ID, Name),
wxFrame:connect(Frame,command_menu_selected,[{id,ID}]).
%% Handle commands
handle_cmd(unload_resource_menuitem, _, _Frame) ->
Xrc = wxXmlResource:get(),
case wxXmlResource:unload(Xrc, "rc/basicdlg") of
true ->
io:format("Basic dialog unloaded~n",[]);
false ->
io:format("Failed to unload basic dialog~n",[])
end;
handle_cmd(reload_resource_menuitem, _, _Frame) ->
Xrc = wxXmlResource:get(),
case wxXmlResource:reload(Xrc, "rc/basicdlg") of
true ->
io:format("Basic dialog reloaded~n",[]);
false ->
io:format("Failed to reload basic dialog~n",[])
end;
handle_cmd(_, ?wxID_EXIT, Frame) ->
wxFrame:close(Frame);
handle_cmd(non_derived_dialog_tool_or_menuitem, _, Frame) ->
Xrc = wxXmlResource:get(),
Dlg = wxDialog:new(),
%% "non_derived_dialog" is the name of the wxDialog XRC node that should
%% be loaded.
case wxXmlResource:loadDialog(Xrc, Dlg, Frame, "non_derived_dialog") of
true ->
wxDialog:showModal(Dlg);
false ->
io:format("Failed to load non_derived_dialog~n",[])
end,
%% In Erlang you should delete the dialog afterwards
wxDialog:destroy(Dlg);
handle_cmd(derived_tool_or_menuitem, _, Frame) ->
Pref = prefDialog(Frame),
wxDialog:showModal(Pref);
handle_cmd(animation_ctrl_play, _, _Frame) ->
%% Not yet implemented
ok;
handle_cmd(controls_tool_or_menuitem,_,Frame) ->
Xrc = wxXmlResource:get(),
Dlg = wxDialog:new(),
true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "controls_dialog"),
LCtrl = wxXmlResource:xrcctrl(Dlg, "controls_listctrl", wxListCtrl),
wxListCtrl:insertColumn(LCtrl, 0, "Name", [{width, 200}]),
wxListCtrl:insertItem(LCtrl, 0, "Todd Hope"),
wxListCtrl:insertItem(LCtrl, 1, "Kim Wynd"),
wxListCtrl:insertItem(LCtrl, 2, "Leon Li"),
TCtrl = wxXmlResource:xrcctrl(Dlg, "controls_treectrl", wxTreeCtrl),
wxTreeCtrl:addRoot(TCtrl, "Godfather"),
TRoot = wxTreeCtrl:getRootItem(TCtrl),
wxTreeCtrl:appendItem(TCtrl,TRoot, "Evil henchmen 1"),
wxTreeCtrl:appendItem(TCtrl,TRoot, "Evil henchmen 2"),
wxTreeCtrl:appendItem(TCtrl,TRoot, "Evil accountant"),
wxDialog:showModal(Dlg),
wxDialog:destroy(Dlg);
handle_cmd(uncentered_tool_or_menuitem,_,Frame) ->
Xrc = wxXmlResource:get(),
Dlg = wxDialog:new(),
true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "uncentered_dialog"),
wxDialog:showModal(Dlg),
wxDialog:destroy(Dlg);
handle_cmd(custom_class_tool_or_menuitem,_,Frame) ->
Xrc = wxXmlResource:get(),
Dlg = wxDialog:new(),
true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "custom_class_dialog"),
ResizeableLC = myResizeableListCtrl(Dlg, ?wxID_ANY, {-1,-1}, {-1,-1},?wxLC_REPORT),
%% "custom_control_placeholder" is the name of the "unknown" tag in the
%% custctrl.xrc XRC file.
wxXmlResource:attachUnknownControl(Xrc, "custom_control_placeholder", ResizeableLC),
wxDialog:showModal(Dlg),
wxDialog:destroy(Dlg);
handle_cmd(platform_property_tool_or_menuitem, _, Frame) ->
Xrc = wxXmlResource:get(),
Dlg = wxDialog:new(),
true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "platform_property_dialog"),
wxDialog:showModal(Dlg),
wxDialog:destroy(Dlg);
handle_cmd(art_provider_tool_or_menuitem, _, Frame) ->
Xrc = wxXmlResource:get(),
Dlg = wxDialog:new(),
true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "art_provider_dialog"),
wxDialog:showModal(Dlg),
wxDialog:destroy(Dlg);
handle_cmd(variable_expansion_tool_or_menuitem, _, Frame) ->
Xrc = wxXmlResource:get(),
Dlg = wxDialog:new(),
true = wxXmlResource:loadDialog(Xrc, Dlg, Frame, "variable_expansion_dialog"),
wxDialog:showModal(Dlg),
wxDialog:destroy(Dlg);
handle_cmd(_, ?wxID_ABOUT, Frame) ->
Msg = "This is the about dialog of XML resources demo.\n",
MD = wxMessageDialog:new(Frame,Msg,
[{style, ?wxOK bor ?wxICON_INFORMATION},
{caption, "About"}]),
wxDialog:showModal(MD),
wxDialog:destroy(MD);
handle_cmd(Dialog, Id, _) ->
io:format("Not implemented yet ~p (~p) ~n",[Dialog, Id]).
%%%%%%%%%%%%%%%%
%% Trying to mimic the derived dialog example
%%%%%%%%%%%%%%%%
prefDialog(Parent) ->
Xrc = wxXmlResource:get(),
Dlg = wxDialog:new(),
true = wxXmlResource:loadDialog(Xrc, Dlg, Parent, "derived_dialog"),
%% Shows that callbacks can be used it doesn't need to though.
OnMyButtonClicked = fun(_EvRec, _wxEvent) ->
MD = wxMessageDialog:new(Dlg, "You clicked on My Button"),
wxMessageDialog:showModal(MD),
wxMessageDialog:destroy(MD)
end,
wxDialog:connect(Dlg, command_button_clicked,
[{id,wxXmlResource:getXRCID("my_button")},
{callback,OnMyButtonClicked}]),
OnMyCheckBox = fun(_EvRec, _Event) ->
CheckB = wxXmlResource:xrcctrl(Dlg, "my_checkbox", wxCheckBox),
Text = wxXmlResource:xrcctrl(Dlg, "my_textctrl", wxTextCtrl),
Bool = wxCheckBox:isChecked(CheckB),
wxTextCtrl:enable(Text, [{enable,Bool}])
end,
wxDialog:connect(Dlg,update_ui,[{id,wxXmlResource:getXRCID("my_checkbox")},
{callback,OnMyCheckBox}]),
%% Keep updateUI event interval at 250ms
wxUpdateUIEvent:setUpdateInterval(250),
OnOk = fun(_,_) ->
Str =
"Press Ok to close derived dialog, or Cancel to abort"
"Overriding base class ok button handler",
MD = wxMessageDialog:new(Dlg, Str, [{style, ?wxOK bor ?wxCANCEL bor ?wxCENTER}]),
case wxMessageDialog:showModal(MD) of
?wxID_OK ->
wxMessageDialog:endModal(Dlg, ?wxID_OK);
_R ->
ignore
end,
wxMessageDialog:destroy(MD)
end,
wxDialog:connect(Dlg,command_button_clicked,[{id,?wxID_OK},{callback,OnOk}]),
Dlg.
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
-define(RECORD_COLUMN, 0).
-define(ACTION_COLUMN, 1).
-define(PRIORITY_COLUMN,2).
-define(PU_ADD_RECORD, ?wxID_HIGHEST+1).
-define(PU_EDIT_RECORD, ?wxID_HIGHEST+2).
-define(PU_DELETE_RECORD, ?wxID_HIGHEST+3).
myResizeableListCtrl(Parent,Id,Pos,Size,Style) ->
LC = wxListCtrl:new(Parent, [{winid,Id}, {pos,Pos}, {size,Size}, {style,Style}]),
wxListCtrl:insertColumn(LC,?RECORD_COLUMN, "Record", [{width, 140}]),
wxListCtrl:insertColumn(LC,?ACTION_COLUMN, "Action", [{width, 70}]),
wxListCtrl:insertColumn(LC,?PRIORITY_COLUMN, "Priority", [{width, 70}]),
wxListCtrl:connect(LC, right_down, [{id,Id}, {callback, fun lc_onRightClick/2}]),
wxListCtrl:connect(LC, size, [{id,Id}, {callback, fun lc_onSize/2}]),
LC.
lc_onRightClick(#wx{obj=ListCtrl, event=#wxMouse{x=X,y=Y}},_Ev) ->
Menu = wxMenu:new(),
wxMenu:append(Menu, ?PU_ADD_RECORD, "Add a new record"),
wxMenu:append(Menu, ?PU_EDIT_RECORD,"Edit selected record"),
wxMenu:append(Menu, ?PU_DELETE_RECORD, "Delete selected record"),
case wxListCtrl:getSelectedItemCount(ListCtrl) of
0 ->
wxMenu:enable(Menu, ?PU_EDIT_RECORD, false),
wxMenu:enable(Menu, ?PU_DELETE_RECORD, false);
_ ->
ignore
end,
MenuCB = fun(_,_) -> io:format("Menu selected~n",[]) end,
wxWindow:connect(ListCtrl, command_menu_selected, [{callback, MenuCB}]),
wxWindow:popupMenu(ListCtrl, Menu, [{pos, {X,Y}}]),
wxMenu:destroy(Menu).
lc_onSize(#wx{obj=ListCtrl},EvObj) ->
{LeftMostColW0,_} = wxListCtrl:getSize(ListCtrl),
LeftMostColW1 = LeftMostColW0 - wxListCtrl:getColumnWidth(ListCtrl, ?ACTION_COLUMN),
LeftMostColW2 = LeftMostColW1 - wxListCtrl:getColumnWidth(ListCtrl, ?PRIORITY_COLUMN),
%% Hmm missing wxSystemSettings::GetMetric( wxSYS_VSCROLL_X );
LeftMostColW = LeftMostColW2 - 5,
wxListCtrl:setColumnWidth(ListCtrl, ?RECORD_COLUMN, LeftMostColW),
%% REQURED event.Skip() call to allow this event to propagate
%% upwards so others can do what they need to do in response to
%% this size event.
wxEvent:skip(EvObj),
io:format("Successfully set column width~n").
%%%%%