2011年6月29日水曜日

wxErlangの設計方法 ~画面とソースの間~

こういうものを作ってみました。
https://docs.google.com/document/pub?id=1sUG9KVsP7rpKYQZHlST3G8elI5YBrEoic-um9DwUfFs

wxErlangで作成された画面とその実装ソースとの間を橋渡しする設計方法についてのドキュメントです。
自分としてはwxErlangを理解する上で助かったのは事実です。

2011年6月20日月曜日

wxErlang wxSashWindow サンプル

よくわからない画面だが、サンプルだけはできた。


ソース:

-module(sashWindowTest).
-include_lib("wx.hrl").

-export([start/0]).
-define(TOP_SASH, 1).
-define(BOTTOM_SASH, 2).

start()->
    Wx = wx:new(),
    Frame = wx:batch(fun() -> create_window(Wx) end),
    wxWindow:show(Frame),
    loop(Frame),
    wx:destroy(),
    ok.

create_window(Wx)->  
    %% Create Frame
    Frame = wxFrame:new(Wx,
 -1,
 "sashWindow Example",
 %%[{size,{300,200}}]),
 [{size,{-1,-1}}]),

    %% Create Panel
    %%Panel1 = wxPanel:new(Frame),
     Panel = wxPanel:new(Frame, []),

    %% Setup sizers
    MainSizer = wxBoxSizer:new(?wxVERTICAL),
    Sizer = wxBoxSizer:new(?wxVERTICAL),

    TopSash = wxSashWindow:new(Panel, [{id, ?TOP_SASH},
      {style, ?wxSW_3D}]),
    Win1 = wxPanel:new(TopSash, []),
    wxStaticText:new(Win1, ?wxID_ANY, "This is the top sash", []),
    BottomSash = wxSashWindow:new(Panel, [{id, ?BOTTOM_SASH},
 {style, ?wxSW_3D}]),
    Win2 = wxPanel:new(BottomSash, []),
    wxStaticText:new(Win2, ?wxID_ANY, "This is the bottom sash", []),

    %% Make the bottom edge of the top sash dragable
    wxSashWindow:setSashVisible(TopSash, ?wxSASH_BOTTOM, true),
    %wxPanel:connect(Panel, sash_dragged),
    %wxPanel:connect(Panel, size),

    %% Add to sizers
    Options = [{flag, ?wxEXPAND}, {proportion, 1}],
    wxSizer:add(Sizer, TopSash, Options),
    wxSizer:add(Sizer, BottomSash, Options),
    wxSizer:add(MainSizer, Sizer, Options),
    wxPanel:setSizer(Panel, MainSizer),
    wxSizer:fit(MainSizer, Panel),
    wxSizer:setSizeHints(MainSizer, Panel),

    %% Set Connect Close
    wxFrame:connect(Frame, close_window),

    Frame.

loop(Frame) ->
    receive
% Window Close Event
#wx{event=#wxClose{}} ->
   io:format("~p Closing window ~n",[self()]),
   wxWindow:destroy(Frame),
   ok
    end.

wx.hrlはErlangのインストールディレクトリを検索してください。
それを本ソースと同一ディレクトリに配置してください。

仕事が終わって、この作業も疲れてきたな。

2011年6月19日日曜日

wxErlang wxSplitterWindow sample サンプル

昨日のwxBoxSizerに引き続き、wxSplitterWindowのサンプルができた。
参考に載せておきます。


ソース:

-module(splittertest_3).
-include_lib("wx.hrl").

-export([start/0]).

start()->
    Wx = wx:new(),
    Frame = wx:batch(fun() -> create_window(Wx) end),
    wxWindow:show(Frame),
    loop(Frame),
    wx:destroy(),
    ok.

create_window(Wx)->  
    %% Create Frame
    Frame = wxFrame:new(Wx,
 -1,
 "SplitterWindow Example",
 %%[{size,{300,200}}]),
 [{size,{-1,-1}}]),

    %% Create Panel
    %%Panel1 = wxPanel:new(Frame),
     Panel = wxPanel:new(Frame, []),

    %% Setup sizers
    MainSizer = wxBoxSizer:new(?wxVERTICAL),
    Sizer = wxStaticBoxSizer:new(?wxVERTICAL, Panel,
[{label, "wxSplitterWindow"}]),

    Splitter = wxSplitterWindow:new(Panel, []),

    Win1 = wxTextCtrl:new(Splitter, 1, [{value, "Splitted Window 1"},
              {style, ?wxDEFAULT bor ?wxTE_MULTILINE}]),
    Win2 = wxTextCtrl:new(Splitter, 1, [{value, "Splitted Window 1"},
{style, ?wxDEFAULT bor ?wxTE_MULTILINE}]),

    wxSplitterWindow:splitVertically(Splitter, Win1, Win2),
    wxSplitterWindow:setSashGravity(Splitter,   0.5),
    %% Set pane-size =/= 0 to not unsplit on doubleclick
    %% on the splitter
    wxSplitterWindow:setMinimumPaneSize(Splitter,50),
   
    %% Add to sizers
    wxSizer:add(Sizer, Splitter, [{flag, ?wxEXPAND},
 {proportion, 1}]),

    wxSizer:add(MainSizer, Sizer, [{flag, ?wxEXPAND}, {proportion, 1}]),

    wxPanel:setSizer(Panel, MainSizer),

    %% Set Connect Close
    wxFrame:connect(Frame, close_window),

    Frame.

loop(Frame) ->
    receive
% Window Close Event
#wx{event=#wxClose{}} ->
   io:format("~p Closing window ~n",[self()]),
   wxWindow:destroy(Frame),
   ok
    end.

wx.hrlはErlangのインストールディレクトリを検索してください。
それを本ソースと同一ディレクトリに配置してください。
サンプル作るの疲れますね。

以上

wxErlang wxBoxSizer wxListBox 表示させる

やっと、wxBoxSizerのサンプルができた。
長かった。

こんな画面です。

wxStaticBoxSizerとか使わないとダメなのかわからない。
wxBoxSizerだけだとどうなんだか。

ソース:

-module(boxSizerTest).
-include_lib("wx.hrl").

-export([start/0]).

start()->
    Wx = wx:new(),
    Frame = wx:batch(fun() -> create_window(Wx) end),
    wxWindow:show(Frame),
    loop(Frame),
    wx:destroy(),
    ok.

create_window(Wx)->  
    %% Create Frame
    Frame = wxFrame:new(Wx,
 -1,
 "BoxSizer Example",
 %%[{size,{300,200}}]),
 [{size,{-1,-1}}]),

    %% Create Panel
    %%Panel1 = wxPanel:new(Frame),
     Panel = wxPanel:new(Frame, []),

    %% Setup sizers
    MainSizer = wxBoxSizer:new(?wxVERTICAL),
    Sizer = wxStaticBoxSizer:new(?wxVERTICAL, Panel,
[{label, "wxSizer"}]),

    Choices = ["Vertical Example",
      "Horizontal Example",
      "Add A Strechable",
      "More Than One Strechable",
      "Weighting Factor",
      "Edge Affinity",
      "Spacer",
      "Centering In Avalible Space",
      "Simple Border",
      "East And West Border",
      "North And South Border",
      "Box In Box",
      "Boxes Inside A Border",
      "Border In A Box",
      "Simple Grid",
      "More Grid Features",
      "Flexible Grid",
      "Grid With Alignment",
      "Proportional Resize With Alignments"],

    ListBox = wxListBox:new(Panel, ?wxID_ANY, [{choices, Choices}]),
    wxListBox:connect(ListBox, command_listbox_doubleclicked),

    %% Add to sizers
    wxSizer:add(Sizer, ListBox, [{flag, ?wxEXPAND}]),
    wxSizer:add(MainSizer, Sizer, [{flag, ?wxEXPAND}, {proportion, 1}]),

    wxPanel:setSizer(Panel, MainSizer),

    %% Set Connect Close
    wxFrame:connect(Frame, close_window),

    Frame.

loop(Frame) ->
    receive
% Window Close Event
#wx{event=#wxClose{}} ->
   io:format("~p Closing window ~n",[self()]),
   wxWindow:destroy(Frame),
   ok
    end.


wx.hrlはErlangのインストールディレクトリ内を検索して見つけてください。
それを本ソースと同一ディレクトリにおいてください。

2011年6月5日日曜日

wxErlang wxTextCrtl chat風に文字列を書きこむ

何がやりたいのかというと、過去に書いてきたソースの改良版ができたので、ブログに載せておきたいということ。

改良したところは、loop内のメッセージを受信するところ。
前はloopの引数にwxTextCtrlのポインタを設定して、receive内でそのポインタを使っていた。
しかし、それはメッセージパッシングではなかったので、自分としては納得していなかった。

ようやくメッセージパッシングでできることを知ったので、改良した。
前後の比較はコメントアウトとそうでないもので表現した。

たぶん、もう一個くらいloopの引数を減らすことができるのではないかと思っている。

ソース:

-module(irc2).
-export([start/0]).
-include_lib("wx.hrl").

-define(wxID_txtEdit,1000).
-define(wxID_txtUnEdit,1001).

start() ->
    % Create Window Object
    Wx = wx:new(),

    % Create Window
    %{Dialog,TxtEdit,TxtUnEdit} = wx:batch(fun() -> create_window(Wx) end),
    {Dialog,TxtUnEdit} = wx:batch(fun() -> create_window(Wx) end),

    % Show Window
    wxWindow:show(Dialog),

    % Message Receive Loop
    %loop(Dialog,TxtEdit,TxtUnEdit),
    loop(Dialog,TxtUnEdit),

    % Destroy Window
    wx:destroy(),
    ok.

create_window(Wx)->
    % Create Dialog
    Dialog = wxDialog:new(Wx,
-1,
"Dialog IRC",
[{size,{300,200}}]),
 
    % Set Option
    OptnTE = [{pos,{1,150}},{size,{290,20}},{style,?wxTE_PROCESS_ENTER}],
    TxtEdit = wxTextCtrl:new(Dialog,
    ?wxID_txtEdit,
    OptnTE),

    % Set Option and set multiline({style,?wxTE_MULTILINE})
    OptnTUE = [{pos,{1,0}},{size,{290,150}},{style,?wxTE_MULTILINE}],
    TxtUnEdit = wxTextCtrl:new(Dialog,
      ?wxID_txtUnEdit,
      OptnTUE),
   
    % set unable edit
    wxTextCtrl:setEditable(TxtUnEdit,false),
   
    % connect
    wxDialog:connect(Dialog, close_window),
    wxTextCtrl:connect(TxtEdit,command_text_enter),

    % Return
    %{Dialog,TxtEdit,TxtUnEdit}
    {Dialog,TxtUnEdit}.

%loop(Dialog,TxtUnEdit) ->
loop(Dialog,TxtUnEdit) ->
    receive
% Window Close Event
#wx{event=#wxClose{}} ->
   io:format("~p Closing window ~n",[self()]),
   wxWindow:destroy(Dialog),
   ok;

% Pressed Enter Event
%#wx{event=#wxCommand{type = command_text_enter}} ->
#wx{obj = TxtEdit ,event=#wxCommand{type = command_text_enter}} ->
   Msg = wxTextCtrl:getValue(TxtEdit),
   io:format("String: ~p~n",[Msg]),
   wxTextCtrl:appendText(TxtUnEdit,Msg),
   %loop(Dialog,TxtEdit,TxtUnEdit)
   loop(Dialog,TxtUnEdit)
    end.

wxErlang wxTextCtrl Enterキーのイベントを拾う

これだけのために何時間費やしただろうか。
Enterキーのイベントを拾うだけで。

キーポイントとなるところを赤字にしておくので、参照してほしい。
解説する(いつもしていないが)力がない。疲れた:-P

ソース:

-module(irc2).
-export([start/0]).
-include_lib("wx.hrl").

-define(wxID_txtEdit,1000).
-define(wxID_txtUnEdit,1001).

start() ->
    Wx = wx:new(),
    {Dialog,TxtEdit,TxtUnEdit} = wx:batch(fun() -> create_window(Wx) end),
    wxWindow:show(Dialog),
    loop(Dialog,TxtEdit,TxtUnEdit),
    wx:destroy(),
    ok.

create_window(Wx)->
    Dialog = wxDialog:new(Wx,
-1,
"Dialog IRC",
[{size,{300,200}}]),
%[{size,?wxDefaultSize}]),
    OptnTE = [{pos,{1,150}},{size,{290,20}},{style,?wxTE_PROCESS_ENTER}],
    TxtEdit = wxTextCtrl:new(Dialog,
    ?wxID_txtEdit,
    OptnTE),

    % set multiline({style,?wxTE_MULTILINE})
    OptnTUE = [{pos,{1,0}},{size,{290,150}},{style,?wxTE_MULTILINE}],
    TxtUnEdit = wxTextCtrl:new(Dialog,
      ?wxID_txtUnEdit,
      OptnTUE),
 
    % set unable edit
    wxTextCtrl:setEditable(TxtUnEdit,false),
    % add text
    %wxTextCtrl:appendText(TxtUnEdit,"Test\rTest\r"),
    %wxTextCtrl:appendText(TxtUnEdit,"Append"),
 
    % connect
    wxDialog:connect(Dialog, close_window),
    wxTextCtrl:connect(TxtEdit,command_text_enter),
    %wxEvtHandler:connect(TxtEdit,key_down),
    %wxTextCtrl:connect(TxtEdit,key_down),
    %wxKeyEvent:connect(TxtEdit,key_down),

    {Dialog,TxtEdit,TxtUnEdit}.

loop(Dialog,TxtEdit,TxtUnEdit) ->
    receive
% Window Close Event
#wx{event=#wxClose{}} ->
   io:format("~p Closing window ~n",[self()]),
   wxWindow:destroy(Dialog),
   ok;
#wx{event=#wxCommand{type = command_text_enter}} ->
% #wx{event=#wxKey{keyCode = ?WXK_RETURN}} ->
   Msg = wxTextCtrl:getValue(TxtEdit),
   io:format("String: ~p~n",[Msg]),
   wxTextCtrl:appendText(TxtUnEdit,Msg),
   loop(Dialog,TxtEdit,TxtUnEdit)
    end.


最終的な解決ができたのは、ここを見たから。
Paste number 88370: chat.erl :
http://paste.lisp.org/display/88370

2011年6月4日土曜日

wxErlang wxTextCtrl 各種マクロはどこに定義してあるのかについて

wxTE_MULTILINEとかどこにあるねんと。

wx.hrlに定義されている。
wx.hrlはErlangのインストールディレクトリ内を検索してもらえればみつかる。

そのファイルをtextctrlでまた検索をかけると、みつかる。

・・・
-define(wxTE_MULTILINE, 32).
-define(wxTE_READONLY, 16).
-define(wxTE_AUTO_SCROLL, 8).
-define(wxTE_NO_VSCROLL, 2).
・・・


などと。

wxErlang wxDefaultSizeのサイズはどのくらいか

wxDefaultSizeはタプルである。
-define(wxDefaultSize, {-1,-1}).
定義して、?wxDefaultSizeと使う。

これを画面のサイズで使うと、
width=400
height=465
になる。

参考までにソースを。


-module(irc2).
-export([start/0]).
-include_lib("wx.hrl").

-define(wxID_txtEdit,1000).
-define(wxID_txtUnEdit,1001).

start() ->
    Wx = wx:new(),
    Dialog = wx:batch(fun() -> create_window(Wx) end),
    wxWindow:show(Dialog),
    loop(Dialog),
    wx:destroy(),
    ok.

create_window(Wx)->
    Dialog = wxDialog:new(Wx,
-1,
"Dialog IRC",
%[{size,{300,200}}]),
[{size,?wxDefaultSize}]),

    % set multiline({style,?wxTE_MULTILINE})
    TxtUnEdit = wxTextCtrl:new(Dialog,?wxID_txtUnEdit,[{pos,{1,0}},{size,{390,465}},{style,?wxTE_MULTILINE}]),

    % set unable edit
    wxTextCtrl:setEditable(TxtUnEdit,false),
    % add text
    wxTextCtrl:appendText(TxtUnEdit,"Test\rTest\r"),
    wxTextCtrl:appendText(TxtUnEdit,"Append"),
   
    % connect
    wxDialog:connect(Dialog, close_window),

    Dialog.

loop(Dialog) ->
    receive
% Window Close Event
#wx{event=#wxClose{}} ->
   io:format("~p Closing window ~n",[self()]),
   wxWindow:destroy(Dialog),
   ok
    end.



wxErlang wxTextCtrl MultiLine 複数行を表示させる

wxTextCtrlを使って、その中に複数行の文字を表示させることに成功。
その画面とソースを記載しておく。
よければ参考にしてください。

それと編集できないようにしているので、合わせてどうぞ。
改行はバックスラッシュでする。



ソース:

-module(irc2).
-export([start/0]).
-include_lib("wx.hrl").

-define(wxID_txtEdit,1000).
-define(wxID_txtUnEdit,1001).

start() ->
    Wx = wx:new(),
    Dialog = wx:batch(fun() -> create_window(Wx) end),
    wxWindow:show(Dialog),
    loop(Dialog),
    wx:destroy(),
    ok.

create_window(Wx)->
    Dialog = wxDialog:new(Wx,
-1,
"Dialog IRC",
[{size,{300,200}}]),

    TxtEdit = wxTextCtrl:new(Dialog,?wxID_txtEdit,[{pos,{1,150}},{size,{290,20}}]),

    %TxtUnAttr = wxTextAttr:new({12,23,33}),
    %wxTextAttr:setBackGroundColour(TxtUnAttr,{0,0,0}),

    % set multiline({style,?wxTE_MULTILINE})
    TxtUnEdit = wxTextCtrl:new(Dialog,?wxID_txtUnEdit,[{pos,{1,0}},{size,{290,140}},{style,?wxTE_MULTILINE}]),
    % set unable edit
    wxTextCtrl:setEditable(TxtUnEdit,false),
    % add text
    wxTextCtrl:appendText(TxtUnEdit,"Test\rTest"),
   
    % connect
    wxDialog:connect(Dialog, close_window),

    Dialog.

loop(Dialog) ->
    receive
% Window Close Event
#wx{event=#wxClose{}} ->
   io:format("~p Closing window ~n",[self()]),
   wxWindow:destroy(Dialog),
   ok
    end.