home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Gold Fish 2
/
goldfish_vol2_cd1.bin
/
files
/
util
/
wb
/
stickit2
/
source
/
notes.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-03-29
|
16KB
|
736 lines
/**********************************************
************** notes.c ******************
**********************************************/
#define INTUI_V36_NAMES_ONLY
#include <intuition/intuition.h>
#include <exec/exec.h>
#include <intuition/gadgetclass.h>
#include <clib/intuition_protos.h>
#include <clib/graphics_protos.h>
#include <clib/exec_protos.h>
#include <clib/diskfont_protos.h>
#include <clib/gadtools_protos.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "stickit2.h"
#include "consts.h"
#include "structs.h"
#include "proto.h"
#ifndef GTMN_NewLookMenus
#define GTMN_NewLookMenus GT_TagBase+67
#endif
extern prj_p prj;
extern struct NewMenu noteMenuNewMenu[];
#ifdef _DCC
extern __chip UWORD WaitPointer[];
#else
extern UWORD __chip WaitPointer[];
#endif
/*
Function : note_p note_create(int note_position)
Purpose : Allocates the memory needed for a note, sets all the values to the
default. Returns a pointer to the new note.
*/
note_p note_create(int note_position)
{
struct Gadget gad_resize = {
NULL,
-7,-7,7,7,
GFLG_GADGHNONE | GFLG_GADGIMAGE | GFLG_RELRIGHT |
GFLG_RELBOTTOM,
GACT_IMMEDIATE,
GTYP_SIZING,
NULL,NULL,NULL,NULL,NULL,
0};
note_p new_note;
/* Sort out the storing of the note pointer */
new_note = (note_p)malloc(sizeof(struct note));
if (!new_note)
error("Can't allocate new note",ERR_MALLOC,__LINE__,__FILE__);
/* Set up defaults */
new_note->win = NULL;
new_note->font = NULL;
new_note->visualinfo = NULL;
new_note->menustrip = NULL;
strncpy(new_note->fontname,prj->prefs.notefont,STRLEN_FONTNAME);
new_note->textattr.ta_Name = new_note->fontname;
new_note->textattr.ta_YSize = prj->prefs.textattr.ta_YSize;
new_note->textattr.ta_Style = prj->prefs.textattr.ta_Style;
new_note->textattr.ta_Flags = prj->prefs.textattr.ta_Flags;
build_fontstring(new_note);
new_note->topedge = DEFAULT_TOPEDGE;
new_note->leftedge = DEFAULT_LEFTEDGE;
new_note->width = prj->prefs.notewidth;
new_note->height = prj->prefs.noteheight;
new_note->backcolour = prj->prefs.backcolour;
new_note->textcolour = prj->prefs.textcolour;
new_note->caratcolour = prj->prefs.caratcolour;
new_note->title[0] = '\0';
strcpy(new_note->text,"Empty");
strcpy(new_note->pubscreen,prj->prefs.pubscreen);
/* Copy gadget into note's gadget */
new_note->gad = gad_resize;
/* Add to note array */
prj->notes[note_position] = new_note;
/* Make an entry in the linked list */
new_note->node.ln_Name = new_note->text;
new_note->node.ln_Type = NT_STICKIT2;
new_note->node.ln_Pri = - (BYTE)note_position;
/* Clear the blocking requester */
InitRequester(&new_note->blockreq);
/* If commodities window is open, detach the list before altering it */
if (commod)
GT_SetGadgetAttrs(commodGadgets[commod_listview],commod,NULL,
GTLV_Labels,~0,TAG_END);
Enqueue(&prj->commodlist,&new_note->node);
if (commod)
GT_SetGadgetAttrs(commodGadgets[commod_listview],commod,NULL,
GTLV_Labels,&prj->commodlist,TAG_END);
return(new_note);
}
/*
Function : void note_open(note_p curr_note)
Purpose : Given a note will open the window and draw the text.
*/
void note_open(note_p curr_note)
{
struct RastPort *curr_rport;
struct Window *curr_win;
/* If already open, bring to front */
if (curr_note->win) {
WindowToFront(curr_note->win);
return;
}
curr_note->win = OpenWindowTags(NULL,
WA_Left,curr_note->leftedge,
WA_Top,curr_note->topedge,
WA_Width,curr_note->width,
WA_Height,curr_note->height,
WA_MinWidth,DEFAULT_MINWIDTH,
WA_MaxWidth,DEFAULT_MAXWIDTH,
WA_MinHeight,DEFAULT_MINHEIGHT,
WA_MaxHeight,DEFAULT_MAXHEIGHT,
WA_Gadgets,&curr_note->gad,
WA_Flags,WFLG_CLOSEGADGET | WFLG_DRAGBAR | WFLG_DEPTHGADGET |
WFLG_SIMPLE_REFRESH,
WA_IDCMP,NULL,
WA_Title,curr_note->title,
WA_ScreenTitle,"StickIt2 ©1994 Andy Dean",
WA_PubScreenName,curr_note->pubscreen,
WA_PubScreenFallBack,TRUE,
WA_Dummy+0x30, TRUE, /* NewLookMenus */
TAG_END);
if (!curr_note->win)
error("Can't open note",ERR_OPENNOTE,__LINE__,__FILE__);
curr_win = curr_note->win;
/* Set up menus */
curr_note->visualinfo = GetVisualInfo(curr_win->WScreen,TAG_END);
if (curr_note->visualinfo) {
curr_note->menustrip = CreateMenus(noteMenuNewMenu,TAG_END);
if (curr_note->menustrip) {
if (LayoutMenus(curr_note->menustrip,
curr_note->visualinfo,GTMN_NewLookMenus,TRUE,TAG_END))
SetMenuStrip(curr_win,curr_note->menustrip);
}
}
/* Set up some easy references */
curr_rport = curr_note->win->RPort;
/* Connect window to message port */
curr_note->win->UserPort = prj->main_msg_port;
ModifyIDCMP(curr_note->win,IDCMP_REFRESHWINDOW|IDCMP_CLOSEWINDOW|
IDCMP_NEWSIZE|IDCMP_INACTIVEWINDOW|IDCMP_MOUSEBUTTONS|IDCMP_VANILLAKEY|
IDCMP_RAWKEY|IDCMP_CHANGEWINDOW|IDCMP_MENUPICK);
/* Set font, if different than the system default */
if ((!curr_note->font) && (curr_note->fontname[0] != '\0'))
curr_note->font = OpenDiskFont(&curr_note->textattr);
/* Add any font styles */
if (curr_note->font) {
SetFont(curr_note->win->RPort,curr_note->font);
SetSoftStyle(curr_rport,curr_note->textattr.ta_Style ^
curr_note->font->tf_Style,(FSF_BOLD | FSF_UNDERLINED | FSF_ITALIC));
}
else /* Cancel font name */
curr_note->fontname[0] = '\0';
/* No carat */
curr_note->carat.text = NULL;
curr_note->carat.xpos = curr_note->carat.ypos = 0;
curr_note->carat.oldxpos = curr_note->carat.oldypos = 0;
}
/*
Function : void note_close(note_p curr_note,bool_e kill)
Purpose : Closes window. Copies last position and size of window. If kill
== FALSE, it doesn't dellocate the gadget memory or close the font,
as the window may be opened up again sometime later. If kill == TRUE
then all resources are deallocated. The memory for the note itself
is also dellocated if kill == TRUE.
*/
void note_close(note_p curr_note,bool_e kill)
{
/* If already closed, return */
if (curr_note->win) {
/* Store window info */
curr_note->leftedge = curr_note->win->LeftEdge;
curr_note->topedge = curr_note->win->TopEdge;
curr_note->width = curr_note->win->Width;
curr_note->height = curr_note->win->Height;
/* Handle menu stuff */
if (curr_note->menustrip) {
ClearMenuStrip(curr_note->win);
FreeMenus(curr_note->menustrip);
}
if (curr_note->visualinfo)
FreeVisualInfo(curr_note->visualinfo);
/* Actually close the window */
andysCloseWindowSafely(curr_note->win);
curr_note->win = NULL;
}
if (kill) {
if (curr_note->font) {
CloseFont(curr_note->font);
curr_note->font = NULL;
}
/* If the listview is up, disconnect it and remove the node */
if (commod) {
GT_SetGadgetAttrs(commodGadgets[commod_listview],
commod,NULL,GTLV_Labels,~0,TAG_END);
Remove(&curr_note->node);
GT_SetGadgetAttrs(commodGadgets[commod_listview],
commod,NULL,GTLV_Labels,&prj->commodlist,TAG_END);
}
/* Free the memory */
free(curr_note);
}
}
/*
Function : void note_refresh(note_p curr_note)
Purpose : Redraws the background and the text in the note.
*/
void note_refresh(note_p curr_note)
{
struct Window *curr_win;
struct RastPort *curr_rport;
struct TextExtent textextent_result;
char *text_ptr;
ULONG remaininglength;
LONG textbaseline,topoffset;
LONG textfit;
int l;
/* 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;
/* Draw backdrop */
SetDrMd(curr_rport,JAM1);
SetAPen(curr_rport,curr_note->backcolour);
RectFill(curr_rport,(LONG)curr_win->BorderLeft,
(LONG)curr_win->BorderTop,curr_win->Width - (curr_win->BorderRight + 1),
curr_win->Height - (curr_win->BorderBottom + 1));
/* Set drawing mode */
SetAPen(curr_rport,curr_note->textcolour);
SetBPen(curr_rport,curr_note->backcolour);
/* 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)))
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 */
SetAPen(curr_rport,curr_note->textcolour);
Text(curr_rport,text_ptr,textfit);
/* 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)
break;
/* Else, set up next line pointer */
text_ptr += textfit;
}
/* If there was a carat in the window, redraw it. Clear old one first */
curr_note->carat.oldxpos = curr_note->carat.oldypos = 0;
carat_draw(curr_note);
}
/*
Function : BOOL note_event(struct IntuiMessage *curr_msg)
Purpose : Handles any events related to the notes on the screen.
*/
BOOL note_event(struct IntuiMessage *curr_msg)
{
note_p curr_note;
char *temp_carat;
int notepos;
curr_note = note_from_window(curr_msg->IDCMPWindow);
/* If stray message from closed window */
if (!curr_note)
return(FALSE);
switch(curr_msg->Class) {
case IDCMP_MENUPICK:
note_menuevent(curr_note,curr_msg);
break;
case IDCMP_MOUSEBUTTONS:
switch(curr_msg->Code) {
case SELECTDOWN:
/* Select in listview if open */
if (commod) {
notepos = positionfromnote(
curr_note);
if (notepos != NOT_IN_ARRAY)
commodlistview(
notepos,0,0);
GT_SetGadgetAttrs(
commodGadgets[commod_listview],commod,NULL,GTLV_Selected,notepos,TAG_END);
}
/* Where's carat ? */
carat_from_coords(curr_note,
curr_msg->MouseX,curr_msg->MouseY);
break;
default:
break;
}
break;
case IDCMP_REFRESHWINDOW:
BeginRefresh(curr_note->win);
note_refresh(curr_note);
EndRefresh(curr_note->win,TRUE);
break;
case IDCMP_NEWSIZE:
/* Store window info */
curr_note->leftedge = curr_note->win->LeftEdge;
curr_note->topedge = curr_note->win->TopEdge;
curr_note->width = curr_note->win->Width;
curr_note->height = curr_note->win->Height;
/* Store carat to place back */
temp_carat = curr_note->carat.text;
/* Remove carat */
carat_clear(curr_note);
note_refresh(curr_note);
/* Place carat back */
if (temp_carat) {
curr_note->carat.text = temp_carat;
carat_from_ptr(curr_note,PTRCHANGE_CURSOR);
}
break;
case IDCMP_CHANGEWINDOW:
/* Store window info */
curr_note->leftedge = curr_note->win->LeftEdge;
curr_note->topedge = curr_note->win->TopEdge;
curr_note->width = curr_note->win->Width;
curr_note->height = curr_note->win->Height;
break;
case IDCMP_INACTIVEWINDOW:
/* Remove carat */
carat_clear(curr_note);
/* If commodities window open, refresh list */
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);
}
break;
case IDCMP_CLOSEWINDOW:
note_close(curr_note,FALSE);
break;
case IDCMP_VANILLAKEY:
/* Is there a carat in the window ? */
if (curr_note->carat.text)
carat_vanillakey(curr_note,curr_msg);
break;
case IDCMP_RAWKEY:
/* Is there a carat in the window ? */
if (curr_note->carat.text)
carat_rawkey(curr_note,curr_msg);
break;
default:
break;
}
return(FALSE);
}
/*
Function : note_p note_from_window(struct Window *curr_win)
Purpose : Given a window pointer, searches the array of notes and if any
note has that window pointer, returns a pointer to that note. Returns
NULL if no valid window is found (ie stray message from closed
window).
*/
note_p note_from_window(struct Window *curr_win)
{
int l;
for (l = 0; l < NO_NOTES; l++) {
if (!prj->notes[l])
continue;
if (prj->notes[l]->win == curr_win)
return(prj->notes[l]);
}
/* Couldn't find the window */
return(NULL);
}
/*
Function : void note_block(note_p curr_note)
Purpose : Blocks the current note to mouse input and puts up a wait pointer.
*/
void note_block(note_p curr_note)
{
/* Only do it if window open */
if (!curr_note->win)
return;
InitRequester(&curr_note->blockreq);
if (Request(&curr_note->blockreq,curr_note->win))
SetPointer(curr_note->win,WaitPointer,16,16,-6,0);
}
/*
Function : void note_blockclear(note_p curr_note)
Purpose : Clears the current note for mouse input and returns to the normal
pointer.
*/
void note_blockclear(note_p curr_note)
{
/* Only do it if window open */
if (!curr_note->win)
return;
ClearPointer(curr_note->win);
EndRequest(&curr_note->blockreq,curr_note->win);
}
/*
Function : void note_blockall()
Purpose : Blocks all the open notes.
*/
void note_blockall()
{
note_p curr_note;
int l;
for (l = 0; l < NO_NOTES; l++) {
if (prj->notes[l]) {
curr_note = prj->notes[l];
if (curr_note->win)
note_block(curr_note);
}
}
}
/*
Function : void note_blockclearall()
Purpose : Unblocks all the open notes.
*/
void note_blockclearall()
{
note_p curr_note;
int l;
for (l = 0; l < NO_NOTES; l++) {
if (prj->notes[l]) {
curr_note = prj->notes[l];
if (curr_note->win)
note_blockclear(curr_note);
}
}
}
/*
Function : void note_menuevent(note_p curr_note,struct IntuiMessage *curr_msg)
Purpose : Handles menu events from a note.
*/
void note_menuevent(note_p curr_note,struct IntuiMessage *curr_msg)
{
struct MenuItem *menuitem;
char *temp_carat = NULL;
UWORD menunumber;
UWORD menunum;
UWORD itemnumber;
UWORD subnumber;
BOOL done = FALSE;
menunumber = curr_msg->Code;
while ((menunumber != MENUNULL) && (!done)) {
menuitem = ItemAddress(curr_note->menustrip,menunumber);
menunum = MENUNUM(menunumber);
itemnumber = ITEMNUM(menunumber);
subnumber = SUBNUM(menunumber);
switch (menunum) {
case NOMENU:
break;
case noteMenu_project:
switch (itemnumber) {
case NOITEM:
break;
case noteMenu_project_save:
file_writenotes();
break;
case noteMenu_project_panel:
openwindowcommod();
break;
default:
break;
}
break;
case noteMenu_edit:
switch(itemnumber) {
case NOITEM:
break;
case noteMenu_edit_copy:
notemenu_editcopy(curr_note);
break;
case noteMenu_edit_cut:
if (notemenu_editcopy(
curr_note)) {
temp_carat =
curr_note->carat.text;
if (temp_carat)
carat_clear(curr_note);
curr_note->text[0] =
'\0';
note_refresh(curr_note);
if (temp_carat) {
curr_note->carat.text =
curr_note->text;
carat_from_ptr(
curr_note,PTRCHANGE_CURSOR);
}
}
prj->projectchanged = TRUE;
break;
case noteMenu_edit_delete:
temp_carat = curr_note->carat.text;
if (temp_carat)
carat_clear(curr_note);
curr_note->text[0] = '\0';
note_refresh(curr_note);
if (temp_carat) {
curr_note->carat.text =
curr_note->text;
carat_from_ptr(
curr_note,PTRCHANGE_CURSOR);
}
prj->projectchanged = TRUE;
break;
case noteMenu_edit_paste:
notemenu_editpaste(curr_note);
break;
default:
break;
}
break;
default:
break;
}
menunumber = menuitem->NextSelect;
}
}