/*
* Copyright (c) 2003-2007 Hypertriton, Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
* USE OF THIS SOFTWARE EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include
#include
#include
static int mapFlipSelection = 0;
static void
Init(void *p)
{
MAP_ToolPushStatus(p,
_("Select element and use $(L)=Mirror, $(R)=Flip"));
}
static void
EditPane(void *p, void *con)
{
AG_CheckboxNewInt(con, 0, _("Flip entire selection"),
&mapFlipSelection);
}
static void
ToggleXform(MAP_Item *mi, int type)
{
RG_Transform *xf;
TAILQ_FOREACH(xf, &mi->transforms, transforms) {
if (xf->type == type) {
TAILQ_REMOVE(&mi->transforms, xf, transforms);
return;
}
}
if ((xf = RG_TransformNew(type, 0, NULL)) == NULL) {
AG_TextMsgFromError();
return;
}
TAILQ_INSERT_TAIL(&mi->transforms, xf, transforms);
}
static int
MouseButtonDown(void *p, int xmap, int ymap, int b)
{
MAP_Tool *t = p;
MAP_View *mv = t->mv;
MAP *m = mv->map;
int selx = mv->mx + mv->mouse.x;
int sely = mv->my + mv->mouse.y;
int w = 1;
int h = 1;
int x, y;
if (!mapFlipSelection ||
MAP_ViewGetSelection(mv, &selx, &sely, &w, &h) == -1) {
if (selx < 0 || selx >= (int)m->mapw ||
sely < 0 || sely >= (int)m->maph)
return (0);
}
MAP_ModBegin(m);
for (y = sely; y < sely+h; y++) {
for (x = selx; x < selx+w; x++) {
MAP_Node *node = &m->map[y][x];
MAP_Item *nref;
MAP_ModNodeChg(m, x, y);
TAILQ_FOREACH(nref, &node->nrefs, nrefs) {
if (nref->layer != m->cur_layer)
continue;
if (b == AG_MOUSE_LEFT) {
ToggleXform(nref, RG_TRANSFORM_MIRROR);
} else if (b == AG_MOUSE_RIGHT) {
ToggleXform(nref, RG_TRANSFORM_FLIP);
}
}
}
}
MAP_ModEnd(m);
return (1);
}
static int
Cursor(void *p, AG_Rect *rd)
{
AG_Color c;
AG_ColorRGBA_8(&c, 255,255,0,64);
AG_DrawRectBlended(TOOL(p)->mv, rd, &c, AG_ALPHA_OVERLAY);
return (1);
}
const MAP_ToolOps mapFlipOps = {
"Flip", N_("Flip/mirror node element"),
&mapIconFlip,
sizeof(MAP_Tool),
0,
Init,
NULL, /* destroy */
EditPane,
NULL, /* edit */
Cursor,
NULL, /* effect */
NULL, /* mousemotion */
MouseButtonDown,
NULL, /* mousebuttonup */
NULL, /* keydown */
NULL /* keyup */
};