home *** CD-ROM | disk | FTP | other *** search
- #include "Globals.h"
- char InvBuf[]=
- {CSI,'7',0x6d,NULL,CSI,'0',0x6d};
- char Inv[]=
- {CSI,'7',0x6d,NULL};
- char Norm[]=
- {CSI,'0',0x6d,NULL};
-
- struct LineItem *InvItem;
-
- void MovedMouse(x,y) /*The mouse was moved! Record its new position*/
- int x,y;
- {
- LastX=PtrX;
- LastY=PtrY;
-
- PtrY=(prefs.DS) ? (y/16)+1 : (y/8)+1;
- PtrX=(x/8)+1;
- }
-
- HandleButton(Seconds,Micros) /*Handle a button press*/
- int Seconds,Micros;
- {
- int status;
- static int LastSeconds=1,LastMicros=1,DoubClicked=FALSE;
- static UBYTE ButtonX,ButtonY;
-
- /*If the user double-clicked (the mouse button), start or modify*/
- /*a highlighted block*/
- if(DoubleClick(LastSeconds,LastMicros,Seconds,Micros) &&
- PtrY==ButtonY && !DoubClicked)
- {
- PtrX=ButtonX;
- PtrY=ButtonY;
- DoubClicked=TRUE;
- HandleInvs();
- BLastX=PtrX;
- }
- else /*Otherwise, just move the cursor accordingly*/
- if(PtrY > 0 && PtrY <= SCRNHEIGHT)
- {
- ButtonX=PtrX;
- ButtonY=PtrY;
- DoubClicked=FALSE;
- if(PtrY != InvY && InvsMode > NOINV) /*End text highlighting*/
- EndLineInvs(); /*if the cursor is moved to a new line*/
-
- if(PtrY-CurY < 0) /*move the cursor to a new line*/
- status=MoveBack(-(PtrY-CurY));
- else
- status=MoveForward(PtrY-CurY);
- if(status==FALSE)
- return(FALSE);
-
- if(PtrX > MaxX(CurrentItem)) /*Move the cursor to a new*/
- CurX=MaxX(CurrentItem); /*X position*/
- else
- if(PtrX < MinX(CurrentItem))
- CurX=MinX(CurrentItem);
- else
- CurX=PtrX;
- PlotCursor(CurX,PtrY);
- }
- LastSeconds=Seconds;
- LastMicros=Micros;
- }
-
- void HandleInvs() /*Handle a modification or creation of a highlighted block*/
- {
- if(InvsMode==NOINV)
- if(PtrX >= MinX(CurrentItem) && PtrX <= MaxX(CurrentItem))
- HandleLineInvs();
- else
- HandleBlockInvs();
- else
- if(InvsMode > NOINV)
- HandleLineInvs(); /*Highlighting on one line*/
- else
- HandleBlockInvs(); /*Block highlighting*/
- }
-
- HandleBlockInvs() /*Handle the inverse of a block of lines*/
- {
- int X,Y;
-
- if(InvsMode==NOINV) /*If nothing is highlighted*/
- {
- InvY=EndIY=CurY;
- WriteConsole(Inv,-1);
- PlotCursor(1,CurY);
- PrintItem(CurrentItem);
- WriteConsole(Norm,-1);
- EndIItem=StartIItem=(struct LineItem *)CurrentItem;
- PlotCursor(MinX(CurrentItem),CurY);
- InvsMode=BLOCK_PENDING;
- return(TRUE);
- }
-
- if(InvsMode==BLOCK_PENDING) /*If one line is highlighted*/
- {
- if(StartIItem == CurrentItem) /*Same line? End highlighting*/
- {
- EndBlockInvs();
- return(TRUE);
- }
- else /*Else, highlight a block (up or down, depending)*/
- if(IsAfter(CurrentItem,StartIItem)) /*down*/
- {
- EndIItem=(struct LineItem *)CurrentItem;
- if((Y=IsOnScreen(StartIItem->NextItem)))
- {
- PlotCursor(1,Y);
- RvsBlock(StartIItem->NextItem,EndIItem);
- }
- else
- {
- PlotCursor(1,1);
- RvsBlock(FirstScrnItem,EndIItem);
- }
- EndIY=CurY=PtrY;
- InvsMode=BLOCK_DOWN;
- PlotCursor(MinX(EndIItem),CurY);
- }
- else /*up*/
- if(IsBefore(CurrentItem,StartIItem))
- {
- EndIItem=(struct LineItem *)CurrentItem;
- EndIY=CurY;
- if( (Y=IsOnScreen(StartIItem->PrevItem)) )
- RvsBlock(EndIItem,StartIItem->PrevItem);
- else
- RvsBlock(EndIItem,ScrnBtm);
- PlotCursor(MinX(EndIItem),EndIY);
- InvsMode=BLOCK_UP;
- }
- return(TRUE);
- }
-
- if(InvsMode == BLOCK_DOWN) /*If highlighting is down*/
- {
- if((IsAfter(CurrentItem,EndIItem)) && CurrentItem != EndIItem)
- { /*Highlight more*/
- if( (Y=IsOnScreen(EndIItem->NextItem)))
- {
- PlotCursor(1,Y);
- RvsBlock(EndIItem->NextItem,CurrentItem);
- }
- else
- {
- PlotCursor(1,1);
- RvsBlock(FirstScrnItem,CurrentItem);
- }
- EndIY=CurY=PtrY;
- EndIItem=(struct LineItem *)CurrentItem;
- PlotCursor(MinX(EndIItem),IsOnScreen(CurrentItem));
- }
- if((IsBefore(CurrentItem,EndIItem)) && CurrentItem != EndIItem)
- { /*Unhighlight some*/
- if(IsBefore(CurrentItem,StartIItem))
- {
- EndBlockInvs(FALSE);
- return(TRUE);
- }
- EndIY=Y=CurY;
- X=CurX;
- PlotCursor(CurX,CurY+1);
- NormBlock(CurrentItem->NextItem,EndIItem);
- PlotCursor(X,Y);
- EndIItem=(struct LineItem *)CurrentItem;
- }
- }
- else /*The higlighting goes up*/
- {
- if((IsBefore(CurrentItem,EndIItem)) && CurrentItem != EndIItem)
- { /*Highlight*/
- EndIY=Y=CurY;
- if( (Y=IsOnScreen(EndIItem->PrevItem)) )
- RvsBlock(CurrentItem,EndIItem->PrevItem);
- else
- RvsBlock(CurrentItem,ScrnBtm);
-
- PlotCursor(MinX(CurrentItem),IsOnScreen(CurrentItem));
- EndIItem=(struct LineItem *)CurrentItem;
- }
- /*Normalize*/
- if((IsAfter(CurrentItem,EndIItem)) && CurrentItem != EndIItem)
- {
- if((CurrentItem==StartIItem)||(IsAfter(CurrentItem,StartIItem)))
- {
- EndBlockInvs();
- return(TRUE);
- }
- Y=CurY;
- PlotCursor(CurX,EndIY);
- NormBlock(EndIItem,CurrentItem->PrevItem);
- EndIItem=(struct LineItem *)CurrentItem;
- PlotCursor(MinX(CurrentItem),IsOnScreen(CurrentItem));
- EndIY=CurY;
- }
- }
- }
-
- void NormIt(Start,End,Start_y) /*Un-highlight an area on screen*/
- struct LineItem *Start,*End;
- int Start_y;
- {
- struct LineItem *CurItem;
-
- CurItem=(struct LineItem *)Start;
- WriteConsole(Norm,-1);
-
- PlotCursor(1,Start_y);
- CurY--;
- while(CurItem != End->NextItem) /*Go down the screen*/
- {
- PlotCursor(1,CurY+1);
- PrintItem(CurItem);
- CurItem=(struct LineItem *)CurItem->NextItem;
- }
- }
-
- void NormBlock(Start,End) /*Unhighlight a block of text, keeping it to*/
- struct LineItem *Start,*End; /*what is on screen currently*/
- {
- int beg_y,end_y,old_y,old_x;
-
- old_y=CurY;
- old_x=CurX;
-
- if((beg_y=IsOnScreen(Start))) /*If 'Start' is on the screen*/
- if((end_y=IsOnScreen(End))) /*If 'End' is on screen*/
- NormIt(Start,End,beg_y); /*Normalize a block in the normal way*/
- else
- NormIt(Start,ScrnBtm,beg_y);/*Normalize from 'Start' to end of screen*/
- else
- if(IsBefore(Start,FirstScrnItem)) /*If 'Start' is above the screen*/
- if(IsAfter(End,ScrnBtm)) /*and 'End' is below it*/
- NormIt(FirstScrnItem,ScrnBtm,1); /*Unhighlight the whole screen*/
- else
- if((IsOnScreen(End))) /*If the end is on the screen*/
- NormIt(FirstScrnItem,End,1); /*Unhighlight from top to End*/
- /*That's it (any other possibilities cause nothing to happen)*/
-
- PlotCursor(old_x,old_y);
- }
-
-
- void RvsBlock(Start,End) /*Highlight a block*/
- struct LineItem *Start,*End;
- {
- struct LineItem *CurItem;
- int y;
-
- CurItem=(struct LineItem *)Start; /*Start at the start*/
- WriteConsole(Inv,-1); /*Activate inversed text*/
-
- CurY--;
- while(CurItem != End->NextItem) /*Go through list*/
- {
- if(y=IsOnScreen(CurItem)) /*Only do lines on screen*/
- {
- PlotCursor(1,y);
- PrintItem(CurItem);
- }
- CurItem=(struct LineItem *)CurItem->NextItem;
- }
- WriteConsole(Norm,-1);
- }
-
- void EndBlockInvs() /*End the highlight of a block of lines*/
- {
- struct WhichOne which;
-
- FindStartEnd(StartIItem,EndIItem,&which);
- NormBlock(which.Start,which.End);
- PlotCursor(MinX(CurrentItem),CurY);
- InvsMode=NOINV;
- }
-
- HandleLineInvs() /*Handle the inverse of individual characters*/
- {
- int NewEnd;
-
- if(PtrX < MinX(CurrentItem))
- PtrX=MinX(CurrentItem);
- else
- if(PtrX > MaxX(CurrentItem))
- PtrX=MaxX(CurrentItem);
-
- if(InvsMode==NOINV) /*If nothing is highlighted, start highlighting*/
- {
- InvBuf[3]=CurrentItem->Text[PosInText(CurrentItem->Level)];
- WriteConsole(InvBuf,7);
- StartChar=EndChar=PosInText(CurrentItem->Level);
- PlotCursor(CurX,CurY);
- InvsMode=LINE_PENDING;
- InvY=CurY;
- InvItem=(struct LineItem *)CurrentItem;
- return(TRUE);
- }
-
- if(InvsMode==LINE_PENDING) /*If one character only*/
- {
- if(PtrX == BLastX) /*Same character? Cancel highlighting*/
- {
- EndLineInvs();
- return(TRUE);
- }
-
- if(PtrX > BLastX) /*After the character*/
- {
- EndChar=PosInText(InvItem->Level);
- PlotCursor(BLastX,CurY);
- RvsText(StartChar,EndChar);
- CurX=CurX+EndChar-StartChar;
- InvsMode=LINE_FWD;
- PlotCursor(CurX,CurY);
- return(TRUE);
- }
-
- if(PtrX < BLastX) /*Before the character*/
- {
- EndChar=PosInText(InvItem->Level);
- RvsText(EndChar,StartChar-1);
- PlotCursor(PtrX,CurY);
- InvsMode=LINE_BACK;
- }
- return(TRUE);
- }
- else
- if(InvsMode==LINE_FWD) /*Left to right highlighting*/
- {
- if(PtrX > BLastX) /*Forward (highlight more)*/
- {
- NewEnd=PtrX-MinX(InvItem);
- PlotCursor(EndChar+MinX(InvItem),CurY);
- RvsText(EndChar,NewEnd);
- CurX=NewEnd+MinX(InvItem);
- PlotCursor(CurX,CurY);
- EndChar=NewEnd;
- }
-
- if(PtrX < BLastX) /*Backward (un-highlight)*/
- if(PtrX-MinX(InvItem)<=StartChar)
- EndLineInvs();
- else
- {
- NewEnd=PtrX-MinX(InvItem);
- NormText(NewEnd+1,EndChar);
- PlotCursor(CurX,CurY);
- EndChar=NewEnd;
- }
- }
- else /*Right to left highlighting*/
- {
- if(PtrX < BLastX) /*Backward (highlight more)*/
- {
- NewEnd=PtrX-MinX(InvItem);
- RvsText(NewEnd+1,EndChar);
- PlotCursor(CurX,CurY);
- EndChar=NewEnd;
- }
-
- if(PtrX > BLastX) /*Forward (un-highlight some)*/
- if(PtrX-MinX(InvItem)>=StartChar)
- EndLineInvs();
- else
- {
- NewEnd=PtrX-MinX(InvItem)-1;
- PlotCursor(EndChar+MinX(InvItem),CurY);
- NormText(EndChar,NewEnd);
- CurX=NewEnd+MinX(InvItem);
- EndChar=NewEnd;
- PlotCursor(CurX+1,CurY);
- }
- }
- }
-
- void RvsText(Start,End) /*Highlight a block of text*/
- int Start,End;
- {
- char Buffer[80];
- int c,l;
-
- strcpy(Buffer,Inv);
- l=strlen(Buffer);
-
- for(c=l; c-l < End-Start+1 ; c++)
- {
- Buffer[c]=InvItem->Text[c+Start-l];
- }
- Buffer[c]=0;
-
- strcat(Buffer,Norm);
-
- WriteConsole(Inv,-1);
- WriteConsole(Buffer,c);
- WriteConsole(Norm,-1);
- }
-
-
- MoveBack(Number) /*Move back in the item list a specified number of times*/
- int Number;
- {
- int c;
-
- for(c=0;c<Number;c++)
- {
- if(CurrentItem->PrevItem==NULL)
- return(FALSE);
- else
- CurrentItem=(struct LineItem *)CurrentItem->PrevItem;
- }
- return(TRUE);
- }
-
- MoveForward(Number) /*Move forward in the item list a specifiecd*/
- int Number; /*number of times*/
- {
- int c;
- struct LineItem *OrigItem;
-
- OrigItem=(struct LineItem *)CurrentItem;
- for(c=0;c<Number;c++)
- {
- if(CurrentItem->NextItem==NULL)
- {
- CurrentItem=(struct LineItem *)OrigItem;
- return(FALSE);
- }
- else
- CurrentItem=(struct LineItem *)CurrentItem->NextItem;
- }
- return(TRUE);
- }
-
- void EndLineInvs() /*End text inverse*/
- {
- if(StartChar < EndChar)
- NormText(StartChar,EndChar);
- else
- NormText(EndChar,StartChar);
- InvsMode=NOINV;
- }
-
- void NormText(Start,End) /*Un-reverse text*/
- int Start,End;
- {
- int TempX,c;
- char Buffer[80];
-
- for(c=Start;c<=End;c++)
- Buffer[c-Start]=InvItem->Text[c];
-
- Buffer[c-Start]=0;
-
- TempX=CurX;
- PlotCursor(MinX(InvItem)+Start,InvY);
- WriteConsole(Buffer,-1);
- PlotCursor(TempX,InvY);
- }
-
- HandleDelBlock() /*Delete a block of lines*/
- {
- struct WhichOne which;
- struct LineItem *temp;
- BOOL stat;
-
- /*If you're deleting everything, just call New*/
- if((StartIItem->PrevItem==NULL && EndIItem->NextItem==NULL) ||
- (StartIItem->NextItem==NULL && EndIItem->PrevItem==NULL))
- {
- NewAll();
- return(TRUE);
- }
-
- /*Otherwise, find the true start and end and delete the block*/
- FindStartEnd(StartIItem,EndIItem,&which);
-
- if(which.Start->NextItem != NULL && which.Start->NextItem->cont &&
- !which.Start->cont && which.Start==which.End) /*TRUE==parent*/
- return(FALSE);
-
- InvsMode=NOINV;
-
- /*Find the end (last child)*/
- if(which.End->NextItem->cont && (which.Start!=which.End))
- {
- temp=(struct LineItem *)which.End->PrevItem;
- stat=FALSE;
-
- while(temp!=which.Start)
- {
- if(!temp->cont)
- stat=TRUE;
- temp=(struct LineItem *)temp->PrevItem;
- }
- if(stat)
- which.End=(struct LineItem *)FindNextNonCont(which.End);
- }
-
- DelBlock(which.Start,which.End,IsOnScreen(which.Start),
- IsOnScreen(which.End));
- return(TRUE);
- }
-
- /*When dealing with highlighted blocks, it is not guaranteed that*/
- /*StartIItem comes before EndIItem in the linked list. This function*/
- /*sorts out which is which and puts each pointer in an appropriate*/
- /*space in a WhichOne structure (created especially for this function)*/
- /*A kludge, I know. But 'Liner's grown up around this technique. It*/
- /*would take more work than it is worth to change it*/
-
- void FindStartEnd(Start,End,which)
- struct LineItem *Start,*End;
- struct WhichOne *which;
- {
- if(IsBefore(Start,End))
- {
- which->Start=(struct LineItem *)Start;
- which->End=(struct LineItem *)End;
- }
- else
- {
- which->Start=(struct LineItem *)End;
- which->End=(struct LineItem *)Start;
- }
- }
-
- void DelBlock(Start,End,StartY,EndY) /*Delete a block of lines*/
- struct LineItem *Start,*End;
- int StartY,EndY;
- {
- int TOS;
-
- if(!Start->cont)
- {
- Start=(struct LineItem *)FindPrevNonCont(Start);
- End=(struct LineItem *)FindNextNonCont(End);
- }
-
- StartY=IsOnScreen(Start);
- EndY=IsOnScreen(End);
-
- if(!StartY) /*If the start of the inversed block isn't on*/
- { /*the screen, put it on the screen and then delete*/
- FirstScrnItem=CurrentItem=(struct LineItem *)Start;
- PrintItemList(Start,(StartY=1));
- }
-
- if(!EndY) /*Handle when the end isn't on screen*/
- EndY=SCRNHEIGHT;
-
- if(Start==FirstScrnItem)
- TOS=TRUE;
- else
- TOS=FALSE;
-
- if(Start->PrevItem == NULL) /*If there is nothing before 'Start'*/
- { /*Make 'End' the start of everything*/
- CurrentItem=FirstItem=FirstScrnItem=
- (struct LineItem *)End->NextItem;
- CurrentItem->PrevItem=NULL;
- RemItem(CurrentItem);
- AddItem(CurrentItem);
- TOS=FALSE;
- }
- else
- if(End->NextItem==NULL) /*If 'End' is the end of everything, make*/
- { /*'Start'->PrevItem the start of everything*/
- CurrentItem=LastItem=
- (struct LineItem *)Start->PrevItem;
- LastItem->NextItem=NULL;
- if(Start==FirstScrnItem)
- {
- FirstScrnItem=ScrnBtm=(struct LineItem *)CurrentItem;
- StartY=1;
- }
- else
- StartY--;
- TOS=FALSE;
- }
- else
- {
- CurrentItem=Start->PrevItem->NextItem=(struct LineItem *)
- End->NextItem;
- End->NextItem->PrevItem=
- (struct LineItem *)Start->PrevItem;
- }
-
- if(TOS) /*If the Start was at the top of the screen...*/
- CurrentItem=FirstScrnItem=(struct LineItem *)End->NextItem;
-
- /*Free the deleted block's memory*/
- FreeListMem(Start,End);
- /*Update some ItemNumbers*/
- RemItem(CurrentItem);
- AddItem(CurrentItem);
-
- BackSearchRefresh(CurrentItem);
- PrintItemList(CurrentItem,StartY);
- PlotCursor(MinX(CurrentItem),StartY);
- }
-
- void FreeListMem(Start,End) /*Free several Items at once*/
- struct LineItem *Start,*End;
- {
- struct LineItem *Item,*Next;
- Next=(struct LineItem *)Start;
- do
- {
- Item=(struct LineItem *)Next;
- Next=(struct LineItem *)Item->NextItem;
- RemItem(Item);
-
- if(Item->PrevItem !=NULL)
- Item->PrevItem->NextItem=(struct LineItem *)Item->NextItem;
- if(Item->NextItem != NULL)
- Item->NextItem->PrevItem=(struct LineItem *)Item->PrevItem;
-
- FreeMem(Item,sizeof(struct LineItem));
- }
- while(Item != End && Next != NULL);
- }
-
- void DelTextBlock() /*Delete the highlighted text*/
- {
- int c,Start,End,len;
- char Buffer[2];
-
- if(StartChar < EndChar) /*Find the start of the highlighted block*/
- {
- Start=StartChar;
- End=EndChar;
- }
- else
- {
- Start=EndChar;
- End=StartChar;
- }
- len=strlen(InvItem->Text);
-
- for(c=0;c <= len-End; c++)
- InvItem->Text[c+Start]=InvItem->Text[c+End+1];
-
- PlotCursor(1,InvY);
- Buffer[0]=CSI;
- Buffer[1]=0x4b;
- WriteConsole(Buffer,2);
- PrintItem(InvItem);
- PlotCursor(MinX(InvItem)+Start,InvY);
- InvsMode=NOINV;
- }
-
- CancelLineInvs() /*Cancel an inversed text section*/
- {
- if(NOINV == InvsMode)
- return(FALSE);
- else
- if(InvsMode > NOINV)
- EndLineInvs();
- }
-
- CancelInvs() /*Cancel inversed text or lines*/
- {
- if(NOINV == InvsMode)
- return(FALSE);
- else
- if(InvsMode > NOINV)
- EndLineInvs();
- else
- EndBlockInvs();
-
- return(TRUE);
- }
-
- DelInvs() /*Delete the highlighted block or text*/
- {
- if(InvsMode==NULL)
- return(FALSE);
-
- if(InvsMode > NOINV)
- DelTextBlock();
- else
- HandleDelBlock();
-
- return(TRUE);
- }
-
- void TitleError(string) /*Display 'string' in the title bar*/
- char *string;
- {
- DisplayBeep(Screen);
- ErrorInTitle = TRUE;
- SetWindowTitles(Window,-1,string);
- }
-
- void TitleErrorCancel() /*Set the title bar text to normal (with the */
- { /*current filename in the title bar*/
- static char Title[85];
-
- strcpy(Title,ScreenTitle);
- if(FileName[0])
- strncat(Title,FileName,65);
- else
- strcat(Title,"Untitled");
- if(Modified==TRUE) /*If the outline has been modified*/
- Title[0]='*'; /*Put a '*' before "'Liner"*/
- ErrorInTitle = FALSE;
- SetWindowTitles(Window,-1,Title);
- }
-
- void BackSearchRefresh(Base) /*Do a refresh of ItemNumbers by searching*/
- struct LineItem *Base; /*back through the item list*/
- {
- struct LineItem *Work,Dummy;
-
- Dummy.PrevItem=(struct LineItem *)Base->PrevItem;
- Dummy.NextItem=(struct LineItem *)Base->NextItem;
-
- for(Dummy.Level=Base->Level;Dummy.Level > 0;Dummy.Level--)
- if((Work=(struct LineItem *)FindPrev(&Dummy))!=NULL)
- {
- RemItem(Work);
- AddItem(Work);
- }
- }
-
- /*End of mouse.c*/
-