/* * CMWcommands.c -- * * Commands for the color map editor. * * ********************************************************************* * * Copyright (C) 1985, 1990 Regents of the University of California. * * * Permission to use, copy, modify, and distribute this * * * software and its documentation for any purpose and without * * * fee is hereby granted, provided that the above copyright * * * notice appear in all copies. The University of California * * * makes no representations about the suitability of this * * * software for any purpose. It is provided "as is" without * * * express or implied warranty. Export of this software outside * * * of the United States of America may require an export license. * * ********************************************************************* */ #ifndef lint static char rcsid[] __attribute__ ((unused)) = "$Header: /usr/cvsroot/magic-8.0/cmwind/CMWcmmnds.c,v 1.1.1.1 2008/02/03 20:43:50 tim Exp $"; #endif /* not lint */ #include #include #include "tcltk/tclmagic.h" #include "utils/magic.h" #include "utils/geometry.h" #include "windows/windows.h" #include "tiles/tile.h" #include "utils/hash.h" #include "database/database.h" #include "dbwind/dbwind.h" #include "utils/main.h" #include "commands/commands.h" #include "cmwind/cmwind.h" #include "graphics/graphics.h" #include "textio/textio.h" #include "utils/utils.h" #include "utils/styles.h" #include "textio/txcommands.h" #include "utils/undo.h" /* Forward declarations: */ extern void cmwButtonUp(), cmwButtonDown(); extern void cbUpdate(); extern void RGBxHSV(); extern void HSVxRGB(); /* If a button is pressed over the top box in the window, which * displays the current color, we must save the window in which * it was pressed for use when the button is released. We also * set a flag so we remember to process the button release. */ MagWindow *cmwWindow; bool cmwWatchButtonUp; /* The following variable keeps track of whether or not the color * map has been modified, so that we can warn the user if he attempts * to exit or load a new color map without saving the changes. */ bool cmwModified = FALSE; /* * ---------------------------------------------------------------------------- * * CMWcommand -- * * This procedure is invoked by the window package whenever a * button is pushed or a command is typed while the cursor is * over a colormap window. * * Results: * None. * * Side effects: * A color may be changed, depending on the command. * * ---------------------------------------------------------------------------- */ void CMWcommand(w, cmd) MagWindow *w; TxCommand *cmd; { switch (cmd->tx_button) { case TX_NO_BUTTON: WindExecute(w, CMWclientID, cmd); break; case TX_LEFT_BUTTON: case TX_RIGHT_BUTTON: case TX_MIDDLE_BUTTON: switch (cmd->tx_buttonAction) { case TX_BUTTON_UP: cmwButtonUp(w, &(cmd->tx_p), cmd->tx_button); break; case TX_BUTTON_DOWN: cmwButtonDown(w, &(cmd->tx_p), cmd->tx_button); break; } break; default: ASSERT(FALSE, "CMWcommand"); } UndoNext(); } /* * ---------------------------------------------------------------------------- * * cmwButtonDown -- * * Process the button command to change a color value. * * Results: * None. * * Side effects: * May update a color value. Depends on where the button is * pushed. If a button is pushed over a color bar, then that * bar is updated to fall where the cursor is. If a button * is pushed over a color pump, the value is incremented or * decremented, depending on which pump is hit. If the left * button is pushed then a small increment is made (the value * in the associated pump record). If one of the other buttons * is pushed, an increment 5 times as great is made. * * ---------------------------------------------------------------------------- */ void cmwButtonDown(w, p, button) MagWindow *w; /* Window where the button was pressed. */ Point *p; int button; { ColorBar *cb; ColorPump *cp; Point surfacePoint; int x; double dx; if (w == NULL) return; WindPointToSurface(w, p, &surfacePoint, (Rect *) NULL); /* See if the cursor is over a color bar. */ for (cb = colorBars; cb->cb_name; cb++) { if (GEO_ENCLOSE(&surfacePoint, &cb->cb_rect)) { x = surfacePoint.p_x; x = MAX(x, cb->cb_rect.r_xbot); x = MIN(x, cb->cb_rect.r_xtop); dx = (double) (x - cb->cb_rect.r_xbot) / (double) (cb->cb_rect.r_xtop - cb->cb_rect.r_xbot); cbUpdate(w, cb->cb_code, dx, TRUE); return; } } /* See if the cursor is over a color pump. */ for (cp = colorPumps; cp->cp_code >= 0; cp++) { if (GEO_ENCLOSE(&surfacePoint, &cp->cp_rect)) { if (button == TX_LEFT_BUTTON) cbUpdate(w, cp->cp_code, cp->cp_amount, FALSE); else cbUpdate(w, cp->cp_code, (double) 5*cp->cp_amount, FALSE); return; } } /* Note that the "color picker" function can't work as implemented * because this function is registered only with the color window, * so it cannot be called with a different window "w". So, we can * only disable the button functions when pushed over the "current * color area" rectangle. */ #ifndef MAGIC_WRAPPER /* See if the cursor is over the current color area. If so, remember * the fact and wait for the button to be released. */ if (GEO_ENCLOSE(&surfacePoint, &cmwCurrentColorArea)) { cmwWindow = w; cmwWatchButtonUp = TRUE; if (button == TX_LEFT_BUTTON) TxPrintf("Release button over new color to edit.\n"); else TxPrintf("Release button over color to copy.\n"); } #endif } /* * ---------------------------------------------------------------------------- * * cmwButtonUp -- * * This procedure handles button releases. * * Results: * None. * * Side effects: * The current color, or its value, may be changed. * * ---------------------------------------------------------------------------- */ void cmwButtonUp(w, p, button) MagWindow *w; /* Window where the button was released */ Point *p; /* Point where button was released, in window coords.*/ int button; /* Button that was released. */ { CMWclientRec *crec; int r, g, b, color, oldR, oldG, oldB; extern int cmwRedisplayFunc(); /* If the button wasn't depressed over the top box in the window * (the one displaying the current color), then we ignore the * button release. */ if (!cmwWatchButtonUp) return; cmwWatchButtonUp = FALSE; /* If it's the left button, change the color being edited to the * one at the pixel underneath the cursor. Otherwise, copy the * color values from the pixel underneath the cursor to the current * color. */ /* Read the pixel from the window that was underneath the cursor when * the button was released. */ color = GrReadPixel(w, p->p_x, p->p_y); if (color < 0) { TxError("Couldn't read that pixel!\n"); color = 0; } if (button == TX_LEFT_BUTTON) CMWloadWindow(cmwWindow, color); else { crec = (CMWclientRec *) cmwWindow->w_clientData; (void) GrGetColor(color, &r, &g, &b); (void) GrGetColor(crec->cmw_color, &oldR, &oldG, &oldB); (void) GrPutColor(crec->cmw_color, r, g, b); cmwModified = TRUE; /* Record old values for undo. */ cmwUndoColor(crec->cmw_color, oldR, oldG, oldB, r, g, b); /* Mark all windows containing this color as modified */ (void) WindSearch(CMWclientID, (ClientData) NULL, (Rect *) NULL, cmwRedisplayFunc, (ClientData)(pointertype) crec->cmw_color); } } /* * ---------------------------------------------------------------------------- * * cmwPushbutton -- * * Usage: * pushbutton