1%% 2%% wpc_deselect_previous.erl -- 3%% 4%% Subtract current selection from previous selection. 5%% 6%% Copyright (c) 2010-2011 Richard Jones. 7%% 8%% See the file "license.terms" for information on usage and redistribution 9%% of this file, and for a DISCLAIMER OF ALL WARRANTIES. 10%% 11 12-module(wpc_deselect_previous). 13-export([init/0,menu/2,command/2]). 14-include_lib("src/wings.hrl"). 15 16init() -> 17 true. 18 19%%% Menu 20menu({select},Menu) -> 21 lists:reverse(parse(Menu, [], false)); 22menu(_,Menu) -> 23 Menu. 24 25parse([], NewMenu, true) -> 26 NewMenu; 27parse([], NewMenu, false) -> 28 [deselect_previous(), separator|NewMenu]; 29parse([A = {_,inverse,_}|Rest], NewMenu, false) -> 30 parse(Rest, [deselect_previous(),A|NewMenu], true); 31parse([Elem|Rest], NewMenu, Found) -> 32 parse(Rest, [Elem|NewMenu], Found). 33 34deselect_previous() -> 35 {?__(1,"Deselect Previous"),deselect_previous, 36 ?__(2,"Subtract the previous selection state from the current selection")}. 37 38%%% Commands 39command({select,deselect_previous}, St) -> 40 {save_state,deselect_previous(St)}; 41command(_, _) -> 42 next. 43 44deselect_previous(St) -> 45 PrevSt = wings_undo:undo(St), 46 deselect_previous(PrevSt, St). 47 48deselect_previous(#st{sel=PrevSel,selmode=Mode}, #st{sel=Sel,selmode=Mode}=St) -> 49 NewSel = subtract(Sel, PrevSel), 50 St#st{sel=NewSel}; 51deselect_previous(PrevSt0, #st{selmode=Mode}=St) -> 52 PrevSt = wings_sel_conv:mode(Mode, PrevSt0), 53 deselect_previous(PrevSt, St). 54 55subtract([{Id1,_}=E1|Es1], [{Id2,_}|_]=Set2) when Id1 < Id2 -> 56 [E1|subtract(Es1, Set2)]; 57subtract([{Id1,_}|_]=Set1, [{Id2,_}|Es2]) when Id1 > Id2 -> 58 subtract(Set1, Es2); 59subtract([{Id,E1}|Es1], [{Id,E2}|Es2]) -> 60 E = gb_sets:subtract(E1, E2), 61 case gb_sets:is_empty(E) of 62 true -> subtract(Es1, Es2); 63 false -> [{Id,E}|subtract(Es1, Es2)] 64 end; 65subtract([], _Es2) -> []; 66subtract(Es1, []) -> Es1. 67