1 // High level management of views
2 // Copyright (C) 2004 Core Technologies.
3
4 // This file is part of e93.
5 //
6 // e93 is free software; you can redistribute it and/or modify
7 // it under the terms of the e93 LICENSE AGREEMENT.
8 //
9 // e93 is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // e93 LICENSE AGREEMENT for more details.
13 //
14 // You should have received a copy of the e93 LICENSE AGREEMENT
15 // along with e93; see the file "LICENSE.TXT".
16
17 #include "includes.h"
18
GetSelectionInView(EDITOR_VIEW * view,SELECTION_UNIVERSE * selection)19 static SELECTION_UNIVERSE *GetSelectionInView(EDITOR_VIEW *view,SELECTION_UNIVERSE *selection)
20 // Work out a selection which is the part of the passed selection which
21 // intersects the visible view.
22 // If there is a problem, clean up, and return NULL
23 {
24 UINT32
25 topLine,
26 numLines;
27 INT32
28 leftPixel;
29 UINT32
30 numPixels;
31 CHUNK_HEADER
32 *chunk;
33 UINT32
34 offset,
35 startPosition,
36 endPosition;
37 SELECTION_UNIVERSE
38 *selectionOut;
39
40 if((selectionOut=OpenSelectionUniverse())) // get selection to work in
41 {
42 GetEditorViewTextInfo(view,&topLine,&numLines,&leftPixel,&numPixels);
43
44 LineToChunkPosition(view->parentBuffer->textUniverse,topLine,&chunk,&offset,&startPosition); // get position of top line in this view
45 LineToChunkPosition(view->parentBuffer->textUniverse,topLine+numLines,&chunk,&offset,&endPosition); // get position past last line in this view
46
47 SetSelectionRange(selectionOut,startPosition,endPosition-startPosition); // select the entire visible area of the view
48 AndSelectionUniverse(selection,selectionOut); // get only the visible part of the current selection
49 }
50 return(selectionOut);
51 }
52
ViewEndSelectionChange(EDITOR_VIEW * view)53 void ViewEndSelectionChange(EDITOR_VIEW *view)
54 // The selection in this view has been changed, update the view
55 {
56 SELECTION_UNIVERSE
57 *finalSelection;
58
59 if(view->heldSelection) // make sure we did not fail to create this at the start
60 {
61 if((finalSelection=GetSelectionInView(view,view->parentBuffer->selectionUniverse))) // get selection that intersects view
62 {
63 XorSelectionUniverse(view->heldSelection,finalSelection);
64 InvalidateViewSelection(view,finalSelection);
65 CloseSelectionUniverse(finalSelection); // get rid of this
66 }
67 CloseSelectionUniverse(view->heldSelection); // get rid of memory this occupies
68 }
69 UpdateEditorWindows();
70
71 ViewEndChange(view);
72
73 if(view->viewSelectionChangedVector) // see if someone needs to be called because of the change
74 {
75 view->viewSelectionChangedVector(view); // call him
76 }
77 }
78
ViewStartSelectionChange(EDITOR_VIEW * view)79 void ViewStartSelectionChange(EDITOR_VIEW *view)
80 // The selection in this view is about to change, so prepare for it
81 // This copies the visible part of the current selection, and compares
82 // it to the updated version when the end function is called
83 {
84 view->heldSelection=GetSelectionInView(view,view->parentBuffer->selectionUniverse); // get a selection universe, use it to work out what changes are about to occur
85 ViewStartChange(view);
86 }
87
ViewEndMarkChange(MARK_VISIBILITY * visibility)88 void ViewEndMarkChange(MARK_VISIBILITY *visibility)
89 // A visible mark in this view has been changed, update the view
90 {
91 SELECTION_UNIVERSE
92 *finalSelection;
93
94 if(visibility->heldMark) // make sure we did not fail to create this at the start
95 {
96 if((finalSelection=GetSelectionInView(visibility->parentView,visibility->parentMark->selectionUniverse))) // work out where the mark is now
97 {
98 XorSelectionUniverse(visibility->heldMark,finalSelection);
99 InvalidateViewSelection(visibility->parentView,finalSelection);
100 CloseSelectionUniverse(finalSelection); // get rid of this
101 }
102 CloseSelectionUniverse(visibility->heldMark); // get rid of memory this occupies
103 }
104 UpdateEditorWindows();
105
106 ViewEndChange(visibility->parentView);
107 }
108
ViewStartMarkChange(MARK_VISIBILITY * visibility)109 void ViewStartMarkChange(MARK_VISIBILITY *visibility)
110 // A visible mark in this view is about to change, so prepare for it
111 {
112 visibility->heldMark=GetSelectionInView(visibility->parentView,visibility->parentMark->selectionUniverse); // get a selection universe, use it to work out what changes are about to occur
113 ViewStartChange(visibility->parentView);
114 }
115
ViewEndStyleAttributeChange(EDITOR_VIEW * view)116 void ViewEndStyleAttributeChange(EDITOR_VIEW *view)
117 // The attributes of styles in view have finished changing
118 {
119 ViewStyleFontsChanged(view);
120 InvalidateView(view); // this is pretty lazy
121 }
122
ViewStartStyleAttributeChange(EDITOR_VIEW * view)123 void ViewStartStyleAttributeChange(EDITOR_VIEW *view)
124 // The attributes of styles in the view are being changed
125 {
126 }
127
ViewEndStyleChange(EDITOR_VIEW * view)128 void ViewEndStyleChange(EDITOR_VIEW *view)
129 // The styles applied the text for this view have been changed, invalidate the view
130 {
131 UINT32
132 topLine,
133 numLines;
134 INT32
135 leftPixel,
136 xPosition;
137 UINT32
138 slopLeft,
139 slopRight;
140 UINT32
141 numPixels;
142 CHUNK_HEADER
143 *chunk;
144 UINT32
145 offset,
146 currentPosition;
147 UINT32
148 lineLength,
149 maxPosition;
150 UINT32
151 oldStyleStart,
152 newStyleStart;
153 UINT32
154 oldStyleElements,
155 newStyleElements;
156 UINT32
157 oldStyle,
158 newStyle;
159 bool
160 hadOldStyle,
161 hadNewStyle;
162 UINT32
163 i;
164 bool
165 done;
166
167 if(view->heldStyle) // make sure we did not fail to create this at the start
168 {
169 GetEditorViewTextInfo(view,&topLine,&numLines,&leftPixel,&numPixels);
170 done=false;
171 for(i=0;!done&&(i<numLines);i++) // add invalidations a line at a time
172 {
173 LineToChunkPosition(view->parentBuffer->textUniverse,topLine+i,&chunk,&offset,¤tPosition); // get position of top line in this view
174 ChunkPositionToNextLine(view->parentBuffer->textUniverse,chunk,offset,&chunk,&offset,&lineLength); // get length of this line
175 maxPosition=currentPosition+lineLength; // go no further than this looking for a style change in this line
176
177 while(!done&&(currentPosition<maxPosition)) // walk through the current line looking for a style change
178 {
179 hadOldStyle=GetStyleRange(view->heldStyle,currentPosition,&oldStyleStart,&oldStyleElements,&oldStyle);
180 hadNewStyle=GetStyleRange(view->parentBuffer->styleUniverse,currentPosition,&newStyleStart,&newStyleElements,&newStyle);
181
182 if(hadOldStyle||hadNewStyle) // make sure there are some changes to look at
183 {
184 if(oldStyle!=newStyle) // is there a change?
185 {
186 // currentPosition now contains the location of the style change, invalidate to the end of the line
187 xPosition=leftPixel+numPixels; // don't look past here
188 GetEditorViewTextToGraphicPosition(view,currentPosition,&xPosition,true,&slopLeft,&slopRight);
189 if(xPosition>(INT32)slopLeft)
190 {
191 xPosition-=slopLeft; // shift back to account for font overhang
192 }
193 else
194 {
195 xPosition=0;
196 }
197 if(xPosition<leftPixel)
198 {
199 xPosition=leftPixel;
200 }
201 xPosition-=leftPixel; // make relative to scrolled view
202 if(xPosition<(INT32)numPixels) // work to do?
203 {
204 InvalidateViewPortion(view,i,i+1,xPosition,numPixels); // invalidate to the end of the view
205 }
206 currentPosition=maxPosition; // done with this line
207 }
208 else
209 {
210 // move forward to the nearest change
211 if(hadOldStyle) // see if we had an old style
212 {
213 currentPosition=oldStyleStart+oldStyleElements;
214 if(hadNewStyle) // if had new style too, see if it changes sooner
215 {
216 if(currentPosition>newStyleStart+newStyleElements)
217 {
218 currentPosition=newStyleStart+newStyleElements;
219 }
220 }
221 }
222 else // no old style, so must have had new
223 {
224 currentPosition=newStyleStart+newStyleElements;
225 }
226 }
227 }
228 else
229 {
230 done=true; // no styles defined here, so no changes
231 }
232 }
233 }
234 CloseStyleUniverse(view->heldStyle); // get rid of memory this occupies
235 }
236 UpdateEditorWindows();
237 ViewEndChange(view);
238 }
239
ViewStartStyleChange(EDITOR_VIEW * view)240 void ViewStartStyleChange(EDITOR_VIEW *view)
241 // The styles applied to text in this view are about to change, so prepare for it
242 {
243 UINT32
244 topLine,
245 numLines;
246 INT32
247 leftPixel;
248 UINT32
249 numPixels;
250 CHUNK_HEADER
251 *chunk;
252 UINT32
253 offset,
254 startPosition,
255 endPosition,
256 actualStart,
257 length;
258 UINT32
259 style;
260 UINT32
261 i;
262 bool
263 done;
264
265 if((view->heldStyle=OpenStyleUniverse())) // get a style universe, and add the styles visible in this view to it
266 {
267 GetEditorViewTextInfo(view,&topLine,&numLines,&leftPixel,&numPixels);
268 LineToChunkPosition(view->parentBuffer->textUniverse,topLine,&chunk,&offset,&startPosition); // get position of top line in this view
269 LineToChunkPosition(view->parentBuffer->textUniverse,topLine+numLines,&chunk,&offset,&endPosition); // get position past last line in this view
270 done=false;
271 i=startPosition;
272 while(i<endPosition&&!done) // copy the part of the style array that intersects the view
273 {
274 if(GetStyleRange(view->parentBuffer->styleUniverse,i,&actualStart,&length,&style))
275 {
276 ForceStyleIntoRange(style);
277 if(actualStart<endPosition)
278 {
279 if(actualStart+length>endPosition)
280 {
281 length=endPosition-actualStart;
282 }
283 SetStyleRange(view->heldStyle,actualStart,length,style);
284 i=actualStart+length;
285 }
286 else
287 {
288 done=true;
289 }
290 }
291 else
292 {
293 done=true;
294 }
295 }
296 }
297 }
298
ViewEndTabSizeChange(EDITOR_VIEW * view)299 void ViewEndTabSizeChange(EDITOR_VIEW *view)
300 // The tab size on the passed view has finished changing
301 {
302 InvalidateView(view); // this is pretty lazy
303 }
304
ViewStartTabSizeChange(EDITOR_VIEW * view)305 void ViewStartTabSizeChange(EDITOR_VIEW *view)
306 // The tab size on the passed view is about to change
307 {
308 }
309
ViewEndTextChange(EDITOR_VIEW * view)310 void ViewEndTextChange(EDITOR_VIEW *view)
311 // The text in view has finished being changed bring the view back
312 // up to date
313 {
314 ViewEndChange(view);
315 if(view->viewTextChangedVector) // see if someone needs to be called because of the change
316 {
317 view->viewTextChangedVector(view); // call him with my pointer
318 }
319 }
320
ViewStartTextChange(EDITOR_VIEW * view)321 void ViewStartTextChange(EDITOR_VIEW *view)
322 // The text in view is about to be changed in some way, do whatever is needed
323 // so that when ViewEndTextChange is called, the correct parts of the view are
324 // invalidated.
325 // NOTE: when the text changes, it is possible that the selection information
326 // will also change, so that updates will be handled correctly
327 {
328 ViewStartChange(view);
329 }
330
ViewEndActiveChange(EDITOR_VIEW * view)331 void ViewEndActiveChange(EDITOR_VIEW *view)
332 // View's active status is done changing
333 {
334 ViewEndSelectionChange(view);
335 }
336
ViewStartActiveChange(EDITOR_VIEW * view)337 void ViewStartActiveChange(EDITOR_VIEW *view)
338 // View's active status is changing
339 {
340 ViewStartSelectionChange(view);
341 }
342
UnSetViewStyleFont(EDITOR_VIEW * view,UINT32 style)343 static void UnSetViewStyleFont(EDITOR_VIEW *view,UINT32 style)
344 // Free the font currently in use by style of view
345 // NOTE: it is a bad idea to call this for the default style until the window
346 // will no longer be used, since the default is used when the given style
347 // is not available
348 {
349 if(view->viewStyles[style].font)
350 {
351 FreeEditorFont(view->viewStyles[style].font);
352 view->viewStyles[style].font=NULL; // mark this font as unused
353 }
354 }
355
SetViewStyleFont(EDITOR_VIEW * view,UINT32 style,char * fontName)356 static bool SetViewStyleFont(EDITOR_VIEW *view,UINT32 style,char *fontName)
357 // Update the font used for a style in view
358 // NOTE: it is necessary to call RecalculateViewFontInfo
359 // after calling this (that is left to the caller, since he may need to make
360 // many calls to this in a row and the recalculation can be left until after
361 // the last call)
362 {
363 EDITOR_FONT
364 *newFont;
365
366 if((newFont=LoadEditorFont(fontName)))
367 {
368 UnSetViewStyleFont(view,style); // get rid of old font that was there (if any)
369 view->viewStyles[style].font=newFont;
370 return(true);
371 }
372 return(false);
373 }
374
SetViewTabSize(EDITOR_VIEW * view,UINT32 size)375 static void SetViewTabSize(EDITOR_VIEW *view,UINT32 size)
376 // set the tabSize for view
377 {
378 if(size>255)
379 {
380 size=255; // limit this
381 }
382 view->tabSize=size;
383 }
384
UnInitializeViewStyles(EDITOR_VIEW * view)385 static void UnInitializeViewStyles(EDITOR_VIEW *view)
386 // get rid of style information tied to view
387 {
388 UINT32
389 i;
390
391 for(i=0;i<VIEW_MAX_STYLES;i++)
392 {
393 UnSetViewStyleFont(view,i);
394 }
395 }
396
InitializeViewStyles(EDITOR_VIEW * view,EDITOR_VIEW_DESCRIPTOR * descriptor)397 static bool InitializeViewStyles(EDITOR_VIEW *view,EDITOR_VIEW_DESCRIPTOR *descriptor)
398 // initialize style information for view
399 {
400 UINT32
401 i;
402
403 for(i=0;i<VIEW_MAX_STYLES;i++)
404 {
405 view->viewStyles[i].font=NULL; // clear pointer
406 view->viewStyles[i].haveForegroundColor=false; // no colors defined yet
407 view->viewStyles[i].haveBackgroundColor=false;
408 }
409
410 // set up default style (which must be present)
411 view->viewStyles[0].foregroundColor=descriptor->foregroundColor;
412 view->viewStyles[0].haveForegroundColor=true;
413
414 view->viewStyles[0].backgroundColor=descriptor->backgroundColor;
415 view->viewStyles[0].haveBackgroundColor=true;
416
417 if(SetViewStyleFont(view,0,descriptor->fontName))
418 {
419 return(true);
420 }
421 return(false);
422 }
423
GetEditorViewTabSize(EDITOR_VIEW * view)424 UINT32 GetEditorViewTabSize(EDITOR_VIEW *view)
425 // get the current tab size for the given view
426 {
427 return(view->tabSize);
428 }
429
SetEditorViewTabSize(EDITOR_VIEW * view,UINT32 size)430 bool SetEditorViewTabSize(EDITOR_VIEW *view,UINT32 size)
431 // set the tab size to be used in view
432 // if there is a problem, leave the tab size unchanged, set the error
433 // and return false
434 {
435 ViewStartTabSizeChange(view);
436 SetViewTabSize(view,size);
437 ViewEndTabSizeChange(view);
438 return(true);
439 }
440
ForceStyleRange(UINT32 * style)441 static void ForceStyleRange(UINT32 *style)
442 // make sure the style is in range (for externally called routines)
443 {
444 if(*style>=VIEW_MAX_STYLES)
445 {
446 *style=VIEW_MAX_STYLES-1;
447 }
448 }
449
GetEditorViewStyleFont(EDITOR_VIEW * view,UINT32 style,char * font,UINT32 stringBytes)450 bool GetEditorViewStyleFont(EDITOR_VIEW *view,UINT32 style,char *font,UINT32 stringBytes)
451 // get the font that is in use in view for the given style
452 // if the font will not fit within string bytes, return false
453 // if there is no font in use, return an empty string
454 {
455 ForceStyleRange(&style);
456 if(stringBytes)
457 {
458 if(view->viewStyles[style].font)
459 {
460 GetEditorFontName(view->viewStyles[style].font,font,stringBytes);
461 return(true);
462 }
463 else
464 {
465 font[0]='\0';
466 return(true);
467 }
468 }
469 return(false);
470 }
471
SetEditorViewStyleFont(EDITOR_VIEW * view,UINT32 style,char * font)472 bool SetEditorViewStyleFont(EDITOR_VIEW *view,UINT32 style,char *font)
473 // set the font to be used in view
474 // this will force an update of view
475 // if there is a problem, leave the window font unchanged, set the error
476 // and return false
477 {
478 bool
479 result;
480
481 result=false;
482 ForceStyleRange(&style);
483 ViewStartStyleAttributeChange(view);
484 if(SetViewStyleFont(view,style,font)) // set new font
485 {
486 result=true;
487 }
488 ViewEndStyleAttributeChange(view);
489 return(result);
490 }
491
ClearEditorViewStyleFont(EDITOR_VIEW * view,UINT32 style)492 void ClearEditorViewStyleFont(EDITOR_VIEW *view,UINT32 style)
493 // clear the font to be used for style in view
494 // this will force an update of view
495 {
496 ForceStyleRange(&style);
497 ViewStartStyleAttributeChange(view);
498 UnSetViewStyleFont(view,style);
499 ViewEndStyleAttributeChange(view);
500 }
501
GetEditorViewStyleForegroundColor(EDITOR_VIEW * view,UINT32 style,EDITOR_COLOR * foregroundColor)502 bool GetEditorViewStyleForegroundColor(EDITOR_VIEW *view,UINT32 style,EDITOR_COLOR *foregroundColor)
503 // get the foreground color in use by style of view
504 // if the style does not have a foreground color associated with it, return false
505 {
506 ForceStyleRange(&style);
507 if(view->viewStyles[style].haveForegroundColor)
508 {
509 *foregroundColor=view->viewStyles[style].foregroundColor; // get pixel of foreground for this style
510 return(true);
511 }
512 return(false);
513 }
514
SetEditorViewStyleForegroundColor(EDITOR_VIEW * view,UINT32 style,EDITOR_COLOR foregroundColor)515 bool SetEditorViewStyleForegroundColor(EDITOR_VIEW *view,UINT32 style,EDITOR_COLOR foregroundColor)
516 // set the foreground color to be used by style of view
517 // this will force an update of view
518 // if there is a problem, leave the color unchanged, set the error
519 // and return false
520 {
521 ForceStyleRange(&style);
522 ViewStartStyleAttributeChange(view);
523 view->viewStyles[style].foregroundColor=foregroundColor;
524 view->viewStyles[style].haveForegroundColor=true;
525 ViewEndStyleAttributeChange(view);
526 return(true);
527 }
528
ClearEditorViewStyleForegroundColor(EDITOR_VIEW * view,UINT32 style)529 void ClearEditorViewStyleForegroundColor(EDITOR_VIEW *view,UINT32 style)
530 // clear the foreground color to be used for style in view
531 // this will force an update of view
532 {
533 ForceStyleRange(&style);
534 ViewStartStyleAttributeChange(view);
535 view->viewStyles[style].haveForegroundColor=false;
536 ViewEndStyleAttributeChange(view);
537 }
538
GetEditorViewStyleBackgroundColor(EDITOR_VIEW * view,UINT32 style,EDITOR_COLOR * backgroundColor)539 bool GetEditorViewStyleBackgroundColor(EDITOR_VIEW *view,UINT32 style,EDITOR_COLOR *backgroundColor)
540 // get the background color in use by style of view
541 // if the style does not have a background color associated with it, return false
542 {
543 ForceStyleRange(&style);
544 if(view->viewStyles[style].haveBackgroundColor)
545 {
546 *backgroundColor=view->viewStyles[style].backgroundColor; // get pixel of background for this style
547 return(true);
548 }
549 return(false);
550 }
551
SetEditorViewStyleBackgroundColor(EDITOR_VIEW * view,UINT32 style,EDITOR_COLOR backgroundColor)552 bool SetEditorViewStyleBackgroundColor(EDITOR_VIEW *view,UINT32 style,EDITOR_COLOR backgroundColor)
553 // set the background color to be used by style of view
554 // this will force an update of view
555 // if there is a problem, leave the color unchanged, set the error
556 // and return false
557 {
558 ForceStyleRange(&style);
559 ViewStartStyleAttributeChange(view);
560 view->viewStyles[style].backgroundColor=backgroundColor;
561 view->viewStyles[style].haveBackgroundColor=true;
562 ViewEndStyleAttributeChange(view);
563 return(true);
564 }
565
ClearEditorViewStyleBackgroundColor(EDITOR_VIEW * view,UINT32 style)566 void ClearEditorViewStyleBackgroundColor(EDITOR_VIEW *view,UINT32 style)
567 // clear the background color to be used for style in view
568 // this will force an update of view
569 {
570 ForceStyleRange(&style);
571 ViewStartStyleAttributeChange(view);
572 view->viewStyles[style].haveBackgroundColor=false;
573 ViewEndStyleAttributeChange(view);
574 }
575
GetEditorViewSelectionForegroundColor(EDITOR_VIEW * view,EDITOR_COLOR * foregroundColor)576 bool GetEditorViewSelectionForegroundColor(EDITOR_VIEW *view,EDITOR_COLOR *foregroundColor)
577 // get the foreground color in use by the selection of view
578 // NOTE: it is possible that no color has been specified.
579 // If that is the case, this will return false
580 {
581 if(view->haveSelectionForegroundColor)
582 {
583 *foregroundColor=view->selectionForegroundColor;
584 return(true);
585 }
586 return(false);
587 }
588
SetEditorViewSelectionForegroundColor(EDITOR_VIEW * view,EDITOR_COLOR foregroundColor)589 bool SetEditorViewSelectionForegroundColor(EDITOR_VIEW *view,EDITOR_COLOR foregroundColor)
590 // set the foreground color to be used for selections in view
591 // this will force an update of view
592 // if there is a problem, leave the color unchanged, set the error
593 // and return false
594 // NOTE: if haveForeground is false, this will clear the foreground color
595 // making the selection draw the foreground as the inverse of the current
596 // color
597 {
598 view->selectionForegroundColor=foregroundColor;
599 view->haveSelectionForegroundColor=true;
600 InvalidateViewSelection(view,view->parentBuffer->selectionUniverse);
601 return(true);
602 }
603
ClearEditorViewSelectionForegroundColor(EDITOR_VIEW * view)604 void ClearEditorViewSelectionForegroundColor(EDITOR_VIEW *view)
605 // Clear the foreground color, making the selection draw the foreground
606 // as the inverse of the current color
607 {
608 view->haveSelectionForegroundColor=false;
609 InvalidateViewSelection(view,view->parentBuffer->selectionUniverse);
610 }
611
GetEditorViewSelectionBackgroundColor(EDITOR_VIEW * view,EDITOR_COLOR * backgroundColor)612 bool GetEditorViewSelectionBackgroundColor(EDITOR_VIEW *view,EDITOR_COLOR *backgroundColor)
613 // get the background color in use by the selection of view
614 // NOTE: it is possible that no color has been specified.
615 // If that is the case, this will return false
616 {
617 if(view->haveSelectionBackgroundColor)
618 {
619 *backgroundColor=view->selectionBackgroundColor;
620 return(true);
621 }
622 return(false);
623 }
624
SetEditorViewSelectionBackgroundColor(EDITOR_VIEW * view,EDITOR_COLOR backgroundColor)625 bool SetEditorViewSelectionBackgroundColor(EDITOR_VIEW *view,EDITOR_COLOR backgroundColor)
626 // set the background color to be used for selections in view
627 // this will force an update of view
628 // if there is a problem, leave the color unchanged, set the error
629 // and return false
630 // NOTE: if haveBackground is false, this will clear the background color
631 // making the selection draw the background as the inverse of the current
632 // color
633 {
634 view->selectionBackgroundColor=backgroundColor;
635 view->haveSelectionBackgroundColor=true;
636 InvalidateViewSelection(view,view->parentBuffer->selectionUniverse);
637 return(true);
638 }
639
ClearEditorViewSelectionBackgroundColor(EDITOR_VIEW * view)640 void ClearEditorViewSelectionBackgroundColor(EDITOR_VIEW *view)
641 // Clear the background color, making the selection draw the background
642 // as the inverse of the current color
643 {
644 view->haveSelectionBackgroundColor=false;
645 InvalidateViewSelection(view,view->parentBuffer->selectionUniverse);
646 }
647
ViewsEndSelectionChange(EDITOR_BUFFER * buffer)648 void ViewsEndSelectionChange(EDITOR_BUFFER *buffer)
649 // The selection in buffer has finished being changed
650 // do whatever needs to be done
651 // to get it up to date
652 {
653 EDITOR_VIEW
654 *currentView;
655
656 currentView=buffer->firstView;
657 while(currentView) // walk through all views, update each one as needed
658 {
659 ViewEndSelectionChange(currentView);
660 currentView=currentView->nextBufferView; // locate next view of this buffer
661 }
662 }
663
ViewsStartSelectionChange(EDITOR_BUFFER * buffer)664 void ViewsStartSelectionChange(EDITOR_BUFFER *buffer)
665 // The selection in buffer are about to be changed in some way, do whatever is needed
666 // NOTE: a change in the selection could mean something as simple as a cursor position change
667 // NOTE also: selection changes cannot be nested, and nothing except the selection is allowed
668 // to be altered during a selection change
669 {
670 EDITOR_VIEW
671 *currentView;
672
673 currentView=buffer->firstView;
674 while(currentView) // walk through all views, update each one as needed
675 {
676 ViewStartSelectionChange(currentView);
677 currentView=currentView->nextBufferView; // locate next view of this buffer
678 }
679 }
680
ViewInvalidateMark(EDITOR_VIEW * view,EDITOR_MARK * mark)681 void ViewInvalidateMark(EDITOR_VIEW *view,EDITOR_MARK *mark)
682 // Invalidate the selection of the passed mark in the passed view
683 {
684 InvalidateViewSelection(view,mark->selectionUniverse);
685 }
686
ViewsInvalidateMark(EDITOR_MARK * mark)687 void ViewsInvalidateMark(EDITOR_MARK *mark)
688 // Invalidate the selection of the passed mark in all visible views
689 {
690 MARK_VISIBILITY
691 *currentVisibility;
692
693 currentVisibility=mark->headVisibility;
694 while(currentVisibility) // walk through all views, update each one as needed
695 {
696 ViewInvalidateMark(currentVisibility->parentView,mark);
697 currentVisibility=currentVisibility->nextView; // locate next view this mark is visible in
698 }
699 }
700
ViewsEndMarkChange(EDITOR_MARK * mark)701 void ViewsEndMarkChange(EDITOR_MARK *mark)
702 // The passed mark has finished being changed, update all
703 // affected views.
704 {
705 MARK_VISIBILITY
706 *currentVisibility;
707
708 currentVisibility=mark->headVisibility;
709 while(currentVisibility) // walk through all views, update each one as needed
710 {
711 ViewEndMarkChange(currentVisibility);
712 currentVisibility=currentVisibility->nextView; // locate next view this mark is visible in
713 }
714 }
715
ViewsStartMarkChange(EDITOR_MARK * mark)716 void ViewsStartMarkChange(EDITOR_MARK *mark)
717 // Marks (which may be visible) in buffer are about to be changed in some way, do whatever is needed
718 // NOTE: mark changes cannot be nested, and nothing except a mark is allowed
719 // to be altered during a mark change
720 {
721 MARK_VISIBILITY
722 *currentVisibility;
723
724 currentVisibility=mark->headVisibility;
725 while(currentVisibility) // walk through all views, update each one as needed
726 {
727 ViewStartMarkChange(currentVisibility);
728 currentVisibility=currentVisibility->nextView; // locate next view this mark is visible in
729 }
730 }
731
ViewsStartStyleChange(EDITOR_BUFFER * buffer)732 void ViewsStartStyleChange(EDITOR_BUFFER *buffer)
733 // The style in buffer is about to be changed in some way, do whatever is needed
734 // NOTE also: style changes cannot be nested, and nothing except the style is allowed
735 // to be altered during a style change
736 {
737 EDITOR_VIEW
738 *currentView;
739
740 currentView=buffer->firstView;
741 while(currentView) // walk through all views, update each one as needed
742 {
743 ViewStartStyleChange(currentView);
744 currentView=currentView->nextBufferView; // locate next view of this buffer
745 }
746 }
747
ViewsEndStyleChange(EDITOR_BUFFER * buffer)748 void ViewsEndStyleChange(EDITOR_BUFFER *buffer)
749 // The style in buffer has finished being changed
750 // do whatever needs to be done to get it up to date
751 {
752 EDITOR_VIEW
753 *currentView;
754
755 currentView=buffer->firstView;
756 while(currentView) // walk through all views, update each one as needed
757 {
758 ViewEndStyleChange(currentView);
759 currentView=currentView->nextBufferView; // locate next view of this buffer
760 }
761 }
762
ViewsStartTextChange(EDITOR_BUFFER * buffer)763 void ViewsStartTextChange(EDITOR_BUFFER *buffer)
764 // The text in buffer is about to be changed in some way, do whatever is needed
765 // NOTE: when the text changes, it is possible that the selection information
766 // will also change, so that updates will be handled correctly
767 {
768 EDITOR_VIEW
769 *currentView;
770
771 currentView=buffer->firstView;
772 while(currentView) // walk through all views, update each one as needed
773 {
774 ViewStartTextChange(currentView);
775 currentView=currentView->nextBufferView; // locate next view of this buffer
776 }
777 }
778
ViewsEndTextChange(EDITOR_BUFFER * buffer)779 void ViewsEndTextChange(EDITOR_BUFFER *buffer)
780 // The text in buffer has finished being changed, and the views have been
781 // updated, do whatever needs to be done
782 {
783 EDITOR_VIEW
784 *currentView;
785
786 currentView=buffer->firstView;
787 while(currentView) // walk through all views, update each one as needed
788 {
789 ViewEndTextChange(currentView);
790 currentView=currentView->nextBufferView; // locate next view of this buffer
791 }
792 }
793
EditorActivateView(EDITOR_VIEW * view)794 void EditorActivateView(EDITOR_VIEW *view)
795 // activate view (this is not nestable)
796 {
797 ViewStartActiveChange(view);
798 view->active=true;
799 ViewEndActiveChange(view);
800 }
801
EditorDeactivateView(EDITOR_VIEW * view)802 void EditorDeactivateView(EDITOR_VIEW *view)
803 // deactivate view (this is not nestable)
804 {
805 ViewStartActiveChange(view);
806 view->active=false;
807 ViewEndActiveChange(view);
808 }
809
DisposeEditorView(EDITOR_VIEW * view)810 void DisposeEditorView(EDITOR_VIEW *view)
811 // unlink view from everywhere, and dispose of it
812 {
813 DisposeViewInfo(view); // tell GUI to tear it down
814 UnInitializeViewStyles(view); // get rid of style information for view
815 UnlinkVisibleMarksFromView(view); // get rid of any visible marks hanging off the view
816 UnlinkViewFromBuffer(view);
817 MDisposePtr(view);
818 }
819
CreateEditorView(EDITOR_WINDOW * window,EDITOR_VIEW_DESCRIPTOR * descriptor)820 EDITOR_VIEW *CreateEditorView(EDITOR_WINDOW *window,EDITOR_VIEW_DESCRIPTOR *descriptor)
821 // create a view in window using descriptor
822 // if there is a problem, SetError, and return NULL
823 {
824 EDITOR_VIEW
825 *view;
826
827 if((view=(EDITOR_VIEW *)MNewPtr(sizeof(EDITOR_VIEW))))
828 {
829 LinkViewToBuffer(view,descriptor->buffer);
830 view->parentWindow=window;
831 view->active=descriptor->active;
832 view->wantHome=false;
833 SetViewTabSize(view,descriptor->tabSize); // set, and limit the tab size
834 view->haveSelectionForegroundColor=false; // select by inverting text colors by default
835 view->haveSelectionBackgroundColor=false;
836 view->headVisibility=NULL; // no visible marks hanging off of this view yet
837 view->tailVisibility=NULL;
838 view->viewTextChangedVector=descriptor->viewTextChangedVector;
839 view->viewSelectionChangedVector=descriptor->viewSelectionChangedVector;
840 view->viewPositionChangedVector=descriptor->viewPositionChangedVector;
841
842 if(InitializeViewStyles(view,descriptor))
843 {
844 if(CreateViewInfo(view,descriptor))
845 {
846 return(view);
847 }
848 }
849 UnlinkViewFromBuffer(view);
850 MDisposePtr(view);
851 }
852 return(NULL);
853 }
854