/* * ClipTool (Udklipsværktøj) - A Commodities Exchange Application * Copyright (C) 1994 Torsten Poulin * * gui.c - the graphic user interface * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * * The author can be contacted by mail at * Torsten Poulin * Banebrinken 99, 2, 77 * DK-2400 Copenhagen NV * Denmark * or via email: torsten@diku.dk * * $Log: gui.c,v $ * Revision 1.1 94/02/20 21:31:46 Torsten * Initial revision * */ static char const RCSid[] = "$Id: gui.c,v 1.1 94/02/20 21:31:46 Torsten Exp $"; #include "cliptool.h" #include "ctstrings.h" struct Menu *ctmenustrip; static void eraseframe(struct Rectangle *); static void drawframe(struct Rectangle *); static void *vi; static struct Gadget *glist; static BOOL hasmenus; static struct Rectangle rect; static struct Region *region; static prevLeft, prevTop, prevWidth, prevHeight; static struct NewMenu ctmenu[] = { { NM_TITLE, 0, 0, 0, 0, 0,}, /* Project */ { NM_ITEM, 0, 0, 0, 0, 0,}, /* Open */ { NM_SUB, 0, 0, 0, 0, (void *) CTM_OPENTEXT,}, { NM_SUB, 0, 0, 0, 0, (void *) CTM_OPENFTXT,}, { NM_ITEM, 0, 0, 0, 0, (void *) CTM_SAVE,}, { NM_SUB, 0, 0, 0, 0, (void *) CTM_SAVETEXT,}, { NM_SUB, 0, 0, 0, 0, (void *) CTM_SAVEFTXT,}, { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,}, { NM_ITEM, 0, 0, 0, 0, (void *) CTM_ABOUT,}, { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,}, { NM_ITEM, 0, 0, 0, 0, (void *) CTM_HIDE,}, { NM_ITEM, 0, 0, 0, 0, (void *) CTM_QUIT,}, { NM_TITLE, 0, 0, 0, 0, 0,}, /* Edit */ { NM_ITEM, 0, 0, 0, 0, (void *) CTM_CUT,}, { NM_ITEM, 0, 0, 0, 0, (void *) CTM_COPY,}, { NM_ITEM, 0, 0, 0, 0, (void *) CTM_PASTE,}, { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,}, { NM_ITEM, 0, 0, 0, 0, (void *) CTM_KILL,}, { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,}, { NM_ITEM, 0, 0, 0, 0, (void *) CTM_PREV,}, { NM_ITEM, 0, 0, 0, 0, (void *) CTM_NEXT,}, { NM_TITLE, 0, 0, 0, 0, 0,}, /* Settings */ { NM_ITEM, 0, 0, 0, 0, (void *) CTM_UNIT,}, { NM_ITEM, NM_BARLABEL, 0, 0, 0, 0,}, { NM_ITEM, 0, 0, CHECKIT | MENUTOGGLE, 0, (void *) CTM_ICONS,}, { NM_ITEM, 0, 0, CHECKIT | MENUTOGGLE, 0, (void *) CTM_APPICON,}, { NM_ITEM, 0, 0, CHECKIT | MENUTOGGLE | NM_ITEMDISABLED, 0, (void *) CTM_AUTO,}, /* not supported, yet :) */ { NM_END, NULL, 0, 0, 0, 0,}, }; void initnewmenustruct(void) { /* Project menu */ ctmenu[0].nm_Label = ls(MSG_PROJECT_MENU); ctmenu[1].nm_Label = ls(MSG_PROJECT_OPEN); ctmenu[2].nm_Label = ls(MSG_PROJECT_OPENSAVEAS_TEXT); ctmenu[2].nm_CommKey = ls(MSG_PROJECT_OPEN_KEY); ctmenu[3].nm_Label = ls(MSG_PROJECT_OPENSAVEAS_FTXT); ctmenu[4].nm_Label = ls(MSG_PROJECT_SAVEAS); ctmenu[5].nm_Label = ls(MSG_PROJECT_OPENSAVEAS_TEXT); ctmenu[5].nm_CommKey = ls(MSG_PROJECT_SAVEAS_KEY); ctmenu[6].nm_Label = ls(MSG_PROJECT_OPENSAVEAS_FTXT); ctmenu[8].nm_Label = ls(MSG_PROJECT_ABOUT); ctmenu[10].nm_Label = ls(MSG_PROJECT_HIDE); ctmenu[10].nm_CommKey = ls(MSG_PROJECT_HIDE_KEY); ctmenu[11].nm_Label = ls(MSG_PROJECT_QUIT); ctmenu[11].nm_CommKey = ls(MSG_PROJECT_QUIT_KEY); /* Edit menu */ ctmenu[12].nm_Label = ls(MSG_EDIT_MENU); ctmenu[13].nm_Label = ls(MSG_EDIT_CUT); ctmenu[13].nm_CommKey = ls(MSG_EDIT_CUT_KEY); ctmenu[14].nm_Label = ls(MSG_EDIT_COPY); ctmenu[14].nm_CommKey = ls(MSG_EDIT_COPY_KEY); ctmenu[15].nm_Label = ls(MSG_EDIT_PASTE); ctmenu[15].nm_CommKey = ls(MSG_EDIT_PASTE_KEY); ctmenu[17].nm_Label = ls(MSG_EDIT_ERASE); ctmenu[17].nm_CommKey = ls(MSG_EDIT_ERASE_KEY); ctmenu[19].nm_Label = ls(MSG_EDIT_PREVIOUS); ctmenu[19].nm_CommKey = ls(MSG_EDIT_PREVIOUS_KEY); ctmenu[20].nm_Label = ls(MSG_EDIT_NEXT); ctmenu[20].nm_CommKey = ls(MSG_EDIT_NEXT_KEY); /* Settings menu */ ctmenu[21].nm_Label = ls(MSG_SETTINGS_MENU); ctmenu[22].nm_Label = ls(MSG_SETTINGS_CLIPUNIT); ctmenu[22].nm_CommKey = ls(MSG_SETTINGS_CLIPUNIT_KEY); ctmenu[24].nm_Label = ls(MSG_SETTINGS_CREATEICONS); ctmenu[25].nm_Label = ls(MSG_SETTINGS_APPICON); ctmenu[26].nm_Label = ls(MSG_SETTINGS_AUTOMATIC); } static UWORD chip appiconI1Data[] = { /* Plane 0 */ 0xFFFF,0xFFFF,0xFF00,0xC000,0x0000,0x0000,0xC000,0x0000, 0x0000,0xC001,0x5540,0x0000,0xC0FF,0xFFFF,0x0000,0xC0E0, 0xFF87,0x8000,0xC0E0,0x0007,0x8000,0xC0E6,0x9B67,0x8000, 0xC0E0,0x0007,0x8000,0xC0E7,0xCEC7,0x8000,0xC0E0,0x0007, 0x8000,0xC0E6,0xEA87,0x8000,0xC0E0,0x0007,0x8000,0xC0E7, 0x7987,0x8000,0xC0E0,0x0007,0x8000,0xC0E7,0x71FF,0x8000, 0xC0E0,0x010F,0x8000,0xC0E0,0x013F,0x8000,0xC0FF,0xFFFF, 0x8000,0xC0FF,0xFFFF,0x8000,0xC07F,0xFFFF,0x8000,0xC000, 0x0000,0x0000,0xC000,0x0000,0x0000,0x8000,0x0000,0x0000, /* Plane 1 */ 0x0000,0x0000,0x0080,0x0000,0x0000,0x0180,0x0000,0x0000, 0x0180,0x0001,0xFFC0,0x0180,0x0001,0xFFC0,0x0180,0x001F, 0xAAFC,0x8180,0x001F,0xFFFC,0x8180,0x0019,0x649C,0x8180, 0x001F,0xFFFC,0x8180,0x0018,0x313C,0x8180,0x001F,0xFFFC, 0x8180,0x0019,0x157C,0x8180,0x001F,0xFFFC,0x8180,0x0018, 0x867C,0x8180,0x001F,0xFFFC,0x8180,0x0018,0x8E00,0x8180, 0x001F,0xFEF8,0x8180,0x001F,0xFEE0,0x8180,0x001F,0xFF00, 0x8180,0x0000,0x0000,0x8180,0x007F,0xFFFF,0x8180,0x0000, 0x0000,0x0180,0x0000,0x0000,0x0180,0x7FFF,0xFFFF,0xFF80, }; static struct Image appiconI1 = { 0, 0, /* Upper left corner */ 41, 24, 2, /* Width, Height, Depth */ appiconI1Data, /* Image data */ 0x0003, 0x0000, /* PlanePick, PlaneOnOff */ NULL /* Next image */ }; static struct DiskObject appicon_do = { 0, /* Magic Number */ 0, /* Version */ { /* Embedded Gadget Structure */ NULL, /* Next Gadget Pointer */ 0, 0, 41, 25, /* Left,Top,Width,Height */ 0, /* Flags */ 0, /* Activation Flags */ 0, /* Gadget Type */ (APTR)&appiconI1, /* Render Image */ NULL, /* Select Image */ NULL, /* Gadget Text */ NULL, /* Mutual Exclude */ NULL, /* Special Info */ 0, /* Gadget ID */ NULL, /* User Data (Revision) */ }, NULL, /* Icon Type */ NULL, /* Default Tool */ NULL, /* Tool Type Array */ NO_ICON_POSITION, /* Current X */ NO_ICON_POSITION, /* Current Y */ NULL, /* Drawer Structure */ NULL, /* Tool Window */ 0, /* Stack Size */ }; void opendropicon(void) { if (appicon_mp = CreateMsgPort()) { aisigflag = 1 << appicon_mp->mp_SigBit; appicon = AddAppIconA(0, 0, ls(MSG_CLIPTOOL), appicon_mp, NULL, &appicon_do, NULL); } } void closedropicon(void) { struct AppMessage *aimsg; if (appicon) RemoveAppIcon(appicon); appicon = NULL; if (appicon_mp) { while (aimsg = (struct AppMessage *) GetMsg(appicon_mp)) ReplyMsg((struct Message *) aimsg); DeleteMsgPort(appicon_mp); } appicon_mp = NULL; } void about(void) { struct EasyStruct aboutreq; aboutreq.es_StructSize = sizeof(struct EasyStruct); aboutreq.es_Flags = 0; aboutreq.es_Title = ls(MSG_ABOUTCLIPTOOL); aboutreq.es_TextFormat = "%s - © 1994 Torsten Poulin (torsten@diku.dk)\n" "(%s: \"%s\" %s: \"%s\")\n\n" "This program is free software; you can redistribute it and/or modify\n" "it under the terms of the GNU General Public License as published by\n" "the Free Software Foundation; either version 2 of the License , or\n" "(at your option) any later version.\n\n" "This program is distributed in the hope that it will be useful,\n" "but WITHOUT ANY WARRANTY; without even the implied warranty of\n" "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n" "GNU General Public License for more details.\n\n" "You should have received a copy of the GNU General Public License\n" "along with this program. If not, write to the Free Software\n" "Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.\n"; aboutreq.es_GadgetFormat = ls(MSG_OK_GAD); EasyRequest(NULL, &aboutreq, NULL, verstring, ls(MSG_PORTNAME), portname, ls(MSG_HOTKEY), hotkey); } void msgreq(UBYTE *msg, UBYTE *name) { struct EasyStruct msgreq; msgreq.es_StructSize = sizeof(struct EasyStruct); msgreq.es_Flags = 0; msgreq.es_Title = ls(MSG_CLIPTOOL); msgreq.es_TextFormat = msg; msgreq.es_GadgetFormat = ls(MSG_OK_GAD); EasyRequest(NULL, &msgreq, NULL, name); } /* * Return the address of the menu-item with UserData = number. * This makes it possible for us to find and check the state * of the "Create menus?" item for instance. * * I could have used ItemAddress(), but I don't want to depend * on the layout of the menus :) */ struct MenuItem *findmenuitem(struct Menu *m, long number) { struct MenuItem *mi, *si; for (; m; m = m->NextMenu) for (mi = m->FirstItem; mi; mi = mi->NextItem) { if (number == (long) GTMENUITEM_USERDATA(mi)) return mi; for (si = mi->SubItem; si; si = si->NextItem) if (number == (long) GTMENUITEM_USERDATA(si)) return si; } return NULL; } /* * This function makes sure the flags controlled by * the menu toggle items reflect what is shown in the menu. * It's a shame that Intuition can't be trusted :-/ */ void synchronizechecked(void) { struct MenuItem *mi; if (hasmenus && guiwin) { if (mi = findmenuitem(ctmenustrip, CTM_ICONS)) createicons = mi->Flags & CHECKED; if (mi = findmenuitem(ctmenustrip, CTM_APPICON)) usedropicon = mi->Flags & CHECKED; } } /* * Open the graphic user interface window. * If it is already open, it is brought to the front. * * The window is also made a Workbench AppWindow, if possible. * This may fail for a number of reasons, the most common one * being that Workbench isn't open... */ BOOL opengui(void) { struct Screen *pubscr = NULL; struct DrawInfo *scr_di; struct MenuItem *mi; WORD alternate[4]; BOOL simple = FALSE; if (guiwin) { /* The GUI is already open; bring it to front */ if (guiminimized) { ZipWindow(guiwin); guiminimized = FALSE; } WindowToFront(guiwin); } else { /* Make sure we don't get a nasty surprise when we clean up ... */ guiminimized = hasmenus = FALSE; ctmenustrip = NULL; glist = NULL; vi = NULL; region = NULL; appwin_mp = NULL; appwin = NULL; /* Get a lock on the default public screen */ if (pubscr = LockPubScreen(NULL)) { if ((vi = GetVisualInfo(pubscr, TAG_END))) { xoffset = pubscr->WBorLeft; yoffset = pubscr->WBorTop + (pubscr->Font->ta_YSize + 1); alternate[0] = 0; /* LeftEdge */ alternate[1] = yoffset; /* TopEdge */ alternate[2] = GUI_WIDTH; /* Width */ alternate[3] = GUI_HEIGHT; /* Height */ /* * Determine what kind of imagery we're going to use. */ if (simplebuttons) simple = TRUE; else if (scr_di = GetScreenDrawInfo(pubscr)) { simple = scr_di->dri_Depth == 1; FreeScreenDrawInfo(pubscr, scr_di); } if (createbuttonbar(&glist, vi, simple)) { if (ctmenustrip = CreateMenus(ctmenu, TAG_END)) { if (LayoutMenus(ctmenustrip, vi, TAG_END)) { if (prevWidth == 0 || prevHeight == 0) { /* Window hasn't been opened before */ prevLeft = 10; prevTop = 20; prevWidth = GUI_WIDTH; prevHeight = GUI_HEIGHT; } guiwin = OpenWindowTags(NULL, WA_Left, prevLeft, WA_Top, prevTop, WA_InnerWidth, prevWidth, WA_InnerHeight, prevHeight, WA_MinWidth, alternate[2], WA_MaxWidth, ~0, WA_MinHeight, alternate[3], WA_MaxHeight, ~0, WA_Zoom, &alternate[0], WA_Activate, TRUE, WA_AutoAdjust, TRUE, WA_DragBar, TRUE, WA_CloseGadget, TRUE, WA_DepthGadget, TRUE, WA_SizeGadget, TRUE, WA_SimpleRefresh, TRUE, WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_REFRESHWINDOW | IDCMP_GADGETUP | IDCMP_MENUPICK | IDCMP_SIZEVERIFY, WA_PubScreen, pubscr, WA_Gadgets, glist, TAG_END); } } } UnlockPubScreen(NULL, pubscr); /* not needed anymore */ } if (guiwin) { if (guiwin->WidthHeightmp_SigBit; appwin = AddAppWindowA(0, 0, guiwin, appwin_mp, NULL); } rect.MinX = xoffset + 4; rect.MinY = yoffset + 21; rect.MaxX = guiwin->Width - guiwin->BorderRight - 4; rect.MaxY = guiwin->Height - guiwin->BorderBottom - 3; if (region = NewRegion()) { if (OrRectRegion(region, &rect)) { drawframe(&rect); InstallClipRegion(guiwin->WLayer, region); SetDrMd(guiwin->RPort, 0L); updatetitlebar(); /* Set checkmarks */ if (mi = findmenuitem(ctmenustrip, CTM_ICONS)) if (createicons) mi->Flags |= CHECKED; if (mi = findmenuitem(ctmenustrip, CTM_APPICON)) if (usedropicon) mi->Flags |= CHECKED; GT_RefreshWindow(guiwin, NULL); hasmenus = SetMenuStrip(guiwin, ctmenustrip); showtext(); } else return FALSE; /* OrRectRegion() failed */ } else return FALSE; /* no region */ } } } } return (BOOL) guiwin; } /* * Close the GUI. */ void closegui(void) { struct AppMessage *awmsg; if (guiwin && region) DisposeRegion(region); region = NULL; if (hasmenus && guiwin) ClearMenuStrip(guiwin); hasmenus = FALSE; if (appwin) RemoveAppWindow(appwin); appwin = NULL; if (appwin_mp) { while (awmsg = (struct AppMessage *) GetMsg(appwin_mp)) ReplyMsg((struct Message *) awmsg); DeleteMsgPort(appwin_mp); } appwin_mp = NULL; synchronizechecked(); /* remember states */ if (guiwin) { /* save the present size for later use */ prevLeft = guiwin->LeftEdge; prevTop = guiwin->TopEdge; prevWidth = guiwin->Width - xoffset - guiwin->BorderRight; prevHeight = guiwin->Height - yoffset - guiwin->BorderBottom; CloseWindow(guiwin); } guiwin = NULL; FreeMenus(ctmenustrip); ctmenustrip = NULL; FreeGadgets(glist); glist = NULL; FreeVisualInfo(vi); vi = NULL; } /* * Resize the display box. */ BOOL newsize(void) { rect.MinX = xoffset + 4; rect.MinY = yoffset + 21; rect.MaxX = guiwin->Width - guiwin->BorderRight - 4; rect.MaxY = guiwin->Height - guiwin->BorderBottom - 3; InstallClipRegion(guiwin->WLayer, NULL); eraseframe(&rect); drawframe(&rect); ClearRegion(region); if (OrRectRegion(region, &rect)) InstallClipRegion(guiwin->WLayer, region); else return FALSE; /* we're in trouble!!! */ return TRUE; } /* * The functions below handle the display of text */ static void eraseframe(struct Rectangle *rect) { SetAPen(guiwin->RPort, 0); RectFill(guiwin->RPort, rect->MinX - 3, rect->MinY - 2, rect->MaxX + 2 + 1, rect->MaxY + 1 + 1); } static void drawframe(struct Rectangle *rect) { DrawBevelBox(guiwin->RPort, rect->MinX - 2, rect->MinY - 1, rect->MaxX - rect->MinX + 4, rect->MaxY - rect->MinY + 3, GT_VisualInfo, vi, GTBB_Recessed, TRUE, TAG_END); } void showtext(void) { long count, position; struct textbuffer *tb; struct TextFont *font; if (!guiwin) return; font = guiwin->RPort->Font; SetRast(guiwin->RPort, 0); if (!currentbuffer) return; /* nothing to display */ tb = currentbuffer->tb; Move(guiwin->RPort, rect.MinX + 1, rect.MinY + font->tf_YSize); SetAPen(guiwin->RPort, 1); for (; tb; tb = tb->next) { position = 0; count = 0; while (position <= tb->length) { while (tb->data[count] != '\n' && count <= tb->length) count++; Text(guiwin->RPort, &tb->data[position], count - position); while (tb->data[count] == '\n' && count <= tb->length) { Move(guiwin->RPort, rect.MinX + 1, guiwin->RPort->cp_y + font->tf_YSize + 1); count++; } position = count; } if (guiwin->RPort->cp_y > rect.MaxY) return; } } /* * Unit number requester */ void getunitnumber(void) { struct TextAttr Topaz80 = { "topaz.font", 8, 0, 0, }; struct Window *unitreq; void *unvi = NULL; struct Gadget *unglist = NULL, *ungad; struct NewGadget ng; struct IntuiMessage *imsg; long fheight; BOOL done = FALSE; long value = unitnumber; long oklen, cancellen, buttonlen, labellen, winwidth; UBYTE *ok = ls(MSG_OK_GAD); UBYTE *cancel = ls(MSG_CANCEL_GAD); UBYTE *label = ls(MSG_CLIPBOARDUNIT_GAD); if (!guiwin) return; /* just to be safe... */ fheight = 8; /* Make the buttons wide enough for the text */ oklen = TextLength(guiwin->RPort, ok, strlen(ok)); cancellen = TextLength(guiwin->RPort, cancel, strlen(cancel)); buttonlen = 8 + (oklen > cancellen ? oklen : cancellen); labellen = TextLength(guiwin->RPort, label, strlen(label)); if ((unvi = GetVisualInfo(guiwin->WScreen, TAG_END))) { ungad = CreateContext(&unglist); ng.ng_VisualInfo = unvi; ng.ng_TextAttr = &Topaz80; ng.ng_GadgetText = ok; ng.ng_Width = buttonlen; ng.ng_Height = 14; ng.ng_TopEdge = yoffset + fheight * 2 + 4; ng.ng_LeftEdge = xoffset + 2; ng.ng_GadgetID = 0; ng.ng_Flags = 0; ungad = CreateGadget(BUTTON_KIND, ungad, &ng, TAG_END); ng.ng_GadgetText = cancel; ng.ng_LeftEdge += buttonlen + 4; ng.ng_GadgetID = 1; ungad = CreateGadget(BUTTON_KIND, ungad, &ng, TAG_END); ng.ng_GadgetText = label; ng.ng_Width = 8 * 5 + 8; ng.ng_Height = 14; ng.ng_TopEdge = yoffset + 3; ng.ng_LeftEdge = xoffset + 2 + labellen + 8; ng.ng_Flags = PLACETEXT_LEFT; ng.ng_GadgetID = 2; ungad = CreateGadget(INTEGER_KIND, ungad, &ng, GTIN_Number, unitnumber, GTIN_MaxChars, 4, STRINGA_Justification, GACT_STRINGLEFT, STRINGA_ReplaceMode, TRUE, TAG_END); winwidth = ng.ng_Width + ng.ng_LeftEdge + 2; if (ungad) { unitreq = OpenWindowTags(NULL, WA_Left, guiwin->LeftEdge + xoffset + 1, WA_Top, guiwin->TopEdge + yoffset + 1, WA_InnerWidth, winwidth, WA_InnerHeight, 4 * fheight + 4, WA_Activate, TRUE, WA_AutoAdjust, TRUE, WA_DragBar, TRUE, WA_DepthGadget, TRUE, WA_SimpleRefresh, TRUE, WA_Title, ls(MSG_CLIPTOOL), WA_IDCMP, IDCMP_REFRESHWINDOW | IDCMP_GADGETUP, WA_PubScreen, guiwin->WScreen, WA_Gadgets, unglist, TAG_END); if (unitreq) { GT_RefreshWindow(unitreq, NULL); while (!done) { WaitPort(unitreq->UserPort); while (imsg = GT_GetIMsg(unitreq->UserPort)) { switch(imsg->Class) { case IDCMP_GADGETUP: ungad = (struct Gadget *) imsg->IAddress; switch (ungad->GadgetID) { case 0: unitnumber = value; done = TRUE; break; case 1: done = TRUE; break; case 2: value = ((struct StringInfo *) ungad->SpecialInfo)->LongInt; if (value < 0 || value > 255) { DisplayBeep(guiwin->WScreen); GT_SetGadgetAttrs(ungad, unitreq, NULL, GTIN_Number, value = unitnumber, TAG_END); } break; } break; case IDCMP_REFRESHWINDOW: GT_BeginRefresh(unitreq); GT_EndRefresh(unitreq, TRUE); break; } GT_ReplyIMsg(imsg); } } CloseWindow(unitreq); } } FreeGadgets(unglist); FreeVisualInfo(unvi); } } static char titletxt[50]; void updatetitlebar(void) { if (guiwin) { if (ntotal == 0) strcpy(titletxt, ls(MSG_EMPTYGUITITLE)); else sprintf(titletxt, ls(MSG_GUITITLE), ncurrent, ntotal); SetWindowTitles(guiwin, titletxt, NULL); } } /* * Ghost unavailable menu items if applicable. * mistate() disables an item if state==FALSE, and enables it * otherwise. */ static void mistate(long id, BOOL state) { struct MenuItem *mi; mi = findmenuitem(ctmenustrip, id); if (state) mi->Flags |= ITEMENABLED; else mi->Flags &= ~ITEMENABLED; } void ghosting(void) { static BOOL ghosted = FALSE; if (guiwin) { if (ghosted && ntotal > 0) { ClearMenuStrip(guiwin); mistate(CTM_SAVE, TRUE); mistate(CTM_CUT, TRUE); mistate(CTM_COPY, TRUE); mistate(CTM_KILL, TRUE); mistate(CTM_PREV, TRUE); mistate(CTM_NEXT, TRUE); ResetMenuStrip(guiwin, ctmenustrip); ghosted = FALSE; } if (!ghosted && ntotal == 0) { ClearMenuStrip(guiwin); mistate(CTM_SAVE, FALSE); /* takes care of sub-items, too */ mistate(CTM_CUT, FALSE); mistate(CTM_COPY, FALSE); mistate(CTM_KILL, FALSE); mistate(CTM_PREV, FALSE); mistate(CTM_NEXT, FALSE); ResetMenuStrip(guiwin, ctmenustrip); ghosted = TRUE; } } }