home *** CD-ROM | disk | FTP | other *** search
- /*--------------------------------------------------
- PMFRUSER.C -- FRACTINT for PM
-
- User Action (Menus mostly) handling
-
- 04/16/91 Code by Donald P. Egen (with help)
-
- The main function (PMfrCommands) acts on the
- events generated by the user on the menus.
- Actions necessary to carry out user requests
- from the menus and/or with mouse and keyboard
- on the main window are performed by the
- subroutines in this module.
-
- Decoding of mouse/keyboard events into these
- action sets is done by the main window procedure
- (ClientWndProc in PMFRACT.C).
-
- All this code is a separate module from the main
- window procedure, so that it can be a separate
- segment, and therefore only be in memory when
- the user is futzing with the program's controls.
-
- ---------------------------------------------------*/
-
- #define INCL_WIN
- #define INCL_GPI
- #define INCL_DOS
- #include <os2.h>
- #include <process.h>
- #include <string.h>
- #include <stdlib.h>
- #include <stdio.h>
- #include <smplhelp.h>
-
- #include <opendlg.h>
-
- #include "pmfract.h"
- #include "fractint.h"
- #include "fractype.h"
-
- MRESULT PMfrCommands (HWND hwnd, USHORT msg, MPARAM mp1, MPARAM mp2)
- {
- /*
- These are the routnes that handle the commands issued by
- the FRACTINT for PM menus.
-
- In most cases, they call another support routine to
- handle or schedule the event requested by the user.
- */
-
- SHORT sCommand = SHORT1FROMMP(mp1);
-
-
- switch (sCommand)
- {
- case IDM_GO:
- /* fire up the subtask */
- cp.fContinueCalc = TRUE ;
- if (npNewParms.fNewParms)
- {
- CopyParmsToBase();
- /* GetMemoryBitmap(); */
- SetSwitchEntry (hwnd, szTitleBar,
- GetFractalName(cp.iFractType) );
- }
-
- cp.sSubAction = SUB_ACT_CALC; /* we want a Calculation */
-
- DosSemClear (&cp.ulSemTrigger) ; /* release the subthread */
-
- sStatus = STATUS_WORKING ;
- /* WinInvalidateRect (hwnd, NULL, FALSE) ; */
- UpdateMenuText (hwnd, IDM_FREEZE_HALT, szHalt);
- EnableMenuItem (hwnd, IDM_GO, FALSE) ;
- EnableMenuItem (hwnd, IDM_FREEZE_HALT, TRUE) ;
- /* WinStartTimer (hab, hwnd, ID_TIMER, 5000); */
- return 0 ;
-
- case IDM_PAN:
- /* Pan selected. Pan to where the cross hairs were */
- PanNewCenter(hwnd);
- fGoodPan = FALSE;
- return 0;
-
- case IDM_ZIN_WIN:
- /* Zoom to the Window selected. */
- EraseZoomBox(hwnd);
- ZoomNewWindow(hwnd, TRUE); /* zoom in */
- fGoodZoom = FALSE;
- return 0;
-
- case IDM_ZOUT_WIN:
- /* Zoom to the Window selected. */
- EraseZoomBox(hwnd);
- ZoomNewWindow(hwnd, FALSE); /* zoom out */
- fGoodZoom = FALSE;
- return 0;
-
- case IDM_FREEZE_HALT:
- if (sStatus == STATUS_WORKING)
- {
- /* schedule the subthread to find a stopping place */
- cp.fContinueCalc = FALSE ;
- EnableMenuItem (hwnd, IDM_FREEZE_HALT, FALSE) ;
- }
- if (sStatus == STATUS_READY)
- {
- /* we Freeze to play with parms repeatedly */
- /* make a copy to play with. We will keep */
- /* working with only this copy */
- InitNewParms(NULL);
- /* now change state */
- sStatus = STATUS_FROZEN;
- EnableMenuItem (hwnd, IDM_FREEZE_HALT, FALSE);
- }
-
- return 0 ;
-
- case IDM_ABOUT:
- /* send up the About box */
- WinDlgBox (HWND_DESKTOP, hwnd, AboutDlgProc,
- (HMODULE) 0, IDD_ABOUT, NULL) ;
-
- return 0 ;
-
- case IDM_NEW_FRACTAL:
- /*
- * send up the Select Fractal Type box.
- * On OK return, schedule the new parameters.
- * Handle the special cases needing files or other data
- * as part of exiting the initial dialog box.
- */
- if (WinDlgBox (HWND_DESKTOP, hwnd, SelFractalDlgProc,
- (HMODULE) 0, IDD_SET_FRACTTYPE, NULL) )
- ScheduleNewParms (hwnd);
-
- return 0 ;
-
- case IDM_SET_PARAMS:
- /*
- * send up the Set Paramters box.
- * On OK return, schedule the new parameters.
- */
- if (WinDlgBox (HWND_DESKTOP, hwnd, SetParametersDlgProc,
- (HMODULE) 0, IDD_SET_PARAMS, NULL) )
- ScheduleNewParms (hwnd);
-
- return 0 ;
-
- case IDM_SET_OPTIONS:
- /*
- * send up the Set Options box.
- * On OK return, schedule the new parameters.
- */
- if (WinDlgBox (HWND_DESKTOP, hwnd, SetOptionsDlgProc,
- (HMODULE) 0, IDD_SET_OPTIONS, NULL) )
- ScheduleNewParms (hwnd);
-
- return 0 ;
-
- case IDM_SET_IMAGE:
- /*
- * send up the Set Image box.
- * On OK return, schedule the new parameters.
- */
- if (WinDlgBox (HWND_DESKTOP, hwnd, SetImageDlgProc,
- (HMODULE) 0, IDD_SET_IMAGE, NULL) )
- ScheduleNewParms (hwnd);
-
- return 0 ;
-
- case IDM_SET_PALETTE:
- /*
- * send up the Set Palette box.
- * Return is not checked because effects are immediate
- */
- WinDlgBox (HWND_DESKTOP, hwnd, SetPaletteDlgProc,
- (HMODULE) 0, IDD_SET_PALETTE, NULL) ;
-
- return 0 ;
-
- case IDM_ZIN_PICK:
- case IDM_ZOUT_PICK:
- /*
- * Send up the Zoom Value dialog box.
- * On OK return, schedule the new parameters.
- */
- if ( WinDlgBox (HWND_DESKTOP, hwnd, ZoomValueDlgProc,
- (HMODULE) 0, IDD_NUMBER_PICK,
- MPFROMP((PVOID) &COMMANDMSG(&msg)->cmd)) )
- ScheduleNewParms (hwnd);
-
- return 0 ;
-
- case IDM_ZIN_2:
- case IDM_ZIN_5:
- case IDM_ZIN_10:
- /*
- * Zoom in by fixed value.
- * Schedule the new parameters.
- */
- InitNewParms(NULL);
- CalcZoomValues(&npNewParms,
- (double) (sCommand), TRUE );
- npNewParms.fNewParms = TRUE;
- ScheduleNewParms(hwnd);
-
- return 0;
-
- case IDM_ZOUT_2:
- case IDM_ZOUT_5:
- case IDM_ZOUT_10:
- /*
- * Zoom out by fixed value.
- * Schedule the new parameters.
- */
- InitNewParms(NULL);
- CalcZoomValues(&npNewParms,
- (double) (sCommand - 10), FALSE );
- npNewParms.fNewParms = TRUE;
- ScheduleNewParms(hwnd);
-
- return 0;
-
- case IDM_SET_EXTENTS:
- /*
- * Send up the Set Extents dialog box.
- * On OK return, schedule the new parameters.
- */
- if ( WinDlgBox (HWND_DESKTOP, hwnd, SetExtentsDlgProc,
- (HMODULE) 0, IDD_SET_EXTENTS, NULL) )
- ScheduleNewParms (hwnd);
-
- return 0;
-
- case IDM_SET_SWAP:
- /* swap Mandel for Julia or vice versa.
- Handle it as a parm change */
- InitNewParms(NULL);
- if (fractalspecific[npNewParms.iFractType].tojulia != NOFRACTAL
- && npNewParms.param[0] == 0.0
- && npNewParms.param[1] == 0.0)
- {
- /* switch to corresponding Julia set */
- npNewParms.iFractType =
- fractalspecific[npNewParms.iFractType].tojulia;
- npNewParms.param[0] = npNewParms.XCenter;
- npNewParms.param[1] = npNewParms.YCenter;
-
- npNewParms.mxXL = fractalspecific[npNewParms.iFractType].xmin;
- npNewParms.mxXR = fractalspecific[npNewParms.iFractType].xmax;
- npNewParms.mxYB = fractalspecific[npNewParms.iFractType].ymin;
- npNewParms.mxYT = fractalspecific[npNewParms.iFractType].ymax;
-
- }
-
- else if (fractalspecific[npNewParms.iFractType].tomandel != NOFRACTAL)
- {
- /* switch to corresponding Mandel set */
- npNewParms.iFractType =
- fractalspecific[npNewParms.iFractType].tomandel;
- npNewParms.param[0] = 0.0;
- npNewParms.param[1] = 0.0;
- npNewParms.mxXL = fractalspecific[npNewParms.iFractType].xmin;
- npNewParms.mxXR = fractalspecific[npNewParms.iFractType].xmax;
- npNewParms.mxYB = fractalspecific[npNewParms.iFractType].ymin;
- npNewParms.mxYT = fractalspecific[npNewParms.iFractType].ymax;
- }
-
- npNewParms.fNewParms = TRUE;
- ScheduleNewParms (hwnd);
- return 0;
-
- case IDM_SET_RESET:
- /* copy the work copy of the parms back from the
- set used by the calculation engine.
- This resets any dicking around done with the
- dialogs.
- Note: this is only active during FREEZE mode.
- */
-
- CopyParmsToNew();
-
- return 0;
-
- case IDM_HELP_INTRO:
- /* basic Introductory Help */
- SimpleHelp(hab, hwnd, szTitleBar,
- (HMODULE) 0, IDT_TEXT, IDT_HELP_INTRO);
- return 0;
-
- case IDM_HELP_FRACTTYPE:
- /* Fractal list Help */
- SimpleHelp(hab, hwnd, szTitleBar,
- (HMODULE) 0, IDT_TEXT, IDT_HELP_TYPES);
- return 0;
-
- case IDM_HELP_OPERATE:
- /* Menu Help */
- SimpleHelp(hab, hwnd, szTitleBar,
- (HMODULE) 0, IDT_TEXT, IDT_HELP_OPERATE);
- return 0;
-
- case IDM_PRINT_FILE:
- /* Send up the Print Where Dialog.
- On OK return, fire up the subtask */
- if ( WinDlgBox(HWND_DESKTOP, hwnd, PrintOptionsDlgProc,
- (HMODULE) 0, IDD_PRINT, NULL) )
- {
- /* fire up the subtask */
- cp.sSubAction = SUB_ACT_PRINT; /* we want a Print */
-
- cp.fContinueCalc = TRUE;
- DosSemClear (&cp.ulSemTrigger) ; /* release the subthread */
-
- sStatus = STATUS_WORKING ;
- UpdateMenuText (hwnd, IDM_FREEZE_HALT, szHalt);
- EnableMenuItem (hwnd, IDM_GO, FALSE) ;
- EnableMenuItem (hwnd, IDM_FREEZE_HALT, TRUE) ;
- cp.fSuppressPaint = TRUE;
- WinInvalidateRect(hwnd, NULL, FALSE);
- }
-
- return 0 ;
-
- case IDM_READ_FILE:
- /* Send up the Load/Save Format Dialog to find
- out the format we will read.
- Then send up the generic Open File dialog.
- On OK return, fire up the subtask */
- {
- DLF dlf;
- HFILE hfDummy;
- PSZ pszExt;
-
- if ( WinDlgBox(HWND_DESKTOP, hwnd, LoadSaveFmtDlgProc,
- (HMODULE) 0, IDD_LOADSAVE_TYPE, szLoadWhatFmt) )
- {
-
- FileFmtExt (&pszExt);
-
- SetupDLF (&dlf, DLG_OPENDLG, &hfDummy,
- pszExt, szTitleBar,
- szOpenTitle, szOpenHelp);
-
- if (TDF_OLDOPEN == DlgFile(hwnd, &dlf) )
- {
- /* close the dummy file handle */
- DosClose(hfDummy);
- /* fire up the subtask */
- cp.sSubAction = SUB_ACT_LOAD; /* we want a Load */
- cp.sSubFunction = cp.sLastLoadSaveType;
- _fstrcpy(cp.szFileName, dlf.szOpenFile);
-
- cp.fContinueCalc = TRUE;
- DosSemClear (&cp.ulSemTrigger) ; /* release the subthread */
-
- sStatus = STATUS_WORKING ;
- UpdateMenuText (hwnd, IDM_FREEZE_HALT, szHalt);
- EnableMenuItem (hwnd, IDM_GO, FALSE) ;
- EnableMenuItem (hwnd, IDM_FREEZE_HALT, TRUE) ;
- cp.fSuppressPaint = TRUE;
- WinInvalidateRect(hwnd, NULL, FALSE);
- }
- }
-
- return 0 ;
- }
-
- case IDM_SAVE_FILE:
- /* Send up the Load/Save Format Dialog to find
- out the format we will be writing.
- Then send up the generic Save File dialog.
- On OK return, fire up the subtask */
- {
- DLF dlf;
- HFILE hfDummy;
- PSZ pszExt;
-
- if ( WinDlgBox(HWND_DESKTOP, hwnd, LoadSaveFmtDlgProc,
- (HMODULE) 0, IDD_LOADSAVE_TYPE, szSaveWhatFmt) )
- {
-
- FileFmtExt (&pszExt);
-
- SetupDLF (&dlf, DLG_SAVEDLG, &hfDummy,
- pszExt, szTitleBar,
- szOpenTitle, szOpenHelp);
- _fstrcpy(dlf.szOpenFile, cp.szFileName);
-
- if (TDF_NOSAVE != DlgFile(hwnd, &dlf) )
- {
- /* close the dummy file handle */
- DosClose(hfDummy);
- /* and delete the dummy file */
- DosDelete(dlf.szOpenFile, 0);
- /* fire up the subtask */
- cp.sSubAction = SUB_ACT_SAVE; /* we want a Save */
- cp.sSubFunction = cp.sLastLoadSaveType;
- _fstrcpy(cp.szFileName, dlf.szOpenFile);
-
- cp.fContinueCalc = TRUE;
- DosSemClear (&cp.ulSemTrigger) ; /* release the subthread */
-
- sStatus = STATUS_WORKING ;
- UpdateMenuText (hwnd, IDM_FREEZE_HALT, szHalt);
- EnableMenuItem (hwnd, IDM_GO, FALSE) ;
- EnableMenuItem (hwnd, IDM_FREEZE_HALT, TRUE) ;
- cp.fSuppressPaint = TRUE;
- WinInvalidateRect(hwnd, NULL, FALSE);
- }
- }
-
- return 0 ;
- }
-
- case IDM_READ_COLORMAP:
- /* Send up the generic Open File dialog.
- On OK return, read in the file via subroutine. */
- {
- DLF dlf;
- HFILE hfDummy;
-
- SetupDLF (&dlf, DLG_OPENDLG, &hfDummy,
- "\\*.map", szTitleBar,
- szColorMapTitle, szColorMapHelp);
-
- if (TDF_OLDOPEN == DlgFile(hwnd, &dlf) )
- {
- /* close the dummy file handle */
- DosClose(hfDummy);
- /* throw up the hour-glass */
- WinSetCapture(HWND_DESKTOP, hwnd);
- WinSetPointer(HWND_DESKTOP, hptrWait);
- /* read it in */
- LoadColorMap(dlf.szOpenFile);
- /* now clean up */
- WinSetPointer(HWND_DESKTOP, hptrArrow);
- WinSetCapture(HWND_DESKTOP, (HWND) NULL);
- }
- }
-
- return 0;
-
- case IDM_WRITE_COLORMAP:
- /* Send up the generic Save File dialog.
- On OK return, write the file via subroutine */
- {
- DLF dlf;
- HFILE hfDummy;
-
- SetupDLF (&dlf, DLG_SAVEDLG, &hfDummy,
- "\\*.map", szTitleBar,
- szColorMapTitle, szColorMapHelp);
-
- if (TDF_NOSAVE != DlgFile(hwnd, &dlf) )
- {
- /* close the dummy file handle */
- DosClose(hfDummy);
- /* throw up the hour-glass */
- WinSetCapture(HWND_DESKTOP, hwnd);
- WinSetPointer(HWND_DESKTOP, hptrWait);
- /* write it out */
- SaveColorMap(dlf.szOpenFile);
- /* now clean up */
- WinSetPointer(HWND_DESKTOP, hptrArrow);
- WinSetCapture(HWND_DESKTOP, (HWND) NULL);
- }
- }
-
- return 0;
-
- case IDM_CLEAR_CLPB:
- /* clear the current contents of the clipboard */
- WinOpenClipbrd (hab);
- WinEmptyClipbrd (hab);
- WinCloseClipbrd (hab);
-
- return 0;
-
- case IDM_PASTE:
- { /* paste from the clipboard into us */
- USHORT usClipBrdInfo;
-
- if ( WinQueryClipbrdFmtInfo(hab, CF_BITMAP, &usClipBrdInfo) )
- { /* we have a bitmap to fetch */
- /* draw the curtain over the display */
- cp.fSuppressPaint = TRUE;
- WinInvalidateRect(hwnd, NULL, FALSE);
- WinUpdateWindow(hwnd);
- /* throw up the hour-glass */
- WinSetCapture(HWND_DESKTOP, hwnd);
- WinSetPointer(HWND_DESKTOP, hptrWait);
- /* fetch the bitmap */
- PMfrFetchClipbrdBmp(hab);
- /* now clean up */
- WinSetPointer(HWND_DESKTOP, hptrArrow);
- WinSetCapture(HWND_DESKTOP, (HWND) NULL);
- /* and schedule redrawing the window */
- SetSwitchEntry (hwnd, szTitleBar,
- GetFractalName(cp.iFractType) );
- cp.fSuppressPaint = FALSE;
- WinInvalidateRect(hwnd, NULL, FALSE);
- }
- }
-
- return 0;
-
- case IDM_COPY_BMP:
- { /* copy to the clipboard from us */
-
- /* throw up the hour-glass */
- WinSetCapture(HWND_DESKTOP, hwnd);
- WinSetPointer(HWND_DESKTOP, hptrWait);
- /* write the bitmap */
- PMfrWriteClipbrdBmp(hab);
- /* now clean up */
- WinSetPointer(HWND_DESKTOP, hptrArrow);
- WinSetCapture(HWND_DESKTOP, (HWND) NULL);
-
- }
-
- return 0;
-
- }
-
- return 0;
-
- }
-
- /* --------------------------------------------------------------------- */
-
- /*
- Helper functions for reading and writing color palette files.
- */
-
- VOID LoadColorMap(PSZ szFileName)
- {
-
- FILE *file;
- char tempname[128];
- char line[128];
- SHORT i;
- RGB _far *prgb;
- BYTE r, g, b;
-
- _fstrcpy(tempname, szFileName);
-
- prgb = &bmiColorTableUser.argbColor[0];
-
- file = fopen(tempname, "r" );
-
- if (file == NULL)
- return;
-
- for( i = 0; i < 256; i++ )
- {
- if (fgets(line,100,file) == NULL)
- break;
-
- sscanf( line, "%d %d %d", /* R G B */
- &r, &g, &b);
- prgb[i].bRed = r;
- prgb[i].bGreen = g;
- prgb[i].bBlue = b;
- }
-
- fclose(file);
-
- /* now effect a switch to the new palette */
- cp.pbmiMemory = &bmiColorTableUser;
- cp.sCurrentPalette = IDD_PAL_USER;
- cp.fNewBits = TRUE;
- cp.fHaveUserPalette = TRUE;
- WinInvalidateRect(cp.hwnd, NULL, FALSE);
-
- }
-
- VOID SaveColorMap(PSZ szFileName)
- {
-
- FILE *file;
- char tempname[128];
- SHORT i;
- RGB _far *prgb;
- BYTE r, g, b;
-
- _fstrcpy(tempname, szFileName);
-
- file = fopen(tempname,"w");
- if (file == NULL)
- return;
-
- prgb = &cp.pbmiMemory->argbColor[0];
-
- fprintf(file," 0 0 0\n");
-
- for (i = 1; i < 256; i++)
- {
- r = prgb[i].bRed;
- g = prgb[i].bGreen;
- b = prgb[i].bBlue;
- fprintf(file, "%3d %3d %3d\n", /* R G B */
- r, g, b);
- }
-
- fclose(file);
-
- }
-
- /* --------------------------------------------------------------------- */
-
- /*
- Helper functions for handling user interfact needs like
- zooming and panning.
- */
- VOID InitCrossHairs(VOID)
- {
- ptlCrossHairs.x = -1;
- ptlCrossHairs.y = -1;
- }
-
- VOID DrawCrossHairsInner (HWND hwnd)
- {
- POINTL ptl1;
-
- GpiSetMix (cp.hpsScreen, FM_INVERT) ;
-
- ptl1.x = 0; ptl1.y = ptlCrossHairs.y;
- GpiMove (cp.hpsScreen, &ptl1);
- ptl1.x = cxClient-1;
- GpiLine (cp.hpsScreen, &ptl1);
- ptl1.x = ptlCrossHairs.x; ptl1.y = 0;
- GpiMove (cp.hpsScreen, &ptl1);
- ptl1.y = cyClient-1;
- GpiLine (cp.hpsScreen, &ptl1);
-
- GpiSetMix (cp.hpsScreen, FM_DEFAULT);
- }
-
- VOID DrawCrossHairs (HWND hwnd, PPOINTL pptlMouse)
- {
-
- if (ptlCrossHairs.x != -1)
- DrawCrossHairsInner(hwnd); /* erase old lines */
-
- ptlCrossHairs.x = pptlMouse->x;
- ptlCrossHairs.y = pptlMouse->y;
- DrawCrossHairsInner(hwnd);
-
- }
-
- VOID MoveCrossHairs (HWND hwnd, MPARAM mp1)
- {
- SHORT xMouse = SHORT1FROMMP (mp1);
- SHORT yMouse = SHORT2FROMMP (mp1);
- POINTL ptl1;
-
- /* limit mouse coordinates to window bounds */
- xMouse = min(xMouse, cxClient-1);
- xMouse = max(xMouse, 0);
- yMouse = min(yMouse, cyClient-1);
- yMouse = max(yMouse, 0);
- /* update the cross hairs */
- ptl1.x = (LONG) xMouse;
- ptl1.y = (LONG) yMouse;
- DrawCrossHairs (hwnd, &ptl1);
-
- }
-
- VOID EraseCrossHairs(HWND hwnd)
- {
- DrawCrossHairsInner(hwnd);
- }
-
- VOID InitZoomBox(SHORT x, SHORT y)
- {
- ptlZBox1.x = x;
- ptlZBox1.y = y;
- ptlZBox2.x = -1;
- ptlZBox2.y = -1;
-
- }
-
- VOID DrawZoomBoxInner (HWND hwnd)
- {
-
- GpiSetMix (cp.hpsScreen, FM_INVERT) ;
-
- GpiMove (cp.hpsScreen, &ptlZBox1);
- GpiBox (cp.hpsScreen, DRO_OUTLINE, &ptlZBox2, 0L, 0L);
-
- GpiSetMix (cp.hpsScreen, FM_DEFAULT);
- }
-
- VOID DrawZoomBox (HWND hwnd, PPOINTL pptlMouse)
- {
-
- if (ptlZBox2.x != -1)
- DrawZoomBoxInner(hwnd); /* erase old box */
-
- ptlZBox2.x = pptlMouse->x;
- ptlZBox2.y = pptlMouse->y;
- DrawZoomBoxInner(hwnd);
-
- }
-
- VOID MoveZoomBox (HWND hwnd, MPARAM mp1)
- {
- SHORT xMouse = SHORT1FROMMP (mp1);
- SHORT yMouse = SHORT2FROMMP (mp1);
- POINTL ptl1;
-
- /* limit mouse coordinates to window bounds */
- xMouse = min(xMouse, cxClient-1);
- xMouse = max(xMouse, 0);
- yMouse = min(yMouse, cyClient-1);
- yMouse = max(yMouse, 0);
- /* update the Zoom Box */
- ptl1.x = (LONG) xMouse;
- ptl1.y = (LONG) yMouse;
- DrawZoomBox (hwnd, &ptl1);
-
- }
-
- VOID EraseZoomBox (HWND hwnd)
- {
- DrawZoomBoxInner (hwnd);
-
- }
-
- /*------------------------------------------------
- We did a pan. Find out where we are now
- and schedule the parameter change.
- ------------------------------------------------*/
- VOID PanNewCenter(HWND hwnd)
- {
- double dTemp, dDelta;
-
- /* process the parms change */
- InitNewParms(NULL);
- dTemp = npNewParms.XL + (npNewParms.XR - npNewParms.XL) *
- ( ((double) ptlCrossHairs.x) / ((double) (cxClient-1)) );
- dDelta = dTemp - npNewParms.XCenter;
- npNewParms.XCenter = dTemp;
- if (dDelta < 0.0)
- { /* shift left - check left edge first for out of bounds */
- dTemp = npNewParms.XL + dDelta; /* new assumed left edge */
- npNewParms.XL = max(dTemp, npNewParms.mxXL); /* corrected left edge */
- dDelta = npNewParms.XL - npNewParms.XCenter;
- npNewParms.XR = npNewParms.XCenter - dDelta;
- }
- else
- { /* shift right - check right edge first for out of bounds */
- dTemp = npNewParms.XR + dDelta; /* new assumed right edge */
- npNewParms.XR = min(dTemp, npNewParms.mxXR); /* corrected right edge */
- dDelta = npNewParms.XR - npNewParms.XCenter;
- npNewParms.XL = npNewParms.XCenter - dDelta;
- }
- dTemp = npNewParms.YB + (npNewParms.YT - npNewParms.YB) *
- ( ((double) ptlCrossHairs.y) / ((double) (cyClient-1)) ) ;
- dDelta = dTemp - npNewParms.YCenter;
- npNewParms.YCenter = dTemp;
- if (dDelta < 0.0)
- { /* shift down - check bottom edge first for out of bounds */
- dTemp = npNewParms.YB + dDelta; /* new assumed bottom edge */
- npNewParms.YB = max(dTemp, npNewParms.mxYB); /* corrected bottom edge */
- dDelta = npNewParms.YB - npNewParms.YCenter;
- npNewParms.YT = npNewParms.YCenter - dDelta;
- }
- else
- { /* shift up - check top edge first for out of bounds */
- dTemp = npNewParms.YT + dDelta; /* new assumed top edge */
- npNewParms.YT = min(dTemp, npNewParms.mxYT); /* corrected top edge */
- dDelta = npNewParms.YT - npNewParms.YCenter;
- npNewParms.YB = npNewParms.YCenter - dDelta;
- }
- npNewParms.fNewParms = TRUE;
- ScheduleNewParms(hwnd);
-
- }
-
- /*----------------------------------------------
- We did a zoom window. Find out where we are
- now and schdedule the parameter change.
- ----------------------------------------------*/
- VOID ZoomNewWindow (HWND hwnd, BOOL InOrOut)
- {
- NEWPARAM npTempParms;
- double dTemp, dDXOld, dDXNew, dDYOld, dDYNew;
- LONG lDXOld, lDYOld;
-
- /* process the parms change */
- InitNewParms(&npTempParms);
-
- if (InOrOut)
- { /* TRUE == Zoom In */
- /* left edge */
- dTemp = (double) min(ptlZBox1.x, ptlZBox2.x);
- npNewParms.XL = npTempParms.XL + (npTempParms.XR - npTempParms.XL) *
- ( dTemp / ((double) (cxClient-1)) );
- /* right edge */
- dTemp = (double) max(ptlZBox1.x, ptlZBox2.x);
- npNewParms.XR = npTempParms.XL + (npTempParms.XR - npTempParms.XL) *
- ( dTemp / ((double) (cxClient-1)) );
- /* top edge */
- dTemp = (double) max(ptlZBox1.y, ptlZBox2.y);
- npNewParms.YT = npTempParms.YB + (npTempParms.YT - npTempParms.YB) *
- ( dTemp / ((double) (cyClient-1)) );
- /* bottom edge */
- dTemp = (double) min(ptlZBox1.y, ptlZBox2.y);
- npNewParms.YB = npTempParms.YB + (npTempParms.YT - npTempParms.YB) *
- ( dTemp / ((double) (cyClient-1)) );
- }
- else
- { /* FALSE == Zoom Out */
-
- /* lDXOld is the new zoom box dimensions, representing the old
- screen complex range */
-
- lDXOld = labs(ptlZBox2.x - ptlZBox1.x);
- lDYOld = labs(ptlZBox2.y - ptlZBox1.y);
- dDXOld = npTempParms.XR - npTempParms.XL;
- dDYOld = npTempParms.YT - npTempParms.YB;
-
- dDXNew = dDXOld * ((double) cxClient)/((double) lDXOld);
- dDYNew = dDYOld * ((double) cyClient)/((double) lDYOld);
-
- /* calculate a new center point */
- npNewParms.XCenter = npTempParms.XL +
- ( (double) ((ptlZBox1.x + ptlZBox2.x)/2L) / (double) cxClient )
- * dDXOld ;
- npNewParms.YCenter = npTempParms.YB +
- ( (double) ((ptlZBox1.y + ptlZBox2.y)/2L) / (double) cyClient )
- * dDYOld ;
-
- /* left edge */
- npNewParms.XL = npNewParms.XCenter - dDXNew / 2.0e0L;
-
- /* right edge */
- npNewParms.XR = npNewParms.XCenter + dDXNew / 2.0e0L;
-
- /* top edge */
- npNewParms.YT = npNewParms.YCenter + dDYNew / 2.0e0L;
-
- /* bottom edge */
- npNewParms.YB = npNewParms.YCenter - dDYNew / 2.0e0L;
-
- /* now clip to the max size */
- npNewParms.XL = max(npNewParms.XL, npNewParms.mxXL);
- npNewParms.XR = min(npNewParms.XR, npNewParms.mxXR);
- npNewParms.YT = min(npNewParms.YT, npNewParms.mxYT);
- npNewParms.YB = max(npNewParms.YB, npNewParms.mxYB);
- }
-
- /* always recalculate a valid center point */
- npNewParms.XCenter = (npNewParms.XL + npNewParms.XR)/2.0;
- npNewParms.YCenter = (npNewParms.YT + npNewParms.YB)/2.0;
-
- npNewParms.fNewParms = TRUE;
- ScheduleNewParms(hwnd);
- }
-
- /*-----------------------------------------------
- Back us out of zoom or pan mode.
- Called for a variety of reasons from the
- main window function.
- -----------------------------------------------*/
- VOID CancelZoomOrPan (HWND hwnd)
- {
- if (fPan) /* Panning */
- {
- /* erase the cross hairs */
- EraseCrossHairs(hwnd);
- WinSetCapture (HWND_DESKTOP, (HWND) NULL);
- WinShowPointer (HWND_DESKTOP, TRUE); /* reshow normal mouse pointer */
- fPan = FALSE;
- fGoodPan = FALSE;
- fZoomWin = FALSE;
- }
-
- if (fZoomWin) /* Zooming */
- {
- /* erase the Zoom Box */
- EraseZoomBox(hwnd);
- WinSetCapture (HWND_DESKTOP, (HWND) NULL);
- WinShowPointer (HWND_DESKTOP, TRUE); /* reshow normal mouse pointer */
- fZoomWin = FALSE;
- fGoodZoom = FALSE;
- fPan = FALSE;
- }
- }
-
- /*---------------------------------------------
- Helper subroutines to work over menu items.
- ---------------------------------------------*/
- VOID EnableMenuItem (HWND hwnd, SHORT sMenuItem, BOOL fEnable)
- {
- HWND hwndParent = WinQueryWindow (hwnd, QW_PARENT, FALSE) ;
- HWND hwndMenu = WinWindowFromID (hwndParent, FID_MENU) ;
-
- WinSendMsg (hwndMenu, MM_SETITEMATTR,
- MPFROM2SHORT (sMenuItem, TRUE),
- MPFROM2SHORT (MIA_DISABLED, fEnable ? 0 : MIA_DISABLED)) ;
- }
-
- VOID UpdateMenuText (HWND hwnd, SHORT sMenuItem, PSZ szNewText)
- {
- HWND hwndParent = WinQueryWindow (hwnd, QW_PARENT, FALSE);
- HWND hwndMenu = WinWindowFromID (hwndParent, FID_MENU);
-
- WinSendMsg (hwndMenu, MM_SETITEMTEXT,
- MPFROMSHORT ( sMenuItem ),
- MPFROMP ( szNewText) ) ;
- }
-
- BOOL UpdateMenuStatus (HWND hwnd, SHORT sMenuID)
- {
-
- /*
- * UpdateMenuStatus tests for and keeps updated the
- * state of the GO button on the main menu bar.
- * Also the selectability and text of the
- * Swap between Mandel/Julia selection on the Set menu.
- * Also other menu items.
- */
-
- int iWhatFractal;
- double ccreal, ccimag;
- USHORT usClipBrdInfo;
-
- switch (sMenuID)
- {
- case ID_RESOURCE:
-
- if (tidCalc == -1)
- EnableMenuItem (hwnd, IDM_GO, FALSE) ;
- return TRUE;
-
- case IDM_OPTIONS_MENU:
-
- /* keep Mandel/Julia status up to date */
- /* keep Reset status up to date */
-
- if (sStatus == STATUS_FROZEN)
- {
- iWhatFractal = npNewParms.iFractType;
- ccreal = npNewParms.param[0];
- ccimag = npNewParms.param[1];
- }
- else
- {
- iWhatFractal = cp.iFractType;
- ccreal = cp.param[0];
- ccimag = cp.param[1];
- }
-
- if (fractalspecific[iWhatFractal].tojulia != NOFRACTAL
- && ccreal == 0.0 && ccimag == 0.0)
- { /* to julia is kosher */
- UpdateMenuText (hwnd, IDM_SET_SWAP, szSwapJulia);
- EnableMenuItem (hwnd, IDM_SET_SWAP, TRUE);
- }
- else
- if (fractalspecific[iWhatFractal].tomandel != NOFRACTAL)
- { /* to mandel is kosher */
- UpdateMenuText (hwnd, IDM_SET_SWAP, szSwapMandel);
- EnableMenuItem (hwnd, IDM_SET_SWAP, TRUE);
- }
- else
- { /* this is a stand-alone fractal, swap disabled */
- UpdateMenuText (hwnd, IDM_SET_SWAP, szSwapMandel);
- EnableMenuItem (hwnd, IDM_SET_SWAP, FALSE);
- }
-
- EnableMenuItem (hwnd, IDM_SET_RESET,
- sStatus == STATUS_FROZEN );
- EnableMenuItem (hwnd, IDM_SET_EXTENTS,
- (sStatus != STATUS_NEWPARMS) &&
- (sStatus != STATUS_INIT) );
- EnableMenuItem (hwnd, IDM_SET_PARAMS,
- (sStatus != STATUS_NEWPARMS) &&
- (sStatus != STATUS_INIT) );
- EnableMenuItem (hwnd, IDM_SET_OPTIONS,
- (sStatus != STATUS_NEWPARMS) &&
- (sStatus != STATUS_INIT) );
- EnableMenuItem (hwnd, IDM_SET_IMAGE,
- (sStatus != STATUS_NEWPARMS) &&
- (sStatus != STATUS_INIT) );
- EnableMenuItem (hwnd, IDM_SET_PALETTE,
- (sStatus != STATUS_NEWPARMS) &&
- (sStatus != STATUS_INIT) );
-
- return TRUE;
-
- case IDM_EDIT_MENU:
-
- EnableMenuItem (hwnd, IDM_COPY_BMP,
- sStatus == STATUS_READY);
- EnableMenuItem (hwnd, IDM_COPY_MET,
- sStatus == STATUS_READY);
- EnableMenuItem (hwnd, IDM_PASTE,
- ( sStatus == STATUS_READY ) &&
- ( WinQueryClipbrdFmtInfo(hab, CF_BITMAP, &usClipBrdInfo)
- /* || WinQueryClipbrdFmtInfo(hab, CF_METAFILE, &usClipBrdInfo) */
- ) ) ;
- EnableMenuItem (hwnd, IDM_CLPB_TEXT,
- WinQueryClipbrdFmtInfo(hab, CF_TEXT, &usClipBrdInfo) );
- EnableMenuItem (hwnd, IDM_CLPB_BMP,
- WinQueryClipbrdFmtInfo(hab, CF_BITMAP, &usClipBrdInfo) );
- EnableMenuItem (hwnd, IDM_CLPB_MET,
- WinQueryClipbrdFmtInfo(hab, CF_METAFILE, &usClipBrdInfo) );
-
- return TRUE;
-
- case IDM_FILE_MENU:
-
- EnableMenuItem (hwnd, IDM_NEW_FRACTAL,
- (sStatus != STATUS_NEWPARMS) &&
- (sStatus != STATUS_INIT) );
- EnableMenuItem (hwnd, IDM_PRINT_FILE,
- sStatus == STATUS_READY);
- EnableMenuItem (hwnd, IDM_SAVE_FILE,
- sStatus == STATUS_READY);
- EnableMenuItem (hwnd, IDM_READ_FILE,
- sStatus == STATUS_READY);
- EnableMenuItem (hwnd, IDM_READ_COLORMAP,
- sStatus != STATUS_INIT);
- EnableMenuItem (hwnd, IDM_WRITE_COLORMAP,
- sStatus != STATUS_INIT);
-
- return TRUE;
-
- case IDM_VIEW_MENU:
-
- EnableMenuItem (hwnd, IDM_ZIN_WIN, fGoodZoom);
- EnableMenuItem (hwnd, IDM_ZOUT_WIN, fGoodZoom);
- EnableMenuItem (hwnd, IDM_PAN,
- fGoodPan && (sStatus != STATUS_NEWPARMS) &&
- (sStatus != STATUS_INIT) );
- EnableMenuItem (hwnd, IDM_ZIN_MENU,
- (sStatus != STATUS_NEWPARMS) &&
- (sStatus != STATUS_INIT) );
- EnableMenuItem (hwnd, IDM_ZOUT_MENU,
- (sStatus != STATUS_NEWPARMS) &&
- (sStatus != STATUS_INIT) );
-
- return TRUE;
-
- default:
- break;
-
- }
-
- return FALSE;
-
- }
-
- /*-----------------------------------------------
- Helper function to keep the title bar and the
- switch entry up to date.
- -----------------------------------------------*/
- VOID SetSwitchEntry(HWND hwnd, PSZ szTitleBar, PSZ szFract)
- {
- PID pid;
- static SWCNTRL swcntrl;
- static HSWITCH hswitch = NULL;
- HWND hwndFrame;
-
- hwndFrame = WinQueryWindow (hwnd, QW_PARENT, FALSE);
-
- if (hswitch == (HSWITCH) NULL) { /* if first time */
-
- /* get our process ID for the Switch structure */
- WinQueryWindowProcess(hwndFrame, &pid, NULL);
-
- /* add/change switch list entry */
- swcntrl.hwnd = hwndFrame;
- swcntrl.hwndIcon = (HWND) NULL;
- swcntrl.hprog = (HPROGRAM) NULL;
- swcntrl.idProcess = pid;
- swcntrl.idSession = 0;
- swcntrl.uchVisibility = SWL_VISIBLE;
- swcntrl.fbJump = SWL_JUMPABLE;
- _fstrcpy( swcntrl.szSwtitle, szTitleBar);
- strcat( swcntrl.szSwtitle, " - ");
- _fstrcat( swcntrl.szSwtitle, szFract);
- swcntrl.fReserved = '\0';
-
- hswitch = WinAddSwitchEntry( &swcntrl );
- }
- else { /* do an update */
- _fstrcpy( swcntrl.szSwtitle, szTitleBar);
- strcat( swcntrl.szSwtitle, " - ");
- _fstrcat( swcntrl.szSwtitle, szFract);
-
- WinChangeSwitchEntry( hswitch, &swcntrl);
- }
-
- /* now put it in the titlebar also */
- WinSetWindowText(hwndFrame, swcntrl.szSwtitle);
-
- }
-
- /*--------------------------------------------------
- Subfunction for all dialog boxes.
-
- Arrange for the dialog box to be centered on the
- screen.
- --------------------------------------------------*/
- VOID CenterDialogBox (HWND hwnd)
- {
- SWP swpMe;
- SHORT xNew, yNew;
-
- WinQueryWindowPos(hwnd, &swpMe);
-
- xNew = ((SHORT) cxScreen - swpMe.cx) / 2;
- yNew = ((SHORT) cyScreen - swpMe.cy) / 2;
-
- WinSetWindowPos(hwnd, HWND_TOP, xNew, yNew, 0, 0,
- SWP_MOVE);
- }
-
- /* --------------------------------------------------------------------- */
-
- /*
- Helper function for specifying file load/save extension.
- */
-
- VOID FileFmtExt (PSZ far *ppszFmt)
- {
-
- switch (cp.sLastLoadSaveType)
- {
- case SUB_LOADSAVE_GIF:
- *ppszFmt = szExtGIF;
- break;
-
- case SUB_LOADSAVE_BMP:
- *ppszFmt = szExtBMP;
- break;
-
- case SUB_LOADSAVE_MET:
- *ppszFmt = szExtMET;
- break;
-
- case SUB_LOADSAVE_WIN3BMP:
- *ppszFmt = szExtBMP;
- break;
-
- case SUB_LOADSAVE_PCX:
- *ppszFmt = szExtPCX;
- break;
-
- default:
- *ppszFmt = szExtGIF;
- }
-
- }