wxErlang 中用wxSpinButton 控制wxTextCtrl值为数字(float/int),并控制数字增减

到目前为止还没做到用erlang在编辑框里面实现换行,这个得下次处理下!

% 在Erlang 中,wxTextCtrl控件的使用是和string 这个模块密切相关的
-module(text_spin).

-behaviour(wx_object).

-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(ID_PRICE_INPUT, 11).
-define(KEY_ESC,        27).
-define(KEY_UP,        315).
-define(KEY_DOWN,      317).

-record(state,
  {
      frame,
      spin_unit = 0.2,
      parent
   }).
%%%===================================================================
%%% API
%%%===================================================================
%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%%--------------------------------------------------------------------
new() ->
    _WX = wx:new(),
    Size = {size, {200, 100}},
    Pos = {pos, {200, 300}},
    Style = {style, ?wxDEFAULT_FRAME_STYLE},
    NOptions = [Pos, Size, Style],
    Frame = makeFrame("wxTextCtrl Text", NOptions),
    new([{parent, Frame}]).

new(Config) ->
    start(Config).

start(Config) ->
    wx_object:start_link({local, ?MODULE}, ?MODULE, Config, []).

%%--------------------------------------------------------------------
%% @doc
%% @spec
%% @end
%% wxclient_position_select:destroy()
%%--------------------------------------------------------------------
destroy() ->
    wx_object:call(?MODULE, shutdown).

show() ->
    wx_object:call(?MODULE, show).

init(Config) ->
    wx:batch(fun() -> do_init(Config) end).

handle_info(Info, State) ->
    io:format("Got Info ~p\n",[Info]),
    {noreply, State}.

handle_call(shutdown, _From, #state{parent = Panel} = State) ->
    wxPanel:destroy(Panel),
    {stop, normal, ok, State};

handle_call(show, _From, #state{frame = Frame} = State) ->
    wxWindow:center(Frame),
    wxFrame:show(Frame),
    {reply, ok,  State};

handle_call(CallMsg, _From, State) ->
    io:format("Got Call ~p\n",[CallMsg]),
    {reply, ok, State}.

handle_cast(CastMsg, State) ->
    io:format("Got cast ~p~n",[CastMsg]),
    {noreply,State}.

code_change(_,  _, State) ->
    {stop, ignore, State}.

terminate(_Reason, _State) ->
    ok.

handle_event(#wx{event = #wxCommand{type = command_text_updated}}, State) ->
    io:format("===>TextCtrl ~n"),
    {noreply, State};

% 通过捕获按键来控制只能输入数字和小数点, 而且小数点只能输入一个
handle_event(#wx{id = ?ID_PRICE_INPUT,
                 event = #wxKey{type = key_up, keyCode = KeyCode}}, State) ->
    InputCtrl = wx:typeCast(wxWindow:findWindowById(?ID_PRICE_INPUT, []), wxTextCtrl),
    Value = wxTextCtrl:getLineText(InputCtrl, 0),
    case KeyCode of        
            KeyCode when (KeyCode >= $A) and (KeyCode  =< $Z)  ->
                % 设置输入只能是数字,不能输入字母
                NewInput = lists:sublist(Value, length(Value) - 1),
                % 这个用string 设置wxTextCtrl 中的内容
                % wxTextCtrl:setValue(InputCtrl, 
                             % OrginalInput ++ string:chars(KeyCode - 32, 1));
                wxTextCtrl:setValue(InputCtrl, NewInput),
                wxTextCtrl:setInsertionPoint(InputCtrl, length(NewInput)) ;
            % 只能输入一个小数点
            $. ->
                case string:words(Value, $.) of
                    Words when Words >= 2 ->
                        NewInput = lists:sublist(Value, length(Value) - 1),
                        wxTextCtrl:setValue(InputCtrl, NewInput),
                        wxTextCtrl:setInsertionPoint(InputCtrl, length(NewInput));
                    Words ->
                        ok
                end;
            _ ->
                ok
    end,
    {noreply, State};

% 价格增减设置,每次增或者减 0.2
% 这里主要解决的是用string判断编辑框里面的内容是int 还是float
handle_event(#wx{userData = Price, event = #wxSpin{type = Type}}, State) ->
    #state{spin_unit = Unit} = State,
    CurrentValue =
        case  wxTextCtrl:getValue(Price) of
            Value when (Value =:= []) or (Value =:= "0") ->
                0.0;
            Value ->
                case string:chr(Value, $.) of
                    0 ->
                        list_to_integer(Value);
                    _ ->
                        list_to_float(Value)
                end
        end,
    case Type of
        spin_up ->
            wxTextCtrl:setValue(Price, float_to_list(CurrentValue + Unit, 
                                                     [{decimals, 1}, compact]));
        spin_down ->
            wxTextCtrl:setValue(Price, float_to_list(CurrentValue - Unit, 
                                                     [{decimals, 1}, compact]))
    end,
    {noreply, State};

handle_event(#wx{},  State) ->
    {noreply, State}.

%%-------------------------
%%%===================================================================
%%% API
%%%===================================================================
do_init(Config) ->
    %% define parent Panelss
    Parent = proplists:get_value(parent, Config),
    Panel = wxPanel:new(Parent, []),  
    Price = wxTextCtrl:new(Panel, ?ID_PRICE_INPUT, [{value, "36000"}, 
                                {size, {-1, -1}}, {style, ?wxALIGN_RIGHT}]),
    Spin = wxSpinButton:new(Panel, [{style, ?wxSP_VERTICAL bor ?wxSP_ARROW_KEYS}]),
    wxSpinButton:setRange(Spin, -10000, 10000),
    HSizer = wxBoxSizer:new(?wxHORIZONTAL),
    [wxSizer:add(HSizer, Item, [{proportion, 1}, {flag, ?wxEXPAND}]) 
                         || Item <-[Price, Spin]],
    wxSpinButton:connect(Spin, spin_up,   [{userData, Price}]),
    wxSpinButton:connect(Spin, spin_down, [{userData, Price}]),
    wxTextCtrl:connect(Price, key_up),
    wxPanel:setSizer(Panel, HSizer),
    wxFrame:show(Parent),
    {Panel, #state{frame = Parent, parent = Panel}}.

makeFrame(Title, Options) ->
    Frame = wxFrame:new(wx:null(), ?wxID_ANY, Title, Options),
    MenuSet  = wxMenu:new(),
    MenuHelp = wxMenu:new(),
    wxMenu:append(MenuHelp, 1, "About..."),
    MenuBar = wxMenuBar:new(),
    wxMenuBar:append(MenuBar, MenuSet, "Setting"),
    wxMenuBar:append(MenuBar, MenuHelp, "Help"),
    wxFrame:setMenuBar(Frame, MenuBar),
    wxFrame:createStatusBar(Frame),
    wxFrame:setStatusText(Frame,"deal wxTextCtrl"),
    wxFrame:connect(Frame, command_menu_selected),
    Frame.
posted @ 2015-03-25 10:30  ShankYan  阅读(508)  评论(0编辑  收藏  举报