home *** CD-ROM | disk | FTP | other *** search
- /*********************************************
- ************** carat.c ******************
- *********************************************/
-
- #define INTUI_V36_NAMES_ONLY
-
- #include <exec/exec.h>
- #include <intuition/intuition.h>
- #include <graphics/gfxmacros.h>
- #include <graphics/rastport.h>
-
- #include <clib/exec_protos.h>
- #include <clib/intuition_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/console_protos.h>
- #include <clib/gadtools_protos.h>
-
- #include <stdio.h>
- #include <string.h>
-
- #include "stickit2.h"
-
- #include "consts.h"
- #include "structs.h"
- #include "proto.h"
-
- extern prj_p prj;
-
- int carat_line_from_carat(note_p,char *);
-
- /*
- Function : void carat_from_coords(note_p curr_note,WORD x_ord,WORD y_ord)
- Purpose : Called by the notes event handler. Given a note and the co-ordinates
- of where the user has clicked this function will position the
- curr_note->carat.text pointer to point to the correct character in the
- text string. To draw the carat at the correct position, use
- carat_draw().
- */
-
- void carat_from_coords(note_p curr_note,WORD x_ord,WORD y_ord)
- {
- struct Window *curr_win;
- struct RastPort *curr_rport;
- struct TextExtent textextent_result;
-
- char *text_ptr;
-
- ULONG remaininglength;
- LONG textbaseline,topoffset;
- LONG textfit = 0;
- LONG curr_x,curr_mid_x,prev_x,prev_mid_x;
-
- int l;
-
- BOOL validclick = TRUE;
-
- /* Set up some easy references */
-
- curr_win = curr_note->win;
- curr_rport = curr_win->RPort;
-
- textbaseline = curr_rport->TxBaseline + NO_INTERLINE_PIXELS;
- topoffset = curr_win->WScreen->BarHeight + 1;
-
- /* See if user clicked in valid region */
-
- if ((x_ord < curr_win->BorderLeft) ||
- (x_ord > (curr_win->Width - curr_win->BorderRight)))
- return;
-
- if ((y_ord < curr_win->BorderTop) ||
- (y_ord > (curr_win->Height - curr_win->BorderBottom)))
- return;
-
- /* Set up the text pointer */
-
- text_ptr = curr_note->text;
-
- /* Move to position */
-
- Move(curr_rport,(LONG)curr_win->BorderLeft,topoffset + textbaseline);
-
- while(strlen(text_ptr)) {
-
- /* Have we reached the bottom ? */
-
- if ((curr_rport->cp_y + (curr_rport->TxHeight - textbaseline))>
- (curr_win->Height - (curr_win->BorderBottom + 2))) {
- validclick = FALSE;
- break;
- }
-
- /* Remove any space */
-
- for (l = 0; (text_ptr[l] == ' ') &&(l < strlen(text_ptr)); l++);
-
- text_ptr += l;
-
- /* How much text will fit on ? */
-
- textfit = TextFit(curr_rport,text_ptr,
- strlen(text_ptr),&textextent_result,NULL,1,(LONG)curr_win->Width -
- (curr_rport->cp_x + curr_win->BorderLeft + curr_win->BorderRight + CARAT_WIDTH),
- curr_rport->TxHeight + 1);
-
- /* If no text will be printed, try next line */
-
- if (textfit == 0) {
- Move(curr_rport,curr_win->BorderLeft,
- curr_rport->cp_y + curr_rport->TxHeight + NO_INTERLINE_PIXELS);
- continue;
- }
-
- /* Will I print all the remainining text ? */
-
- remaininglength = strlen(text_ptr);
-
- if (textfit != remaininglength) {
- for (l = textfit;((l > 0) &&(text_ptr[l] != ' ')); l--);
-
- /* If we can successfully wrap it */
-
- if (l != 0)
- textfit = l + 1;
- }
-
- /* textfit now holds the number of characters to be printed */
- /* See if on this line. */
-
- if (y_ord <= (curr_rport->cp_y + (curr_rport->TxHeight -
- textbaseline)))
- break;
-
- /* Next line */
-
- Move(curr_rport,curr_win->BorderLeft,
- curr_rport->cp_y + curr_rport->TxHeight + NO_INTERLINE_PIXELS);
-
- /* If we've finished */
-
- if (textfit == remaininglength) {
- validclick = FALSE;
- break;
- }
-
- /* Else, set up next line pointer */
-
- text_ptr += textfit;
- }
-
- if (!validclick)
- return;
-
- /* text_ptr now points to the start of the line the user clicked on */
-
- prev_x = (LONG)curr_win->BorderLeft;
- prev_mid_x = (LONG)curr_win->BorderLeft - 1;
-
- for (l = 1; l <= textfit; l++) {
- curr_x = TextLength(curr_rport,text_ptr,l) +
- (LONG)curr_win->BorderLeft;
-
- curr_mid_x = prev_x + (curr_x - prev_x) / 2;
-
- if ((x_ord > prev_mid_x) && (x_ord <= curr_mid_x)) {
- curr_note->carat.text = text_ptr + l - 1;
-
- /* Store old carat positions */
-
- curr_note->carat.oldxpos = curr_note->carat.xpos;
- curr_note->carat.oldypos = curr_note->carat.ypos;
-
- curr_note->carat.xpos = prev_x;
- curr_note->carat.ypos = curr_rport->cp_y - textbaseline + 2;
-
- carat_draw(curr_note);
-
- return;
- }
-
- prev_x = curr_x;
- prev_mid_x = curr_mid_x;
- }
-
- /* It must lie at the end of the line */
-
- curr_note->carat.text = text_ptr + textfit;
-
- /* Store old carat positions */
-
- curr_note->carat.oldxpos = curr_note->carat.xpos;
- curr_note->carat.oldypos = curr_note->carat.ypos;
-
- curr_note->carat.xpos = prev_x;
- curr_note->carat.ypos = curr_rport->cp_y - textbaseline + 2;
-
- carat_draw(curr_note);
- }
-
- /*
- Function : void carat_draw(note_p curr_note)
- Purpose : Will draw the carat in the current note window. It takes the values
- from curr_note->carat.xpos etc... If the values of oldxpos etc...
- are valid, the old carat is removed by XORing.
- */
-
- void carat_draw(note_p curr_note)
- {
- struct Window *curr_win;
- struct RastPort *curr_rport;
-
- LONG textbaseline;
-
- /* Shortcuts */
-
- curr_win = curr_note->win;
- curr_rport = curr_win->RPort;
-
- textbaseline = curr_rport->TxBaseline + NO_INTERLINE_PIXELS;
-
- /* Set draw modes */
-
- SetDrMd(curr_rport,COMPLEMENT);
- SetAPen(curr_rport,curr_note->caratcolour);
- SetBPen(curr_rport,curr_note->caratcolour);
-
- /* Undraw the old one, if it exists */
-
- if (curr_note->carat.oldxpos)
- RectFill(curr_rport,curr_note->carat.oldxpos,
- curr_note->carat.oldypos,curr_note->carat.oldxpos + CARAT_WIDTH,
- curr_note->carat.oldypos + curr_rport->TxHeight - 1);
-
- /* Draw new one */
-
- if (curr_note->carat.xpos)
- RectFill(curr_rport,curr_note->carat.xpos,
- curr_note->carat.ypos,curr_note->carat.xpos + CARAT_WIDTH,
- curr_note->carat.ypos + curr_rport->TxHeight - 1);
- }
-
- /*
- Function : void carat_clear(note_p curr_note)
- Purpose : Clears all the info for the carat. This "undraws" the carat from
- the window.
- */
-
- void carat_clear(note_p curr_note)
- {
- struct Window *curr_win;
- struct RastPort *curr_rport;
-
- LONG textbaseline;
-
- /* Shortcuts */
-
- curr_win = curr_note->win;
- curr_rport = curr_win->RPort;
-
- textbaseline = curr_rport->TxBaseline + NO_INTERLINE_PIXELS;
-
- /* Set draw modes */
-
- SetDrMd(curr_rport,COMPLEMENT);
- SetAPen(curr_rport,curr_note->caratcolour);
- SetBPen(curr_rport,curr_note->caratcolour);
-
- /* Undraw the current one, if it exists */
-
- if (curr_note->carat.xpos)
- RectFill(curr_rport,curr_note->carat.xpos,
- curr_note->carat.ypos,curr_note->carat.xpos + CARAT_WIDTH,
- curr_note->carat.ypos + curr_rport->TxHeight - 1);
-
- curr_note->carat.xpos = curr_note->carat.ypos = 0;
- curr_note->carat.oldxpos = curr_note->carat.oldypos = 0;
- curr_note->carat.text = NULL;
- }
-
- /*
- Function : void carat_from_ptr(note_p curr_note,int ptrchange)
- Purpose : Given the curr_note->carat.text pointer, will place the carat in the
- correct position in the window. Set ptrchange to PTRCHANGE_CLICK if
- the carat position is being changed due to a mouse click,
- PTRCHANGE_CURSOR if it because the user has used the cursor keys.
- */
-
- void carat_from_ptr(note_p curr_note,int ptrchange)
- {
- struct Window *curr_win;
- struct RastPort *curr_rport;
- struct TextExtent textextent_result;
-
- char *text_ptr;
-
- ULONG remaininglength;
- LONG topoffset,textbaseline;
- LONG textfit;
-
- int l;
-
- BOOL foundline = TRUE;
-
- /* Shortcuts */
-
- curr_win = curr_note->win;
- curr_rport = curr_win->RPort;
-
- textbaseline = curr_rport->TxBaseline + NO_INTERLINE_PIXELS;
- topoffset = curr_win->WScreen->BarHeight + 1;
-
- /* Set up the text pointer */
-
- text_ptr = curr_note->text;
-
- /* If we are cursoring to the end */
-
- if (*curr_note->carat.text == '\0')
- ptrchange = 1;
-
- /* Move to position */
-
- Move(curr_rport,(LONG)curr_win->BorderLeft,
- topoffset + textbaseline);
-
- while(strlen(text_ptr)) {
-
- /* Have we reached the bottom ? */
-
- if ((curr_rport->cp_y + (curr_rport->TxHeight - textbaseline))>
- (curr_win->Height - (curr_win->BorderBottom + 2))) {
- foundline = FALSE;
- break;
- }
-
- /* Remove any space */
-
- for (l = 0; (text_ptr[l] == ' ') &&(l < strlen(text_ptr)); l++);
-
- text_ptr += l;
-
- /* How much text will fit on ? */
-
- textfit = TextFit(curr_rport,text_ptr,
- strlen(text_ptr),&textextent_result,NULL,1,(LONG)curr_win->Width -
- (curr_rport->cp_x + curr_win->BorderLeft + curr_win->BorderRight + CARAT_WIDTH),
- curr_rport->TxHeight + 1);
-
- /* If no text will be printed, try next line */
-
- if (textfit == 0) {
- Move(curr_rport,curr_win->BorderLeft,
- curr_rport->cp_y + curr_rport->TxHeight + NO_INTERLINE_PIXELS);
- continue;
- }
-
- /* Will I print all the remainining text ? */
-
- remaininglength = strlen(text_ptr);
-
- if (textfit != remaininglength) {
- for (l = textfit;((l > 0) &&(text_ptr[l] != ' ')); l--);
-
- /* If we can successfully wrap it */
-
- if (l != 0)
- textfit = l + 1;
- }
-
- /* textfit now holds the number of characters to be printed */
- /* See if on this line. */
-
- if ((curr_note->carat.text >= text_ptr) &&
- ((curr_note->carat.text < text_ptr + textfit + ptrchange)))
- break;
-
- /* Next line */
-
- Move(curr_rport,curr_win->BorderLeft,
- curr_rport->cp_y + curr_rport->TxHeight + NO_INTERLINE_PIXELS);
-
- /* If we've finished */
-
- if (textfit == remaininglength) {
- foundline = FALSE;
- break;
- }
-
- /* Else, set up next line pointer */
-
- text_ptr += textfit;
- }
-
- if (!foundline)
- return;
-
- /* text_ptr points to the start of the line of text */
-
- /* Pretend we've clicked in the window at the calculated position */
-
- carat_from_coords(curr_note,(WORD)(TextLength(curr_rport,text_ptr,
- curr_note->carat.text - text_ptr) + curr_win->BorderLeft),
- curr_rport->cp_y);
- }
-
- /*
- Function : void carat_vanillakey(note_p curr_note,struct IntuiMessage *curr_msg)
- Purpose : This is the routine that is called when the user types some text
- into the note. It contains any character that can be described as a
- vanilla key.
- */
-
- void carat_vanillakey(note_p curr_note,struct IntuiMessage *curr_msg)
- {
- carat_addachar(curr_note,(char)curr_msg->Code,TRUE);
-
- prj->projectchanged = TRUE;
- }
-
- /*
- Function : void carat_rawkey(note_p curr_note,struct IntuiMessage *curr_msg)
- Purpose : This is the routine that is called when the user types some text
- into the note. It contains any character that can't be described as a
- vanilla key (ie cursor keys).
- */
-
- void carat_rawkey(note_p curr_note,struct IntuiMessage *curr_msg)
- {
- struct InputEvent *ievent;
- struct Window *curr_win;
- struct RastPort *curr_rport;
-
- UBYTE buffer[SIZE_RAWKEYBUFFER];
- LONG textbaseline;
- LONG actual;
-
- /* Set up some easy reference */
-
- curr_win = curr_note->win;
- curr_rport = curr_win->RPort;
-
- textbaseline = curr_rport->TxBaseline + NO_INTERLINE_PIXELS;
-
- /* Alloc some temporary buffer memory */
-
- ievent = AllocMem(sizeof (struct InputEvent),MEMF_CLEAR);
-
- if (!ievent) /* Can't allocate structure */
- return;
-
- ievent->ie_Class = IECLASS_RAWKEY;
- ievent->ie_Code = curr_msg->Code;
- ievent->ie_Qualifier = curr_msg->Qualifier;
- ievent->ie_position.ie_addr = *((APTR *)curr_msg->IAddress);
-
- if (!(curr_msg->Code & 0x80)) {
- /* Key down */
-
- actual = RawKeyConvert(ievent,buffer,SIZE_RAWKEYBUFFER-1,NULL);
-
- if ((actual == 2) && (buffer[0] = 155)){
- switch(buffer[1]) {
- case 'D': /* Left */
- if (curr_note->carat.text >
- curr_note->text) {
- curr_note->carat.text--;
-
- carat_from_ptr(curr_note,
- PTRCHANGE_CURSOR);
- }
- break;
- case 'C': /* Right */
- if (*curr_note->carat.text != '\0') {
- curr_note->carat.text++;
-
- carat_from_ptr(curr_note,
- PTRCHANGE_CURSOR);
- }
- break;
- case 'A': /* Up */
- carat_from_coords(curr_note,
- (WORD)curr_note->carat.xpos,(WORD)(curr_note->carat.ypos - NO_INTERLINE_PIXELS
- - 2));
-
- break;
- case 'B': /* Down */
- carat_from_coords(curr_note,
- (WORD)curr_note->carat.xpos,(WORD)(curr_note->carat.ypos +
- curr_rport->TxHeight + 1));
-
- break;
- default: /* Who knows? */
- break;
- }
- }
- }
-
- FreeMem(ievent,sizeof(struct InputEvent));
- }
-
- /*
- Function : void carat_addachar(note_p curr_note,char c,BOOL redraw)
- Pupose : When given a characer, will add the character to the note and refresh
- it. If redraw is TRUE, the note is refresh (ie the user is typing into
- the note) else the note is note refreshed (ie the user has pasted data
- into the note.
- */
-
- void carat_addachar(note_p curr_note,char c,BOOL redraw)
- {
- struct Window *curr_win;
- struct RastPort *curr_rport;
- struct TextFont *curr_font;
-
- if (!curr_note)
- return;
-
- curr_win = curr_note->win;
-
- if (!curr_win)
- return; /* The window's not open */
-
- curr_rport = curr_win->RPort;
- curr_font = curr_rport->Font;
-
- /* Is the character un-printable ? */
-
- if ((c != '\b') && (c != '\r') && (c != 127) && (c != '\t')) {
- if (((UBYTE)c < curr_font->tf_LoChar) || ((UBYTE)c > curr_font->tf_HiChar)) {
- return;
- }
- }
-
- if (c == '\b') {
- if (curr_note->carat.text > curr_note->text) {
- remove_char_from_string(curr_note->carat.text - 1);
-
- curr_note->carat.text--;
-
- if (redraw) {
- carat_from_ptr(curr_note,PTRCHANGE_CLICK);
- note_refresh(curr_note);
- }
- }
- }
- else if (c == 127) {
- if (*curr_note->carat.text != '\0') {
- remove_char_from_string(curr_note->carat.text);
-
- if (redraw) {
- carat_from_ptr(curr_note,PTRCHANGE_CLICK);
- note_refresh(curr_note);
- }
- }
- }
- else if (c == '\t') {
- if (strlen(curr_note->text) < (STRLEN_NOTETEXT - 1)) {
- add_char_to_string(curr_note->carat.text,' ');
-
- curr_note->carat.text++;
-
- if (redraw) {
- carat_from_ptr(curr_note,PTRCHANGE_CLICK);
- note_refresh(curr_note);
- }
- }
- }
- else if (c == '\r') {
- carat_clear(curr_note);
-
- /* If commodities window open, refresh listview */
-
- if (commod) {
- GT_SetGadgetAttrs(commodGadgets[commod_listview],
- commod,NULL,GTLV_Labels,~0,TAG_END);
- GT_SetGadgetAttrs(commodGadgets[commod_listview],
- commod,NULL,GTLV_Labels,&prj->commodlist,TAG_END);
- }
- }
- else {
- if (strlen(curr_note->text) < (STRLEN_NOTETEXT - 1)) {
- /* Add the character then refresh */
-
- add_char_to_string(curr_note->carat.text,c);
-
- curr_note->carat.text++;
-
- if (redraw) {
- carat_from_ptr(curr_note,PTRCHANGE_CLICK);
- note_refresh(curr_note);
- }
- }
- }
- }
-