Fewer bugs
This commit is contained in:
parent
4254fe7643
commit
a164af45cd
203
src/gmc_con.erl
203
src/gmc_con.erl
@ -12,7 +12,8 @@
|
|||||||
|
|
||||||
-behavior(gen_server).
|
-behavior(gen_server).
|
||||||
-export([show_ui/1,
|
-export([show_ui/1,
|
||||||
open_wallet/2, close_wallet/0, new_wallet/3, import_wallet/3, password/2,
|
open_wallet/2, close_wallet/0, new_wallet/3, import_wallet/3, drop_wallet/2,
|
||||||
|
password/2,
|
||||||
refresh/0,
|
refresh/0,
|
||||||
nonce/1, spend/2, chain/1, grids/1,
|
nonce/1, spend/2, chain/1, grids/1,
|
||||||
make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1,
|
make_key/6, recover_key/1, mnemonic/1, rename_key/2, drop_key/1,
|
||||||
@ -94,6 +95,14 @@ import_wallet(Name, Path, Password) ->
|
|||||||
gen_server:cast(?MODULE, {import_wallet, Name, Path, Password}).
|
gen_server:cast(?MODULE, {import_wallet, Name, Path, Password}).
|
||||||
|
|
||||||
|
|
||||||
|
-spec drop_wallet(Path, Delete) -> ok
|
||||||
|
when Path :: file:filename(),
|
||||||
|
Delete :: boolean().
|
||||||
|
|
||||||
|
drop_wallet(Path, Delete) ->
|
||||||
|
gen_server:cast(?MODULE, {drop_wallet, Path, Delete}).
|
||||||
|
|
||||||
|
|
||||||
-spec password(Old, New) -> ok
|
-spec password(Old, New) -> ok
|
||||||
when Old :: none | string(),
|
when Old :: none | string(),
|
||||||
New :: none | string().
|
New :: none | string().
|
||||||
@ -241,20 +250,16 @@ init(none) ->
|
|||||||
Prefs = read_prefs(),
|
Prefs = read_prefs(),
|
||||||
GUI_Prefs = maps:get(gmc_gui, Prefs, #{}),
|
GUI_Prefs = maps:get(gmc_gui, Prefs, #{}),
|
||||||
Window = gmc_gui:start_link(GUI_Prefs),
|
Window = gmc_gui:start_link(GUI_Prefs),
|
||||||
State = #s{window = Window, prefs = Prefs},
|
Wallets = get_prefs(wallets, Prefs, []),
|
||||||
|
State = #s{window = Window, wallets = Wallets, prefs = Prefs},
|
||||||
NewState = do_show_ui(gmc_v_wallman, State),
|
NewState = do_show_ui(gmc_v_wallman, State),
|
||||||
{ok, NewState}.
|
{ok, NewState}.
|
||||||
|
|
||||||
|
|
||||||
read_prefs() ->
|
read_prefs() ->
|
||||||
case file:consult(prefs_path()) of
|
case file:consult(prefs_path()) of
|
||||||
{ok, Prefs} ->
|
{ok, Prefs} -> proplists:to_map(Prefs);
|
||||||
proplists:to_map(Prefs);
|
_ -> #{}
|
||||||
_ ->
|
|
||||||
#{selected => 0,
|
|
||||||
last => save_path(),
|
|
||||||
lang => en_us,
|
|
||||||
geometry => none}
|
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
@ -309,6 +314,12 @@ handle_cast(close_wallet, State) ->
|
|||||||
handle_cast({new_wallet, Name, Path, Password}, State) ->
|
handle_cast({new_wallet, Name, Path, Password}, State) ->
|
||||||
NewState = do_new_wallet(Name, Path, Password, State),
|
NewState = do_new_wallet(Name, Path, Password, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
|
handle_cast({import_wallet, Name, Path, Password}, State) ->
|
||||||
|
NewState = do_import_wallet(Name, Path, Password, State),
|
||||||
|
{noreply, NewState};
|
||||||
|
handle_cast({drop_wallet, Path, Delete}, State) ->
|
||||||
|
NewState = do_drop_wallet(Path, Delete, State),
|
||||||
|
{noreply, NewState};
|
||||||
handle_cast({password, Old, New}, State) ->
|
handle_cast({password, Old, New}, State) ->
|
||||||
NewState = do_password(Old, New, State),
|
NewState = do_password(Old, New, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
@ -434,19 +445,37 @@ do_add_node(New, State) ->
|
|||||||
State.
|
State.
|
||||||
|
|
||||||
|
|
||||||
% FIXME: This will, of course, totally explode if anything goes wrong
|
|
||||||
do_set_sole_node(TOTN = #node{external = none}, State) ->
|
do_set_sole_node(TOTN = #node{external = none}, State) ->
|
||||||
do_set_sole_node(TOTN#node{external = 3013}, State);
|
do_set_sole_node(TOTN#node{external = 3013}, State);
|
||||||
do_set_sole_node(New, State = #s{wallet = W}) ->
|
do_set_sole_node(New = #node{ip = IP, external = Port}, State = #s{wallet = W}) ->
|
||||||
ChainID = ensure_hz_set(New),
|
ok = hz:chain_nodes([{IP, Port}]),
|
||||||
|
case ensure_hz_set(New) of
|
||||||
|
{ok, ChainID} ->
|
||||||
Net = #net{id = ChainID, chains = [#chain{id = ChainID, nodes = [New]}]},
|
Net = #net{id = ChainID, chains = [#chain{id = ChainID, nodes = [New]}]},
|
||||||
NewWallet = W#wallet{chain_id = ChainID, endpoint = New, nets = [Net]},
|
NewWallet = W#wallet{chain_id = ChainID, endpoint = New, nets = [Net]},
|
||||||
NewState = State#s{wallet = NewWallet},
|
NewState = State#s{wallet = NewWallet},
|
||||||
do_refresh(NewState).
|
do_refresh(NewState);
|
||||||
|
Error ->
|
||||||
|
gmc_gui:trouble(Error),
|
||||||
|
State
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
do_refresh(State = #s{wallet = W = #wallet{poas = POAs, endpoint = Node}}) ->
|
do_refresh(State = #s{wallet = none}) ->
|
||||||
ChainID = ensure_hz_set(Node),
|
State;
|
||||||
|
do_refresh(State = #s{wallet = #wallet{endpoint = none}}) ->
|
||||||
|
State;
|
||||||
|
do_refresh(State = #s{wallet = #wallet{endpoint = Node}}) ->
|
||||||
|
case ensure_hz_set(Node) of
|
||||||
|
{ok, ChainID} ->
|
||||||
|
do_refresh2(ChainID, State);
|
||||||
|
Error ->
|
||||||
|
ok = gmc_gui:trouble({do_refresh, 1, Error}),
|
||||||
|
State
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
do_refresh2(ChainID, State = #s{wallet = W = #wallet{poas = POAs}}) ->
|
||||||
CheckBalance =
|
CheckBalance =
|
||||||
fun(This = #poa{id = ID}) ->
|
fun(This = #poa{id = ID}) ->
|
||||||
Pucks =
|
Pucks =
|
||||||
@ -467,14 +496,14 @@ do_refresh(State = #s{wallet = W = #wallet{poas = POAs, endpoint = Node}}) ->
|
|||||||
ensure_hz_set(Node = #node{ip = IP, external = Port}) ->
|
ensure_hz_set(Node = #node{ip = IP, external = Port}) ->
|
||||||
case hz:status() of
|
case hz:status() of
|
||||||
{ok, #{"network_id" := ChainID}} ->
|
{ok, #{"network_id" := ChainID}} ->
|
||||||
list_to_binary(ChainID);
|
|
||||||
{error, no_nodes} ->
|
|
||||||
ok = hz:chain_nodes([{IP, Port}]),
|
|
||||||
{ok, #{"network_id" := C}} = hz:status(),
|
|
||||||
ChainID = list_to_binary(C),
|
|
||||||
ok = hz:network_id(ChainID),
|
ok = hz:network_id(ChainID),
|
||||||
ok = gmc_gui:chain(ChainID, Node),
|
ok = gmc_gui:chain(ChainID, Node),
|
||||||
ChainID
|
{ok, list_to_binary(ChainID)};
|
||||||
|
{error, no_nodes} ->
|
||||||
|
ok = hz:chain_nodes([{IP, Port}]),
|
||||||
|
ensure_hz_set(Node);
|
||||||
|
Error ->
|
||||||
|
Error
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
@ -696,23 +725,17 @@ do_drop_key(ID, State = #s{wallet = W}) ->
|
|||||||
State#s{wallet = NewWallet}.
|
State#s{wallet = NewWallet}.
|
||||||
|
|
||||||
|
|
||||||
do_open_wallet(Path, none, State) ->
|
|
||||||
case read(Path, none) of
|
|
||||||
{ok, Recovered = #wallet{poas = POAs, chain_id = ChainID, endpoint = Node}} ->
|
|
||||||
ok = gmc_gui:show(POAs),
|
|
||||||
ok = gmc_gui:chain(ChainID, Node),
|
|
||||||
State#s{wallet = Recovered};
|
|
||||||
Error ->
|
|
||||||
ok = gmc_gui:trouble(Error),
|
|
||||||
New = default_wallet(),
|
|
||||||
State#s{wallet = New}
|
|
||||||
end;
|
|
||||||
do_open_wallet(Path, Phrase, State) ->
|
do_open_wallet(Path, Phrase, State) ->
|
||||||
Pass = pass(Phrase),
|
Pass = pass(Phrase),
|
||||||
case read(Path, Pass) of
|
case read(Path, Pass) of
|
||||||
{ok, Recovered = #wallet{poas = POAs, chain_id = ChainID, endpoint = Node}} ->
|
{ok, Recovered = #wallet{name = Name, poas = POAs, endpoint = Node}} ->
|
||||||
ok = gmc_gui:show(POAs),
|
ok = gmc_gui:show(POAs),
|
||||||
ok = gmc_gui:chain(ChainID, Node),
|
ok = gmc_gui:wallet(Name),
|
||||||
|
ok =
|
||||||
|
case ensure_hz_set(Node) of
|
||||||
|
{ok, ChainID} -> gmc_gui:chain(ChainID, Node);
|
||||||
|
Error -> gmc_gui:trouble(Error)
|
||||||
|
end,
|
||||||
State#s{wallet = Recovered};
|
State#s{wallet = Recovered};
|
||||||
Error ->
|
Error ->
|
||||||
ok = gmc_gui:trouble(Error),
|
ok = gmc_gui:trouble(Error),
|
||||||
@ -723,12 +746,12 @@ do_open_wallet(Path, Phrase, State) ->
|
|||||||
|
|
||||||
default_wallet() ->
|
default_wallet() ->
|
||||||
DevNet = #net{id = <<"devnet">>, chains = [#chain{}]},
|
DevNet = #net{id = <<"devnet">>, chains = [#chain{}]},
|
||||||
TestChain1 = #chain{id = <<"groot.testnet">>,
|
% TestChain1 = #chain{id = <<"groot.testnet">>,
|
||||||
nodes = [#node{ip = {1,2,3,4}}, #node{ip = {5,6,7,8}}]},
|
% nodes = [#node{ip = {1,2,3,4}}, #node{ip = {5,6,7,8}}]},
|
||||||
TestChain2 = #chain{id = <<"test_ac.testnet">>,
|
% TestChain2 = #chain{id = <<"test_ac.testnet">>,
|
||||||
nodes = [#node{ip = {11,12,13,14}}, #node{ip = {15,16,17,18}}]},
|
% nodes = [#node{ip = {11,12,13,14}}, #node{ip = {15,16,17,18}}]},
|
||||||
TestNet = #net{id = <<"testnet">>, chains = [TestChain1, TestChain2]},
|
% TestNet = #net{id = <<"testnet">>, chains = [TestChain1, TestChain2]},
|
||||||
#wallet{nets = [DevNet, TestNet]}.
|
#wallet{nets = [DevNet]}.
|
||||||
|
|
||||||
|
|
||||||
do_password(none, none, State) ->
|
do_password(none, none, State) ->
|
||||||
@ -765,23 +788,113 @@ do_stop(State = #s{prefs = Prefs}) ->
|
|||||||
do_close_wallet(State).
|
do_close_wallet(State).
|
||||||
|
|
||||||
|
|
||||||
do_new_wallet(Name, Path, Password, State = #s{wallets = Wallets}) ->
|
do_new_wallet(Name, Path, Password, State = #s{wallets = Wallets, prefs = Prefs}) ->
|
||||||
case lists:keyfind(Name, #wr.name, Wallets) of
|
case lists:keyfind(Name, #wr.name, Wallets) of
|
||||||
false ->
|
false ->
|
||||||
NextState = do_close_wallet(State),
|
NextState = do_close_wallet(State),
|
||||||
Pass = pass(Password),
|
Pass = pass(Password),
|
||||||
HasPass = Pass =/= none,
|
HasPass = Pass =/= none,
|
||||||
Entry = #wr{name = Name, path = Path, pass = HasPass},
|
Entry = #wr{name = Name, path = Path, pass = HasPass},
|
||||||
New = #wallet{},
|
New = #wallet{name = Name},
|
||||||
ok = save_wallet(Entry, Pass, New),
|
ok = save_wallet(Entry, Pass, New),
|
||||||
ok = gmc_gui:show([]),
|
ok = gmc_gui:show([]),
|
||||||
NextState#s{wallet = New, pass = Pass, wallets = [Entry | Wallets]};
|
ok = gmc_gui:wallet(Name),
|
||||||
|
NewWallets = [Entry | Wallets],
|
||||||
|
NewPrefs = put_prefs(wallets, NewWallets, Prefs),
|
||||||
|
ok = persist(NewPrefs),
|
||||||
|
NextState#s{wallet = New, pass = Pass, wallets = NewWallets, prefs = NewPrefs};
|
||||||
#wr{} ->
|
#wr{} ->
|
||||||
% FIXME
|
% FIXME
|
||||||
% Need to provide feedback based on where this came from
|
% Need to provide feedback based on where this came from
|
||||||
State
|
State
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
do_import_wallet(Name, Path, Password, State = #s{wallets = Wallets}) ->
|
||||||
|
NameExists = lists:keymember(Name, #wr.name, Wallets),
|
||||||
|
PathExists = lists:keymember(Path, #wr.path, Wallets),
|
||||||
|
case {NameExists, PathExists} of
|
||||||
|
{false, false} ->
|
||||||
|
do_import_wallet2(Name, Path, Password, State);
|
||||||
|
{true, false} ->
|
||||||
|
ok = gmc_gui:trouble({error, name_exists}),
|
||||||
|
State;
|
||||||
|
{false, true} ->
|
||||||
|
ok = gmc_gui:trouble({error, path_exists}),
|
||||||
|
State;
|
||||||
|
{true, true} ->
|
||||||
|
ok = gmc_gui:trouble("Whoa! This exact wallet already exists!"),
|
||||||
|
State
|
||||||
|
end.
|
||||||
|
|
||||||
|
do_import_wallet2(Name, Path, Password, State = #s{wallets = Wallets, prefs = Prefs}) ->
|
||||||
|
Pass = pass(Password),
|
||||||
|
case read(Path, Pass) of
|
||||||
|
{ok, Recovered = #wallet{poas = POAs, chain_id = ChainID, endpoint = Endpoint}} ->
|
||||||
|
Imported = Recovered#wallet{name = Name},
|
||||||
|
HasPass = Pass =/= none,
|
||||||
|
Record = #wr{name = Name, path = Path, pass = HasPass},
|
||||||
|
NewWallets = [Record | Wallets],
|
||||||
|
NewPrefs = put_prefs(wallets, NewWallets, Prefs),
|
||||||
|
ok = save_wallet(Record, Pass, Imported),
|
||||||
|
ok = persist(NewPrefs),
|
||||||
|
ok = gmc_gui:show(POAs),
|
||||||
|
ok = gmc_gui:chain(ChainID, Endpoint),
|
||||||
|
ok = gmc_gui:wallet(Name),
|
||||||
|
State#s{wallet = Imported, wallets = NewWallets, prefs = NewPrefs};
|
||||||
|
Error ->
|
||||||
|
ok = gmc_gui:trouble(Error),
|
||||||
|
State
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
do_drop_wallet(Path, Delete, State = #s{tasks = Tasks,
|
||||||
|
wallet = Wallet,
|
||||||
|
wallets = Wallets,
|
||||||
|
prefs = Prefs}) ->
|
||||||
|
CurrentName =
|
||||||
|
case Wallet of
|
||||||
|
#wallet{name = N} -> N;
|
||||||
|
none -> none
|
||||||
|
end,
|
||||||
|
case lists:keytake(Path, #wr.path, Wallets) of
|
||||||
|
{value, #wr{name = Name}, NewWallets} ->
|
||||||
|
ok =
|
||||||
|
case Name =:= CurrentName of
|
||||||
|
true ->
|
||||||
|
ok = gmc_gui:show([]),
|
||||||
|
ok = gmc_gui:wallet(none),
|
||||||
|
ok = gmc_gui:chain(none, none);
|
||||||
|
false ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
ok = maybe_clean(Delete, Path),
|
||||||
|
NewPrefs = put_prefs(wallets, NewWallets, Prefs),
|
||||||
|
ok = persist(NewPrefs),
|
||||||
|
#ui{wx = WallMan} = lists:keyfind(gmc_v_wallman, #ui.name, Tasks),
|
||||||
|
ok = gmc_v_wallman:show(WallMan, NewWallets),
|
||||||
|
State#s{wallets = NewWallets, prefs = NewPrefs};
|
||||||
|
false ->
|
||||||
|
State
|
||||||
|
end.
|
||||||
|
|
||||||
|
maybe_clean(true, Path) ->
|
||||||
|
case file:delete(Path) of
|
||||||
|
ok -> ok;
|
||||||
|
Error -> gmc_gui:trouble(Error)
|
||||||
|
end;
|
||||||
|
maybe_clean(false, _) ->
|
||||||
|
ok.
|
||||||
|
|
||||||
|
|
||||||
|
get_prefs(K, M, D) ->
|
||||||
|
P = maps:get(?MODULE, M, #{}),
|
||||||
|
maps:get(K, P, D).
|
||||||
|
|
||||||
|
put_prefs(K, V, M) ->
|
||||||
|
P = maps:get(?MODULE, M, #{}),
|
||||||
|
NewP = maps:put(K, V, P),
|
||||||
|
maps:put(?MODULE, NewP, M).
|
||||||
|
|
||||||
|
|
||||||
do_save(Module, Prefs, State = #s{prefs = Cached}) ->
|
do_save(Module, Prefs, State = #s{prefs = Cached}) ->
|
||||||
Updated = maps:put(Module, Prefs, Cached),
|
Updated = maps:put(Module, Prefs, Cached),
|
||||||
@ -838,10 +951,6 @@ read2(Bin) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
save_path() ->
|
|
||||||
filename:join(zx_lib:path(var, "otpr", "clutch"), "default.gaju").
|
|
||||||
|
|
||||||
|
|
||||||
persist(Prefs) ->
|
persist(Prefs) ->
|
||||||
Path = prefs_path(),
|
Path = prefs_path(),
|
||||||
ok = filelib:ensure_dir(Path),
|
ok = filelib:ensure_dir(Path),
|
||||||
|
101
src/gmc_gui.erl
101
src/gmc_gui.erl
@ -14,7 +14,7 @@
|
|||||||
|
|
||||||
-behavior(wx_object).
|
-behavior(wx_object).
|
||||||
-include_lib("wx/include/wx.hrl").
|
-include_lib("wx/include/wx.hrl").
|
||||||
-export([show/1, chain/2, trouble/1, ask_password/0]).
|
-export([show/1, wallet/1, chain/2, trouble/1, ask_password/0]).
|
||||||
-export([start_link/1]).
|
-export([start_link/1]).
|
||||||
-export([init/1, terminate/2, code_change/3,
|
-export([init/1, terminate/2, code_change/3,
|
||||||
handle_call/3, handle_cast/2, handle_info/2, handle_event/2]).
|
handle_call/3, handle_cast/2, handle_info/2, handle_event/2]).
|
||||||
@ -52,6 +52,10 @@ show(Accounts) ->
|
|||||||
wx_object:cast(?MODULE, {show, Accounts}).
|
wx_object:cast(?MODULE, {show, Accounts}).
|
||||||
|
|
||||||
|
|
||||||
|
wallet(Name) ->
|
||||||
|
wx_object:cast(?MODULE, {wallet, Name}).
|
||||||
|
|
||||||
|
|
||||||
chain(ChainID, Node) ->
|
chain(ChainID, Node) ->
|
||||||
wx_object:cast(?MODULE, {chain, ChainID, Node}).
|
wx_object:cast(?MODULE, {chain, ChainID, Node}).
|
||||||
|
|
||||||
@ -178,16 +182,7 @@ init(Prefs) ->
|
|||||||
ok = wxFrame:setSizer(Frame, MainSz),
|
ok = wxFrame:setSizer(Frame, MainSz),
|
||||||
ok = wxSizer:layout(MainSz),
|
ok = wxSizer:layout(MainSz),
|
||||||
|
|
||||||
ok =
|
ok = gmc_v:safe_size(Frame, Prefs),
|
||||||
case safe_size(Prefs) of
|
|
||||||
{pref, max} ->
|
|
||||||
wxTopLevelWindow:maximize(Frame);
|
|
||||||
{pref, WSize} ->
|
|
||||||
wxFrame:setSize(Frame, WSize);
|
|
||||||
{center, WSize} ->
|
|
||||||
ok = wxFrame:setSize(Frame, WSize),
|
|
||||||
wxFrame:center(Frame)
|
|
||||||
end,
|
|
||||||
|
|
||||||
ok = wxFrame:connect(Frame, command_button_clicked),
|
ok = wxFrame:connect(Frame, command_button_clicked),
|
||||||
ok = wxFrame:connect(Frame, close_window),
|
ok = wxFrame:connect(Frame, close_window),
|
||||||
@ -202,35 +197,6 @@ init(Prefs) ->
|
|||||||
{Frame, State}.
|
{Frame, State}.
|
||||||
|
|
||||||
|
|
||||||
% Put this in a gmc bevhavior
|
|
||||||
safe_size(Prefs) ->
|
|
||||||
Display = wxDisplay:new(),
|
|
||||||
GSize = wxDisplay:getGeometry(Display),
|
|
||||||
CSize = wxDisplay:getClientArea(Display),
|
|
||||||
PPI =
|
|
||||||
try
|
|
||||||
wxDisplay:getPPI(Display)
|
|
||||||
catch
|
|
||||||
Class:Exception -> {Class, Exception}
|
|
||||||
end,
|
|
||||||
ok = log(info, "Geometry: ~p", [GSize]),
|
|
||||||
ok = log(info, "ClientArea: ~p", [CSize]),
|
|
||||||
ok = log(info, "PPI: ~p", [PPI]),
|
|
||||||
Geometry =
|
|
||||||
case maps:find(geometry, Prefs) of
|
|
||||||
{ok, none} ->
|
|
||||||
{X, Y, _, _} = GSize,
|
|
||||||
{center, {X, Y, 420, 520}};
|
|
||||||
{ok, G} ->
|
|
||||||
{pref, G};
|
|
||||||
error ->
|
|
||||||
{X, Y, _, _} = GSize,
|
|
||||||
{center, {X, Y, 420, 520}}
|
|
||||||
end,
|
|
||||||
ok = wxDisplay:destroy(Display),
|
|
||||||
Geometry.
|
|
||||||
|
|
||||||
|
|
||||||
-spec handle_call(Message, From, State) -> Result
|
-spec handle_call(Message, From, State) -> Result
|
||||||
when Message :: term(),
|
when Message :: term(),
|
||||||
From :: {pid(), reference()},
|
From :: {pid(), reference()},
|
||||||
@ -257,9 +223,15 @@ handle_call(Unexpected, From, State) ->
|
|||||||
handle_cast({show, Accounts}, State) ->
|
handle_cast({show, Accounts}, State) ->
|
||||||
NewState = do_show(Accounts, State),
|
NewState = do_show(Accounts, State),
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
|
handle_cast({wallet, Name}, State) ->
|
||||||
|
ok = do_wallet(Name, State),
|
||||||
|
{noreply, State};
|
||||||
handle_cast({chain, ChainID, Node}, State) ->
|
handle_cast({chain, ChainID, Node}, State) ->
|
||||||
ok = do_chain(ChainID, Node, State),
|
ok = do_chain(ChainID, Node, State),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
|
handle_cast({trouble, Info}, State) ->
|
||||||
|
ok = handle_trouble(Info, State),
|
||||||
|
{noreply, State};
|
||||||
handle_cast(password, State) ->
|
handle_cast(password, State) ->
|
||||||
ok = do_ask_password(State),
|
ok = do_ask_password(State),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
@ -629,12 +601,13 @@ drop_key(State = #s{picker = Picker}) ->
|
|||||||
Selected -> drop_key(Selected + 1, State)
|
Selected -> drop_key(Selected + 1, State)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
drop_key(Selected, State = #s{frame = Frame, j = J, accounts = Accounts}) ->
|
drop_key(Selected, State = #s{frame = Frame, j = J, accounts = Accounts, prefs = Prefs}) ->
|
||||||
#poa{id = ID, name = Name} = lists:nth(Selected, Accounts),
|
#poa{id = ID, name = Name} = lists:nth(Selected, Accounts),
|
||||||
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("New Key")),
|
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("New Key"), [{size, {500, 150}}]),
|
||||||
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
||||||
Message = ["REALLY delete key: ", Name, " ?"],
|
Message = ["REALLY delete key?\r\n\r\n\"", Name, "\"\r\n(", ID, ")"],
|
||||||
MessageT = wxStaticText:new(Dialog, ?wxID_ANY, Message),
|
MessageT = wxStaticText:new(Dialog, ?wxID_ANY, Message,
|
||||||
|
[{style, ?wxALIGN_CENTRE_HORIZONTAL}]),
|
||||||
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
||||||
Affirm = wxButton:new(Dialog, ?wxID_OK),
|
Affirm = wxButton:new(Dialog, ?wxID_OK),
|
||||||
Cancel = wxButton:new(Dialog, ?wxID_CANCEL),
|
Cancel = wxButton:new(Dialog, ?wxID_CANCEL),
|
||||||
@ -645,13 +618,19 @@ drop_key(Selected, State = #s{frame = Frame, j = J, accounts = Accounts}) ->
|
|||||||
ok = wxDialog:setSizer(Dialog, Sizer),
|
ok = wxDialog:setSizer(Dialog, Sizer),
|
||||||
ok = wxBoxSizer:layout(Sizer),
|
ok = wxBoxSizer:layout(Sizer),
|
||||||
ok = wxFrame:center(Dialog),
|
ok = wxFrame:center(Dialog),
|
||||||
ok =
|
NewPrefs =
|
||||||
case wxDialog:showModal(Dialog) of
|
case wxDialog:showModal(Dialog) of
|
||||||
?wxID_OK -> gmc_con:drop_key(ID);
|
?wxID_OK ->
|
||||||
?wxID_CANCEL -> ok
|
gmc_con:drop_key(ID),
|
||||||
|
case Selected =:= length(Accounts) of
|
||||||
|
true -> maps:put(selected, Selected - 2, Prefs);
|
||||||
|
false -> Prefs
|
||||||
|
end;
|
||||||
|
?wxID_CANCEL ->
|
||||||
|
Prefs
|
||||||
end,
|
end,
|
||||||
ok = wxDialog:destroy(Dialog),
|
ok = wxDialog:destroy(Dialog),
|
||||||
State.
|
State#s{prefs = NewPrefs}.
|
||||||
|
|
||||||
|
|
||||||
copy(State = #s{id = {_, #w{wx = ID_T}}}) ->
|
copy(State = #s{id = {_, #w{wx = ID_T}}}) ->
|
||||||
@ -853,13 +832,16 @@ handle_button(Name, State) ->
|
|||||||
|
|
||||||
do_selection(Selected,
|
do_selection(Selected,
|
||||||
State = #s{prefs = Prefs, accounts = Accounts,
|
State = #s{prefs = Prefs, accounts = Accounts,
|
||||||
balance = {_, #w{wx = B}}, id = {_, #w{wx = I}}}) ->
|
balance = {_, #w{wx = B}}, id = {_, #w{wx = I}}})
|
||||||
|
when Selected < length(Accounts) ->
|
||||||
#poa{id = ID, balances = Balances} = lists:nth(Selected + 1, Accounts),
|
#poa{id = ID, balances = Balances} = lists:nth(Selected + 1, Accounts),
|
||||||
[#balance{total = Pucks}] = Balances,
|
[#balance{total = Pucks}] = Balances,
|
||||||
ok = wxStaticText:setLabel(I, ID),
|
ok = wxStaticText:setLabel(I, ID),
|
||||||
ok = wxStaticText:setLabel(B, price_to_string(Pucks)),
|
ok = wxStaticText:setLabel(B, price_to_string(Pucks)),
|
||||||
NewPrefs = maps:put(selected, Selected, Prefs),
|
NewPrefs = maps:put(selected, Selected, Prefs),
|
||||||
State#s{prefs = NewPrefs}.
|
State#s{prefs = NewPrefs};
|
||||||
|
do_selection(_, State) ->
|
||||||
|
do_selection(0, State).
|
||||||
|
|
||||||
|
|
||||||
do_show(Accounts, State = #s{prefs = Prefs, picker = Picker}) ->
|
do_show(Accounts, State = #s{prefs = Prefs, picker = Picker}) ->
|
||||||
@ -873,12 +855,25 @@ do_show(Accounts, State = #s{prefs = Prefs, picker = Picker}) ->
|
|||||||
ok = wxListBox:setSelection(Picker, Selected),
|
ok = wxListBox:setSelection(Picker, Selected),
|
||||||
do_selection(Selected, State#s{accounts = Accounts});
|
do_selection(Selected, State#s{accounts = Accounts});
|
||||||
_ ->
|
_ ->
|
||||||
Selected = maps:get(selected, Prefs),
|
Selected = maps:get(selected, Prefs, 0),
|
||||||
ok = wxListBox:setSelection(Picker, Selected),
|
ok = wxListBox:setSelection(Picker, Selected),
|
||||||
do_selection(Selected, State#s{accounts = Accounts})
|
do_selection(Selected, State#s{accounts = Accounts})
|
||||||
end.
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
do_wallet(none, #s{buttons = Buttons}) ->
|
||||||
|
#w{wx = WalletB} = lists:keyfind(wallet, #w.name, Buttons),
|
||||||
|
ok = wxButton:setLabel(WalletB, "[no wallet]");
|
||||||
|
do_wallet(Name, #s{buttons = Buttons}) ->
|
||||||
|
#w{wx = WalletB} = lists:keyfind(wallet, #w.name, Buttons),
|
||||||
|
ok = wxButton:setLabel(WalletB, Name).
|
||||||
|
|
||||||
|
|
||||||
|
do_chain(none, none, #s{buttons = Buttons}) ->
|
||||||
|
#w{wx = ChainB} = lists:keyfind(chain, #w.name, Buttons),
|
||||||
|
#w{wx = NodeB} = lists:keyfind(node, #w.name, Buttons),
|
||||||
|
ok = wxButton:setLabel(ChainB, "[no chain]"),
|
||||||
|
ok = wxButton:setLabel(NodeB, "[no node]");
|
||||||
do_chain(ChainID, #node{ip = IP}, #s{buttons = Buttons}) ->
|
do_chain(ChainID, #node{ip = IP}, #s{buttons = Buttons}) ->
|
||||||
#w{wx = ChainB} = lists:keyfind(chain, #w.name, Buttons),
|
#w{wx = ChainB} = lists:keyfind(chain, #w.name, Buttons),
|
||||||
#w{wx = NodeB} = lists:keyfind(node, #w.name, Buttons),
|
#w{wx = NodeB} = lists:keyfind(node, #w.name, Buttons),
|
||||||
@ -892,6 +887,10 @@ do_chain(ChainID, #node{ip = IP}, #s{buttons = Buttons}) ->
|
|||||||
ok = wxButton:setLabel(NodeB, Address).
|
ok = wxButton:setLabel(NodeB, Address).
|
||||||
|
|
||||||
|
|
||||||
|
handle_trouble(Info, #s{frame = Frame}) ->
|
||||||
|
zxw:show_message(Frame, Info).
|
||||||
|
|
||||||
|
|
||||||
do_ask_password(#s{frame = Frame, prefs = Prefs, j = J}) ->
|
do_ask_password(#s{frame = Frame, prefs = Prefs, j = J}) ->
|
||||||
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Password")),
|
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Password")),
|
||||||
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
||||||
|
@ -12,50 +12,9 @@
|
|||||||
|
|
||||||
-export([make_key/2, encode/1, decode/1]).
|
-export([make_key/2, encode/1, decode/1]).
|
||||||
-export([lcg/1]).
|
-export([lcg/1]).
|
||||||
%-export([start_link/1]).
|
|
||||||
%-export([init/1, terminate/2, code_change/3,
|
|
||||||
% handle_call/3, handle_cast/2, handle_info/2, handle_event/2]).
|
|
||||||
%-include("$zx_include/zx_logger.hrl").
|
|
||||||
-include("gmc.hrl").
|
-include("gmc.hrl").
|
||||||
|
|
||||||
|
|
||||||
%-record(s,
|
|
||||||
% {wx = none :: none | wx:wx_object(),
|
|
||||||
% frame = none :: none | wx:wx_object(),
|
|
||||||
% lang = en :: en | jp,
|
|
||||||
% j = none :: none | fun(),
|
|
||||||
% prefs = #{} :: #{atom() := term()},
|
|
||||||
% accounts = [] :: [clutch:ak()],
|
|
||||||
% picker = none :: none | wx:wx_object(),
|
|
||||||
% balance = {#w{}, #w{}} :: labeled(),
|
|
||||||
% buttons = [] :: [widget()]}).
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%% Startup Functions
|
|
||||||
|
|
||||||
%start_link(Accounts) ->
|
|
||||||
% wx_object:start_link({local, ?MODULE}, ?MODULE, Accounts, []).
|
|
||||||
|
|
||||||
|
|
||||||
%init({Accounts, Prefs}) ->
|
|
||||||
% ok = log(info, "GUI starting..."),
|
|
||||||
% Lang = maps:get(lang, Prefs, en_us),
|
|
||||||
% Trans = gmc_jt:read_translations(?MODULE),
|
|
||||||
% J = gmc_jt:j(Lang, Trans),
|
|
||||||
%
|
|
||||||
% Selected = maps:get(selected, Prefs, 1),
|
|
||||||
% AKs = [ID || #ak{id = ID} <- Accounts],
|
|
||||||
%
|
|
||||||
% Wx = wx:new(),
|
|
||||||
% Frame = wxFrame:new(Wx, ?wxID_ANY, J("Gajumaru Clutch")),
|
|
||||||
% MainSz = wxBoxSizer:new(?wxVERTICAL),
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%%
|
|
||||||
|
|
||||||
|
|
||||||
make_key("", <<>>) ->
|
make_key("", <<>>) ->
|
||||||
Pair = #{public := Public} = ecu_eddsa:sign_keypair(),
|
Pair = #{public := Public} = ecu_eddsa:sign_keypair(),
|
||||||
ID = aeser_api_encoder:encode(account_pubkey, Public),
|
ID = aeser_api_encoder:encode(account_pubkey, Public),
|
||||||
|
46
src/gmc_v.erl
Normal file
46
src/gmc_v.erl
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
-module(gmc_v).
|
||||||
|
-vsn("0.1.0").
|
||||||
|
-author("Craig Everett <craigeverett@qpq.swiss>").
|
||||||
|
-copyright("QPQ AG <info@qpq.swiss>").
|
||||||
|
-license("GPL-3.0-or-later").
|
||||||
|
|
||||||
|
-export([safe_size/2]).
|
||||||
|
|
||||||
|
|
||||||
|
-callback to_front(Window) -> ok
|
||||||
|
when Window :: wx:wx_object().
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
-spec safe_size(Frame, Prefs) -> ok
|
||||||
|
when Frame :: wx:wx_object(),
|
||||||
|
Prefs :: map().
|
||||||
|
|
||||||
|
safe_size(Frame, Prefs) ->
|
||||||
|
case safe_size(Prefs) of
|
||||||
|
{pref, max} ->
|
||||||
|
wxTopLevelWindow:maximize(Frame);
|
||||||
|
{pref, WSize} ->
|
||||||
|
wxFrame:setSize(Frame, WSize);
|
||||||
|
{center, WSize} ->
|
||||||
|
ok = wxFrame:setSize(Frame, WSize),
|
||||||
|
wxFrame:center(Frame)
|
||||||
|
end.
|
||||||
|
|
||||||
|
|
||||||
|
safe_size(Prefs) ->
|
||||||
|
Display = wxDisplay:new(),
|
||||||
|
GSize = wxDisplay:getGeometry(Display),
|
||||||
|
ok = wxDisplay:destroy(Display),
|
||||||
|
Geometry =
|
||||||
|
case maps:find(geometry, Prefs) of
|
||||||
|
{ok, none} ->
|
||||||
|
{X, Y, _, _} = GSize,
|
||||||
|
{center, {X, Y, 700, 500}};
|
||||||
|
{ok, G} ->
|
||||||
|
{pref, G};
|
||||||
|
error ->
|
||||||
|
{X, Y, _, _} = GSize,
|
||||||
|
{center, {X, Y, 700, 500}}
|
||||||
|
end,
|
||||||
|
Geometry.
|
@ -5,6 +5,7 @@
|
|||||||
-license("GPL-3.0-or-later").
|
-license("GPL-3.0-or-later").
|
||||||
|
|
||||||
-behavior(wx_object).
|
-behavior(wx_object).
|
||||||
|
-behavior(gmc_v).
|
||||||
-include_lib("wx/include/wx.hrl").
|
-include_lib("wx/include/wx.hrl").
|
||||||
-export([to_front/1]).
|
-export([to_front/1]).
|
||||||
-export([set_manifest/1]).
|
-export([set_manifest/1]).
|
||||||
@ -90,16 +91,7 @@ init({Prefs, Manifest}) ->
|
|||||||
_ = wxFrame:setSizer(Frame, MainSz),
|
_ = wxFrame:setSizer(Frame, MainSz),
|
||||||
_ = wxSizer:layout(MainSz),
|
_ = wxSizer:layout(MainSz),
|
||||||
|
|
||||||
ok =
|
ok = gmc_v:safe_size(Frame, Prefs),
|
||||||
case safe_size(Prefs) of
|
|
||||||
{pref, max} ->
|
|
||||||
wxTopLevelWindow:maximize(Frame);
|
|
||||||
{pref, WSize} ->
|
|
||||||
wxFrame:setSize(Frame, WSize);
|
|
||||||
{center, WSize} ->
|
|
||||||
ok = wxFrame:setSize(Frame, WSize),
|
|
||||||
wxFrame:center(Frame)
|
|
||||||
end,
|
|
||||||
|
|
||||||
ok = wxFrame:connect(Frame, close_window),
|
ok = wxFrame:connect(Frame, close_window),
|
||||||
ok = wxFrame:connect(Frame, command_button_clicked),
|
ok = wxFrame:connect(Frame, command_button_clicked),
|
||||||
@ -112,32 +104,6 @@ init({Prefs, Manifest}) ->
|
|||||||
buttons = Buttons, nets = Manifest, book = Notebook},
|
buttons = Buttons, nets = Manifest, book = Notebook},
|
||||||
{Frame, State}.
|
{Frame, State}.
|
||||||
|
|
||||||
safe_size(Prefs) ->
|
|
||||||
Display = wxDisplay:new(),
|
|
||||||
GSize = wxDisplay:getGeometry(Display),
|
|
||||||
CSize = wxDisplay:getClientArea(Display),
|
|
||||||
PPI =
|
|
||||||
try
|
|
||||||
wxDisplay:getPPI(Display)
|
|
||||||
catch
|
|
||||||
Class:Exception -> {Class, Exception}
|
|
||||||
end,
|
|
||||||
ok = log(info, "Geometry: ~p", [GSize]),
|
|
||||||
ok = log(info, "ClientArea: ~p", [CSize]),
|
|
||||||
ok = log(info, "PPI: ~p", [PPI]),
|
|
||||||
Geometry =
|
|
||||||
case maps:find({?MODULE, geometry}, Prefs) of
|
|
||||||
{ok, none} ->
|
|
||||||
{X, Y, _, _} = GSize,
|
|
||||||
{center, {X, Y, 420, 520}};
|
|
||||||
{ok, G} ->
|
|
||||||
{pref, G};
|
|
||||||
error ->
|
|
||||||
{X, Y, _, _} = GSize,
|
|
||||||
{center, {X, Y, 420, 520}}
|
|
||||||
end,
|
|
||||||
ok = wxDisplay:destroy(Display),
|
|
||||||
Geometry.
|
|
||||||
|
|
||||||
add_pages(Notebook, J, [#net{id = ID, chains = Chains} | Rest]) ->
|
add_pages(Notebook, J, [#net{id = ID, chains = Chains} | Rest]) ->
|
||||||
Page = wxScrolledWindow:new(Notebook),
|
Page = wxScrolledWindow:new(Notebook),
|
||||||
|
@ -5,8 +5,10 @@
|
|||||||
-license("GPL-3.0-or-later").
|
-license("GPL-3.0-or-later").
|
||||||
|
|
||||||
-behavior(wx_object).
|
-behavior(wx_object).
|
||||||
|
-behavior(gmc_v).
|
||||||
-include_lib("wx/include/wx.hrl").
|
-include_lib("wx/include/wx.hrl").
|
||||||
-export([to_front/1]).
|
-export([to_front/1]).
|
||||||
|
-export([show/2]).
|
||||||
-export([start_link/1]).
|
-export([start_link/1]).
|
||||||
-export([init/1, terminate/2, code_change/3,
|
-export([init/1, terminate/2, code_change/3,
|
||||||
handle_call/3, handle_cast/2, handle_info/2, handle_event/2]).
|
handle_call/3, handle_cast/2, handle_info/2, handle_event/2]).
|
||||||
@ -39,6 +41,13 @@ to_front(Win) ->
|
|||||||
wx_object:cast(Win, to_front).
|
wx_object:cast(Win, to_front).
|
||||||
|
|
||||||
|
|
||||||
|
-spec show(Win, Manifest) -> ok
|
||||||
|
when Win :: wx:xw_object(),
|
||||||
|
Manifest :: [#wr{}].
|
||||||
|
|
||||||
|
show(Win, Manifest) ->
|
||||||
|
wx_object:cast(Win, {show, Manifest}).
|
||||||
|
|
||||||
|
|
||||||
%%% Startup
|
%%% Startup
|
||||||
|
|
||||||
@ -80,21 +89,11 @@ init({Prefs, Manifest}) ->
|
|||||||
ok = wxFrame:setSizer(Frame, MainSz),
|
ok = wxFrame:setSizer(Frame, MainSz),
|
||||||
ok = wxSizer:layout(MainSz),
|
ok = wxSizer:layout(MainSz),
|
||||||
|
|
||||||
ok =
|
ok = gmc_v:safe_size(Frame, Prefs),
|
||||||
case safe_size(Prefs) of
|
|
||||||
{pref, max} ->
|
|
||||||
wxTopLevelWindow:maximize(Frame);
|
|
||||||
{pref, WSize} ->
|
|
||||||
wxFrame:setSize(Frame, WSize);
|
|
||||||
{center, WSize} ->
|
|
||||||
ok = wxFrame:setSize(Frame, WSize),
|
|
||||||
wxFrame:center(Frame)
|
|
||||||
end,
|
|
||||||
|
|
||||||
ok = wxFrame:connect(Frame, command_button_clicked),
|
ok = wxFrame:connect(Frame, command_button_clicked),
|
||||||
ok = wxFrame:connect(Frame, close_window),
|
ok = wxFrame:connect(Frame, close_window),
|
||||||
true = wxFrame:show(Frame),
|
true = wxFrame:show(Frame),
|
||||||
ok = wxListBox:connect(Picker, command_listbox_selected),
|
|
||||||
ok = wxListBox:connect(Picker, command_listbox_doubleclicked),
|
ok = wxListBox:connect(Picker, command_listbox_doubleclicked),
|
||||||
State = #s{wx = Wx, frame = Frame, lang = Lang, j = J, prefs = Prefs,
|
State = #s{wx = Wx, frame = Frame, lang = Lang, j = J, prefs = Prefs,
|
||||||
wallets = Manifest,
|
wallets = Manifest,
|
||||||
@ -103,34 +102,6 @@ init({Prefs, Manifest}) ->
|
|||||||
{Frame, State}.
|
{Frame, State}.
|
||||||
|
|
||||||
|
|
||||||
safe_size(Prefs) ->
|
|
||||||
Display = wxDisplay:new(),
|
|
||||||
GSize = wxDisplay:getGeometry(Display),
|
|
||||||
CSize = wxDisplay:getClientArea(Display),
|
|
||||||
PPI =
|
|
||||||
try
|
|
||||||
wxDisplay:getPPI(Display)
|
|
||||||
catch
|
|
||||||
Class:Exception -> {Class, Exception}
|
|
||||||
end,
|
|
||||||
ok = log(info, "Geometry: ~p", [GSize]),
|
|
||||||
ok = log(info, "ClientArea: ~p", [CSize]),
|
|
||||||
ok = log(info, "PPI: ~p", [PPI]),
|
|
||||||
Geometry =
|
|
||||||
case maps:find(geometry, Prefs) of
|
|
||||||
{ok, none} ->
|
|
||||||
{X, Y, _, _} = GSize,
|
|
||||||
{center, {X, Y, 420, 520}};
|
|
||||||
{ok, G} ->
|
|
||||||
{pref, G};
|
|
||||||
error ->
|
|
||||||
{X, Y, _, _} = GSize,
|
|
||||||
{center, {X, Y, 420, 520}}
|
|
||||||
end,
|
|
||||||
ok = wxDisplay:destroy(Display),
|
|
||||||
Geometry.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
%%% wx_object
|
%%% wx_object
|
||||||
|
|
||||||
@ -142,6 +113,9 @@ handle_call(Unexpected, From, State) ->
|
|||||||
handle_cast(to_front, State = #s{frame = Frame}) ->
|
handle_cast(to_front, State = #s{frame = Frame}) ->
|
||||||
ok = wxFrame:raise(Frame),
|
ok = wxFrame:raise(Frame),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
|
handle_cast({show, Manifest}, State) ->
|
||||||
|
NewState = do_show(Manifest, State),
|
||||||
|
{noreply, NewState};
|
||||||
handle_cast(Unexpected, State) ->
|
handle_cast(Unexpected, State) ->
|
||||||
ok = log(warning, "Unexpected cast: ~tp~n", [Unexpected]),
|
ok = log(warning, "Unexpected cast: ~tp~n", [Unexpected]),
|
||||||
{noreply, State}.
|
{noreply, State}.
|
||||||
@ -160,10 +134,16 @@ handle_event(#wx{event = #wxCommand{type = command_button_clicked},
|
|||||||
#w{name = open} -> do_open(State);
|
#w{name = open} -> do_open(State);
|
||||||
#w{name = new} -> do_new(State);
|
#w{name = new} -> do_new(State);
|
||||||
#w{name = import} -> do_import(State);
|
#w{name = import} -> do_import(State);
|
||||||
|
#w{name = drop} -> do_drop(State);
|
||||||
#w{name = Name} -> handle_button(Name, State);
|
#w{name = Name} -> handle_button(Name, State);
|
||||||
false -> State
|
false -> State
|
||||||
end,
|
end,
|
||||||
{noreply, NewState};
|
{noreply, NewState};
|
||||||
|
handle_event(#wx{event = #wxCommand{type = command_listbox_doubleclicked,
|
||||||
|
commandInt = Selected}},
|
||||||
|
State) ->
|
||||||
|
NewState = do_open2(Selected + 1, State),
|
||||||
|
{noreply, NewState};
|
||||||
handle_event(#wx{event = #wxClose{}}, State) ->
|
handle_event(#wx{event = #wxClose{}}, State) ->
|
||||||
ok = do_close(State),
|
ok = do_close(State),
|
||||||
{noreply, State};
|
{noreply, State};
|
||||||
@ -186,6 +166,12 @@ terminate(Reason, State) ->
|
|||||||
|
|
||||||
%%% doers
|
%%% doers
|
||||||
|
|
||||||
|
do_show(Manifest, State = #s{picker = Picker}) ->
|
||||||
|
Names = [Name || #wr{name = Name} <- Manifest],
|
||||||
|
ok = wxListBox:set(Picker, Names),
|
||||||
|
State#s{wallets = Manifest}.
|
||||||
|
|
||||||
|
|
||||||
do_close(#s{frame = Frame, prefs = Prefs}) ->
|
do_close(#s{frame = Frame, prefs = Prefs}) ->
|
||||||
Geometry =
|
Geometry =
|
||||||
case wxTopLevelWindow:isMaximized(Frame) of
|
case wxTopLevelWindow:isMaximized(Frame) of
|
||||||
@ -229,7 +215,7 @@ do_open3(Path, State = #s{frame = Frame, j = J}) ->
|
|||||||
Dialog = wxDialog:new(Frame, ?wxID_ANY, Label),
|
Dialog = wxDialog:new(Frame, ?wxID_ANY, Label),
|
||||||
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
||||||
PassSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, Label}]),
|
PassSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, Label}]),
|
||||||
PassTx = wxTextCtrl:new(Dialog, ?wxID_ANY),
|
PassTx = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]),
|
||||||
_ = wxStaticBoxSizer:add(PassSz, PassTx, zxw:flags(wide)),
|
_ = wxStaticBoxSizer:add(PassSz, PassTx, zxw:flags(wide)),
|
||||||
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
||||||
Affirm = wxButton:new(Dialog, ?wxID_OK),
|
Affirm = wxButton:new(Dialog, ?wxID_OK),
|
||||||
@ -242,17 +228,18 @@ do_open3(Path, State = #s{frame = Frame, j = J}) ->
|
|||||||
ok = wxStyledTextCtrl:setFocus(PassTx),
|
ok = wxStyledTextCtrl:setFocus(PassTx),
|
||||||
case wxDialog:showModal(Dialog) of
|
case wxDialog:showModal(Dialog) of
|
||||||
?wxID_OK ->
|
?wxID_OK ->
|
||||||
ok = wxFileDialog:destroy(Dialog),
|
|
||||||
case wxTextCtrl:getValue(PassTx) of
|
case wxTextCtrl:getValue(PassTx) of
|
||||||
"" ->
|
"" ->
|
||||||
|
ok = wxDialog:destroy(Dialog),
|
||||||
State;
|
State;
|
||||||
Password ->
|
Password ->
|
||||||
|
ok = wxDialog:destroy(Dialog),
|
||||||
ok = gmc_con:open_wallet(Path, Password),
|
ok = gmc_con:open_wallet(Path, Password),
|
||||||
ok = do_close(State),
|
ok = do_close(State),
|
||||||
State
|
State
|
||||||
end;
|
end;
|
||||||
?wxID_CANCEL ->
|
?wxID_CANCEL ->
|
||||||
ok = wxFileDialog:destroy(Dialog),
|
ok = wxDialog:destroy(Dialog),
|
||||||
State
|
State
|
||||||
end.
|
end.
|
||||||
|
|
||||||
@ -285,18 +272,19 @@ do_new(State = #s{frame = Frame, j = J, prefs = Prefs}) ->
|
|||||||
end.
|
end.
|
||||||
|
|
||||||
do_new2(Path, J, Frame) ->
|
do_new2(Path, J, Frame) ->
|
||||||
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Set Node")),
|
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Set Node"), [{size, {400, 250}}]),
|
||||||
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
||||||
|
|
||||||
NameSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Name")}]),
|
NameSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Name")}]),
|
||||||
NameTx = wxTextCtrl:new(Dialog, ?wxID_ANY),
|
NameTx = wxTextCtrl:new(Dialog, ?wxID_ANY),
|
||||||
_ = wxSizer:add(NameSz, NameTx, zxw:flags(wide)),
|
_ = wxSizer:add(NameSz, NameTx, zxw:flags(wide)),
|
||||||
PassSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Passphrase")}]),
|
Label1 = J("Passphrase (optional)"),
|
||||||
PassTx = wxTextCtrl:new(Dialog, ?wxID_ANY),
|
PassSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, Label1}]),
|
||||||
|
PassTx = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]),
|
||||||
_ = wxSizer:add(PassSz, PassTx, zxw:flags(wide)),
|
_ = wxSizer:add(PassSz, PassTx, zxw:flags(wide)),
|
||||||
Label = "Passphrase Confirmation",
|
Label2= J("Passphrase Confirmation"),
|
||||||
PassConSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J(Label)}]),
|
PassConSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, Label2}]),
|
||||||
PassConTx = wxTextCtrl:new(Dialog, ?wxID_ANY),
|
PassConTx = wxTextCtrl:new(Dialog, ?wxID_ANY, [{style, ?wxTE_PASSWORD}]),
|
||||||
_ = wxSizer:add(PassConSz, PassConTx, zxw:flags(wide)),
|
_ = wxSizer:add(PassConSz, PassConTx, zxw:flags(wide)),
|
||||||
|
|
||||||
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
||||||
@ -312,8 +300,7 @@ do_new2(Path, J, Frame) ->
|
|||||||
|
|
||||||
ok = wxDialog:setSizer(Dialog, Sizer),
|
ok = wxDialog:setSizer(Dialog, Sizer),
|
||||||
ok = wxBoxSizer:layout(Sizer),
|
ok = wxBoxSizer:layout(Sizer),
|
||||||
ok = wxFrame:setSize(Dialog, {500, 200}),
|
ok = wxDialog:center(Dialog),
|
||||||
ok = wxFrame:center(Dialog),
|
|
||||||
ok = wxStyledTextCtrl:setFocus(NameTx),
|
ok = wxStyledTextCtrl:setFocus(NameTx),
|
||||||
|
|
||||||
Result =
|
Result =
|
||||||
@ -419,6 +406,45 @@ do_import2(Dir, File, J, Frame) ->
|
|||||||
Result.
|
Result.
|
||||||
|
|
||||||
|
|
||||||
do_selection(Selected, State = #s{prefs = Prefs}) ->
|
do_drop(State = #s{picker = Picker}) ->
|
||||||
NewPrefs = maps:put(selected, Selected, Prefs),
|
case wxListBox:getSelection(Picker) of
|
||||||
State#s{prefs = NewPrefs}.
|
-1 -> State;
|
||||||
|
Selected -> do_drop(Selected + 1, State)
|
||||||
|
end.
|
||||||
|
|
||||||
|
do_drop(Selected, State = #s{j = J, frame = Frame, wallets = Wallets}) ->
|
||||||
|
#wr{name = Name, path = Path} = lists:nth(Selected, Wallets),
|
||||||
|
Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Drop Wallet")),
|
||||||
|
Sizer = wxBoxSizer:new(?wxVERTICAL),
|
||||||
|
|
||||||
|
MessageM = J("REALLY delete wallet?"),
|
||||||
|
Message = ["\r\n", MessageM, "\r\n\r\n\"", Name, "\""],
|
||||||
|
MessageT = wxStaticText:new(Dialog, ?wxID_ANY, Message,
|
||||||
|
[{style, ?wxALIGN_CENTRE_HORIZONTAL}]),
|
||||||
|
DeleteM = J("Delete file data?"),
|
||||||
|
DeleteCheck = wxCheckBox:new(Dialog, ?wxID_ANY, DeleteM),
|
||||||
|
|
||||||
|
ButtSz = wxBoxSizer:new(?wxHORIZONTAL),
|
||||||
|
Affirm = wxButton:new(Dialog, ?wxID_OK),
|
||||||
|
Cancel = wxButton:new(Dialog, ?wxID_CANCEL),
|
||||||
|
_ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)),
|
||||||
|
_ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)),
|
||||||
|
|
||||||
|
_ = wxSizer:add(Sizer, MessageT, zxw:flags(base)),
|
||||||
|
_ = wxSizer:add(Sizer, DeleteCheck, zxw:flags(base)),
|
||||||
|
_ = wxSizer:add(Sizer, ButtSz, zxw:flags(wide)),
|
||||||
|
|
||||||
|
ok = wxDialog:setSizer(Dialog, Sizer),
|
||||||
|
ok = wxBoxSizer:layout(Sizer),
|
||||||
|
ok = wxFrame:setSize(Dialog, {500, 200}),
|
||||||
|
ok = wxFrame:center(Dialog),
|
||||||
|
|
||||||
|
ok =
|
||||||
|
case wxDialog:showModal(Dialog) of
|
||||||
|
?wxID_OK ->
|
||||||
|
Delete = wxCheckBox:getValue(DeleteCheck),
|
||||||
|
gmc_con:drop_wallet(Path, Delete);
|
||||||
|
?wxID_CANCEL ->
|
||||||
|
ok
|
||||||
|
end,
|
||||||
|
State.
|
||||||
|
@ -5,12 +5,12 @@
|
|||||||
{desc,"A desktop client for the Gajumaru network of blockchain networks"}.
|
{desc,"A desktop client for the Gajumaru network of blockchain networks"}.
|
||||||
{author,"Craig Everett"}.
|
{author,"Craig Everett"}.
|
||||||
{package_id,{"otpr","clutch",{0,1,0}}}.
|
{package_id,{"otpr","clutch",{0,1,0}}}.
|
||||||
{deps,[{"otpr","zj",{1,1,0}},
|
{deps,[{"otpr","aeserialization",{0,1,2}},
|
||||||
|
{"otpr","zj",{1,1,0}},
|
||||||
{"otpr","aesophia",{7,1,2}},
|
{"otpr","aesophia",{7,1,2}},
|
||||||
{"otpr","aebytecode",{3,2,1}},
|
{"otpr","aebytecode",{3,2,1}},
|
||||||
{"otpr","hakuzaru",{0,1,0}},
|
{"otpr","hakuzaru",{0,1,0}},
|
||||||
{"otpr","erl_base58",{0,1,0}},
|
{"otpr","erl_base58",{0,1,0}},
|
||||||
{"otpr","aeserialization",{0,1,0}},
|
|
||||||
{"otpr","eblake2",{1,0,0}},
|
{"otpr","eblake2",{1,0,0}},
|
||||||
{"otpr","ec_utils",{1,0,0}},
|
{"otpr","ec_utils",{1,0,0}},
|
||||||
{"otpr","zxwidgets",{1,0,1}}]}.
|
{"otpr","zxwidgets",{1,0,1}}]}.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user