/* * Copyright (c) 2005-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 #include #include #include const AG_Version rgSketchProjVer = { 0, 0 }; const RG_FeatureOps rgSketchProjOps = { "sketchproj", sizeof(struct rg_sketchproj), N_("Sketch projection."), FEATURE_AUTOREDRAW, RG_SketchProjInit, RG_SketchProjLoad, RG_SketchProjSave, NULL, /* destroy */ RG_SketchProjApply, NULL, NULL, RG_SketchProjEdit }; void RG_SketchProjInit(void *p, RG_Tileset *ts, int flags) { struct rg_sketchproj *sproj = p; RG_FeatureInit(sproj, ts, flags, &rgSketchProjOps); sproj->alpha = 255; sproj->color = AG_MapPixelRGB(ts->fmt, 0,0,0); sproj->sketch[0] = '\0'; } int RG_SketchProjLoad(void *p, AG_DataSource *buf) { struct rg_sketchproj *sproj = p; RG_Tileset *ts = RG_FEATURE(sproj)->ts; if (AG_ReadVersion(buf, "RG_Feature:RG_SketchProj", &rgSketchProjVer, NULL) == -1) return (-1); AG_CopyString(sproj->sketch, buf, sizeof(sproj->sketch)); sproj->alpha = AG_ReadUint8(buf); sproj->color = AG_ReadColor(buf, ts->fmt); return (0); } void RG_SketchProjSave(void *p, AG_DataSource *buf) { struct rg_sketchproj *sproj = p; RG_Tileset *ts = RG_FEATURE(sproj)->ts; AG_WriteVersion(buf, "RG_Feature:RG_SketchProj", &rgSketchProjVer); AG_WriteString(buf, sproj->sketch); AG_WriteUint8(buf, sproj->alpha); AG_WriteColor(buf, ts->fmt, sproj->color); } static void PollSketches(AG_Event *_Nonnull event) { AG_Tlist *tl = AG_SELF(); RG_Tile *t = AG_PTR(1); RG_Tileset *ts = t->ts; RG_TileElement *tel; AG_TlistItem *it; AG_TlistClear(tl); AG_MutexLock(&ts->lock); TAILQ_FOREACH(tel, &t->elements, elements) { if (tel->type != RG_TILE_SKETCH) { continue; } it = AG_TlistAddS(tl, NULL, tel->name); it->p1 = tel; it->cat = "tile-sketch"; AG_TlistSetIcon(tl, it, tel->tel_sketch.sk->vg->su); } AG_MutexUnlock(&ts->lock); AG_TlistRestore(tl); } static void SelectSketch(AG_Event *_Nonnull event) { struct rg_sketchproj *sproj = AG_PTR(1); AG_TlistItem *it = AG_PTR(3); Strlcpy(sproj->sketch, it->text, sizeof(sproj->sketch)); } AG_Window * RG_SketchProjEdit(void *p, RG_Tileview *tv) { struct rg_sketchproj *sproj = p; AG_Window *win; AG_Box *box; AG_Combo *comSK; win = AG_WindowNew(0); AG_WindowSetCaptionS(win, _("Polygon")); comSK = AG_ComboNew(win, AG_COMBO_POLL|AG_COMBO_HFILL, _("Sketch: ")); AG_SetEvent(comSK->list, "tlist-poll", PollSketches, "%p", tv->tile); AG_SetEvent(comSK, "combo-selected", SelectSketch, "%p,%p", sproj, tv->tile); AG_ComboSelectText(comSK, sproj->sketch); box = AG_BoxNew(win, AG_BOX_VERT, AG_BOX_HFILL|AG_BOX_VFILL); { AG_HSVPal *hsv1; AG_Numerical *num; AG_Notebook *nb; AG_NotebookTab *ntab; nb = AG_NotebookNew(box, AG_NOTEBOOK_HFILL|AG_NOTEBOOK_VFILL); ntab = AG_NotebookAdd(nb, _("Color"), AG_BOX_VERT); { hsv1 = AG_HSVPalNew(ntab, AG_HSVPAL_EXPAND); AG_BindPointer(hsv1, "pixel-format", &tv->ts->fmt); AG_BindUint32(hsv1, "pixel", &sproj->color); } num = AG_NumericalNewUint8(box, 0, NULL, _("Alpha: "), &sproj->alpha); AG_NumericalSetRange(num, 0, 255); AG_NumericalSetIncrement(num, 5); } AG_WidgetFocus(comSK); return (win); } void RG_SketchProjApply(void *p, RG_Tile *t, int fx, int fy) { struct rg_sketchproj *sproj = p; float x1, y1, x2, y2; VG *vg; VG_Element *vge; RG_TileElement *ske; RG_Sketch *sk; int i; if ((ske = RG_TileFindElement(t, RG_TILE_SKETCH, sproj->sketch)) == NULL) { return; } sk = ske->tel_sketch.sk; vg = ske->tel_sketch.sk->vg; TAILQ_FOREACH(vge, &vg->vges, vges) { switch (vge->type) { case VG_LINE_STRIP: VG_VtxCoords2d(vg, vge, 0, &x1, &y1); for (i = 1; i < vge->nvtx; i++) { VG_VtxCoords2d(vg, vge, i, &x2, &y2); RG_ColorUint32(t, sproj->color); RG_WuLine(t, ske->tel_sketch.x+x1, ske->tel_sketch.y+y1, ske->tel_sketch.x+x2, ske->tel_sketch.y+y2); x1 = x2; y1 = y2; } break; default: break; } } }