@@ -18,6 +18,7 @@ use std::cmp::min;
1818use std:: ops:: Range ;
1919use std:: any:: Any ;
2020use std:: sync:: { Mutex , Weak } ;
21+ use std:: mem;
2122
2223use serde_json:: Value ;
2324
@@ -59,16 +60,20 @@ pub enum EditViewCommands {
5960 SelectAll ,
6061}
6162
63+ type Method = String ;
64+ type Params = Value ;
65+
6266/// State and behavior for one editor view.
6367pub struct EditView {
64- view_id : String ,
68+ view_id : Option < String > ,
6569 line_cache : LineCache ,
6670 dwrite_factory : directwrite:: Factory ,
6771 resources : Option < Resources > ,
6872 scroll_offset : f32 ,
6973 size : ( f32 , f32 ) , // in px units
7074 viewport : Range < usize > ,
7175 core : Weak < Mutex < Core > > ,
76+ pending : Vec < ( Method , Params ) > ,
7277}
7378
7479struct Resources {
@@ -116,7 +121,10 @@ impl Widget for EditView {
116121 fn layout ( & mut self , bc : & BoxConstraints , _children : & [ Id ] , _size : Option < ( f32 , f32 ) > ,
117122 _ctx : & mut LayoutCtx ) -> LayoutResult
118123 {
119- LayoutResult :: Size ( bc. constrain ( ( 0.0 , 0.0 ) ) )
124+ let size = bc. constrain ( ( 0.0 , 0.0 ) ) ;
125+ self . size = size;
126+ self . update_viewport ( ) ;
127+ LayoutResult :: Size ( size)
120128 }
121129
122130 fn mouse ( & mut self , event : & MouseEvent , _ctx : & mut HandlerCtx ) -> bool {
@@ -137,13 +145,24 @@ impl Widget for EditView {
137145 if let Some ( cmd) = payload. downcast_ref :: < EditViewCommands > ( ) {
138146 match cmd {
139147 EditViewCommands :: ViewId ( view_id) => {
140- self . view_id = view_id. to_string ( ) ;
148+ self . view_id = Some ( view_id. to_string ( ) ) ;
149+ self . viewport = 0 ..0 ; // zorch viewport
150+ self . update_viewport ( ) ;
151+
152+ // Fire off the pending notifications
153+ let pending = mem:: replace ( & mut self . pending , Vec :: new ( ) ) ;
154+ for notification in pending {
155+ let ( method, params) = notification;
156+ self . send_edit_cmd ( & method, & params) ;
157+ }
141158 }
142159 EditViewCommands :: ApplyUpdate ( update) => {
143160 self . apply_update ( & update) ;
161+ ctx. invalidate ( ) ;
144162 }
145163 EditViewCommands :: ScrollTo ( line) => {
146164 self . scroll_to ( * line) ;
165+ ctx. invalidate ( ) ;
147166 }
148167 EditViewCommands :: Core ( core) => {
149168 self . core = core. clone ( ) ;
@@ -164,48 +183,55 @@ impl Widget for EditView {
164183 self . send_action ( "transpose" ) ;
165184 }
166185 EditViewCommands :: AddCursorAbove => {
167- self . add_cursor_above ( ) ;
186+ // Note: some subtlety around find, the escape key cancels it, but the menu
187+ // shouldn't.
188+ self . send_action ( "add_selection_above" ) ;
168189 }
169190 EditViewCommands :: AddCursorBelow => {
170- self . add_cursor_below ( ) ;
191+ // Note: some subtlety around find, the escape key cancels it, but the menu
192+ // shouldn't.
193+ self . send_action ( "add_selection_below" ) ;
171194 }
172195 EditViewCommands :: SingleSelection => {
173- self . single_selection ( ) ;
196+ // Note: some subtlety around find, the escape key cancels it, but the menu
197+ // shouldn't.
198+ self . send_action ( "cancel_operation" ) ;
174199 }
175200 EditViewCommands :: SelectAll => {
176- self . select_all ( ) ;
201+ // Note: some subtlety around find, the escape key cancels it, but the menu
202+ // shouldn't.
203+ self . send_action ( "select_all" ) ;
177204 }
178205 }
179- // TODO: Finer grained invalidation
180- ctx. invalidate ( ) ;
181206 }
182207 true
183208 }
184209
185- fn key ( & mut self , event : & KeyEvent , _ctx : & mut HandlerCtx ) -> bool {
210+ fn key ( & mut self , event : & KeyEvent , ctx : & mut HandlerCtx ) -> bool {
186211 match event. key {
187212 KeyVariant :: Vkey ( vk) => {
188- self . keydown ( vk, event. mods ) ;
213+ return self . keydown ( vk, event. mods , ctx )
189214 }
190215 KeyVariant :: Char ( ch) => {
191216 self . char ( ch as u32 , event. mods ) ;
192217 }
193- }
218+ }
194219 true
195220 }
196221}
197222
198223impl EditView {
199224 pub fn new ( ) -> EditView {
200225 EditView {
201- view_id : "" . into ( ) ,
226+ view_id : Default :: default ( ) ,
202227 line_cache : LineCache :: new ( ) ,
203228 dwrite_factory : directwrite:: Factory :: new ( ) . unwrap ( ) ,
204229 resources : None ,
205230 scroll_offset : 0.0 ,
206231 size : ( 0.0 , 0.0 ) ,
207232 viewport : 0 ..0 ,
208233 core : Default :: default ( ) ,
234+ pending : Default :: default ( ) ,
209235 }
210236 }
211237
@@ -232,11 +258,6 @@ impl EditView {
232258 self . resources = None ;
233259 }
234260
235- pub fn size ( & mut self , x : f32 , y : f32 ) {
236- self . size = ( x, y) ;
237- self . constrain_scroll ( ) ;
238- }
239-
240261 pub fn clear_line_cache ( & mut self ) {
241262 self . line_cache = LineCache :: new ( ) ;
242263 }
@@ -254,7 +275,7 @@ impl EditView {
254275 self . constrain_scroll ( ) ;
255276 }
256277
257- pub fn char ( & self , ch : u32 , _mods : u32 ) {
278+ pub fn char ( & mut self , ch : u32 , _mods : u32 ) {
258279 if let Some ( c) = :: std:: char:: from_u32 ( ch) {
259280 if ch >= 0x20 {
260281 // Don't insert control characters
@@ -264,34 +285,35 @@ impl EditView {
264285 }
265286 }
266287
267- fn send_edit_cmd ( & self , method : & str , params : & Value ) {
268- let edit_params = json ! ( {
269- "method" : method,
270- "params" : params,
271- "view_id" : & self . view_id,
272- } ) ;
273- self . send_notification ( "edit" , & edit_params) ;
274- }
288+ fn send_edit_cmd ( & mut self , method : & str , params : & Value ) {
289+ // TODO: When let_chains lands, this will be easier.
290+ let core = self . core . upgrade ( ) ;
291+ if core. is_some ( ) && self . view_id . is_some ( ) {
292+ let view_id = & self . view_id . clone ( ) . unwrap ( ) ;
293+ let edit_params = json ! ( {
294+ "method" : method,
295+ "params" : params,
296+ "view_id" : view_id,
297+ } ) ;
275298
276- fn send_notification ( & self , method : & str , params : & Value ) {
277- if let Some ( ref core) = self . core . upgrade ( ) {
278- core. lock ( ) . unwrap ( ) . send_notification ( method, params) ;
299+ let core = core. unwrap ( ) ;
300+ core. lock ( ) . unwrap ( ) . send_notification ( "edit" , & edit_params) ;
279301 // NOTE: For debugging, could be replaced by trace logging
280302 // println!("fe->core: {}", json!({
281303 // "method": method,
282304 // "params": params,
283305 // }));
284306 } else {
285- // TODO: queue pending
307+ self . pending . push ( ( method . to_owned ( ) , params . clone ( ) ) ) ;
286308 }
287309 }
288310
289311 /// Sends a simple action with no parameters
290- fn send_action ( & self , method : & str ) {
312+ fn send_action ( & mut self , method : & str ) {
291313 self . send_edit_cmd ( method, & json ! ( [ ] ) ) ;
292314 }
293315
294- pub fn keydown ( & mut self , vk_code : i32 , mods : u32 ) -> bool {
316+ pub fn keydown ( & mut self , vk_code : i32 , mods : u32 , ctx : & mut HandlerCtx ) -> bool {
295317 // Handle special keys here
296318 match vk_code {
297319 VK_RETURN => {
@@ -307,6 +329,7 @@ impl EditView {
307329 self . scroll_offset -= LINE_SPACE ;
308330 self . constrain_scroll ( ) ;
309331 self . update_viewport ( ) ;
332+ ctx. invalidate ( ) ;
310333 } else {
311334 let action = if mods == M_CTRL | M_ALT {
312335 "add_selection_above"
@@ -322,6 +345,7 @@ impl EditView {
322345 self . scroll_offset += LINE_SPACE ;
323346 self . constrain_scroll ( ) ;
324347 self . update_viewport ( ) ;
348+ ctx. invalidate ( ) ;
325349 } else {
326350 let action = if mods == M_CTRL | M_ALT {
327351 "add_selection_below"
@@ -421,31 +445,6 @@ impl EditView {
421445 true
422446 }
423447
424- // Commands
425- pub fn add_cursor_above ( & mut self ) {
426- // Note: some subtlety around find, the escape key cancels it, but the menu
427- // shouldn't.
428- self . send_action ( "add_selection_above" ) ;
429- }
430-
431- pub fn add_cursor_below ( & mut self ) {
432- // Note: some subtlety around find, the escape key cancels it, but the menu
433- // shouldn't.
434- self . send_action ( "add_selection_below" ) ;
435- }
436-
437- pub fn single_selection ( & mut self ) {
438- // Note: some subtlety around find, the escape key cancels it, but the menu
439- // shouldn't.
440- self . send_action ( "cancel_operation" ) ;
441- }
442-
443- pub fn select_all ( & mut self ) {
444- // Note: some subtlety around find, the escape key cancels it, but the menu
445- // shouldn't.
446- self . send_action ( "select_all" ) ;
447- }
448-
449448 pub fn mouse_wheel ( & mut self , delta : i32 , _mods : u32 ) {
450449 // TODO: scale properly, taking SPI_GETWHEELSCROLLLINES into account
451450 let scroll_scaling = 0.5 ;
0 commit comments