1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419 |
- /* GCSx
- ** TILESETPAINT.CPP
- **
- ** Tileset editing- actual paint/edit window
- */
- /*****************************************************************************
- ** Copyright (C) 2003-2006 Janson
- **
- ** 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., 59 Temple Place - Suite 330, Boston, MA 02111, USA.
- *****************************************************************************/
- #include "all.h"
- // Tile edit window- toolbar
- const ToolSelect::ToolIconStruct TilePaintTools::toolIcons[TOOLSELECT_NUM_TOOLS] = {
- { TOOLS_PEN, 0, 0, "Draw (pixel by pixel)" },
- { TOOLS_LINE, 20, 0, "Straight line" },
- { TOOLS_DROPPER, 40, 40, "Dropper (grab/select color)" },
- { TOOLS_FILL, 80, 0, "Flood fill" },
- { TOOLS_RECT, 80, 60, "Rectangle (outline)" },
- { TOOLS_RECTFILL, 40, 0, "Rectangle (filled)" },
- { TOOLS_ELLIPSE, 40, 80, "Ellipse (outline)" },
- { TOOLS_ELLIPSEFILL, 60, 0, "Ellipse (filled)" },
- { TOOLS_SELECT, 0, 20, "Select area (rectangle)" },
- { TOOLS_SELECTELLIPSE, 20, 20, "Select area (ellipse)" },
- { TOOLS_WAND, 40, 20, "Magic wand (select area by color)" },
- };
- const ToolSelect::ToolIconStruct TilePaintTools::dotsIcons[TOOLSELECT_NUM_DOTS] = {
- { VIEW_DOTS_NONE, 20, 100, "Don't show dots" },
- { VIEW_DOTS_TRANS, 40, 100, "Show dots on transparent pixels" },
- { VIEW_DOTS_ALPHA, 60, 100, "Show alpha as dots" },
- };
- Window::WindowSort TilePaintTools::windowSort() const { start_func
- return WINDOWSORT_ONTOP;
- }
- void TilePaintTools::adjustForTool() { start_func
- WCheckBox* check = dynamic_cast<WCheckBox*>(findWidget(ID_ANTIALIAS));
-
- if ((*toolPtr == TOOLS_WAND) || (*toolPtr == TOOLS_FILL)) {
- check->enable();
- check->changeText("Contiguous");
- check->setToolTip("Contiguous will only fill or select a single, connected area");
-
- findWidget(ID_TOLERANCELABEL)->enable();
- findWidget(ID_TOLERANCE_S)->enable();
- findWidget(ID_TOLERANCE_N)->enable();
- }
- else {
- check->changeText("Smooth");
- check->setToolTip("Draw smooth lines and circles (antialiased)");
- if ((*toolPtr == TOOLS_LINE) || (*toolPtr == TOOLS_ELLIPSE) || (*toolPtr == TOOLS_ELLIPSEFILL)) check->enable();
- else check->disable();
- findWidget(ID_TOLERANCELABEL)->disable();
- findWidget(ID_TOLERANCE_S)->disable();
- findWidget(ID_TOLERANCE_N)->disable();
- }
- }
- int TilePaintTools::event(int hasFocus, const SDL_Event* event) { start_func
- if (event->type == SDL_COMMAND) {
- // Simple cases
- switch (event->user.code) {
- case VIEW_GRID:
- *gridPtr = *gridPtr ? 0 : 1;
- findWidget(ID_GRID)->load();
- paintArea->refresh();
- config->write(TILEPAINT_GRID, *gridPtr);
- return 1;
-
- case TOOLS_BLENDUP:
- case TOOLS_BLENDDOWN:
- if (event->user.code == TOOLS_BLENDUP) {
- if (((*alphaBlendPtr) += 10) > 100) *alphaBlendPtr = 100;
- }
- else {
- if (((*alphaBlendPtr) -= 10) < 0) *alphaBlendPtr = 0;
- }
- findWidget(ID_ALPHA_S)->load();
- findWidget(ID_ALPHA_N)->load();
- paintArea->refresh();
- return 1;
- case TOOLS_TOLERANCEUP:
- case TOOLS_TOLERANCEDOWN:
- if (event->user.code == TOOLS_TOLERANCEUP) {
- if (((*tolerancePtr) += 10) > 100) *tolerancePtr = 100;
- }
- else {
- if (((*tolerancePtr) -= 10) < 0) *tolerancePtr = 0;
- }
- findWidget(ID_TOLERANCE_S)->load();
- findWidget(ID_TOLERANCE_N)->load();
- config->write(TILEPAINT_TOLERANCE, *tolerancePtr);
- return 1;
- case TOOLS_ANTIALIAS:
- case TOOLS_CONTIGUOUS:
- *antiAliasPtr = *antiAliasPtr ? 0 : 1;
- findWidget(ID_ANTIALIAS)->load();
- config->write(TILEPAINT_ANTIALIAS, *antiAliasPtr);
- return 1;
- }
-
- // Choose tool or dots
- int newTool = 0;
- int newDots = 0;
- WButton* toolButton = dynamic_cast<WButton*>(findWidget(ID_TOOL));
- WButton* dotsButton = dynamic_cast<WButton*>(findWidget(ID_DOTS));
- int x, y;
-
- if (event->user.code == TOOLS_CHOOSE) {
- newTool = toolSelect->run(toolButton->getScreenX(), toolButton->getScreenY() + toolButton->getHeight());
- }
- else if (toolSelect->isTool(event->user.code)) {
- newTool = event->user.code;
- paintArea->startToolIfMove();
- }
- else if (event->user.code == VIEW_DOTS_CHOOSE) {
- newDots = dotsSelect->run(dotsButton->getScreenX(), dotsButton->getScreenY() + dotsButton->getHeight());
- }
- else if (dotsSelect->isTool(event->user.code)) {
- newDots = event->user.code;
- }
-
- if (newTool) {
- if (toolSelect->getToolIcon(newTool, x, y)) {
- toolButton->changeIcon(x, y);
- *toolPtr = newTool;
- adjustForTool();
- return 1;
- }
- }
-
- if (newDots) {
- if (dotsSelect->getToolIcon(newDots, x, y)) {
- dotsButton->changeIcon(x, y);
- *dotsPtr = newDots;
- paintArea->refresh();
- config->write(TILEPAINT_DOTS, *dotsPtr);
- return 1;
- }
- }
-
- if (event->user.code == TOOLS_CHOOSE) return 1;
- if (event->user.code == VIEW_DOTS_CHOOSE) return 1;
- }
- return Dialog::event(hasFocus, event);
- }
- void TilePaintTools::childModified(Window* modified) { start_func
- Dialog::childModified(modified);
-
- Widget* widget = dynamic_cast<Widget*>(modified);
-
- if (widget) {
- // If certain settings modified, tile area needs to refresh
- if ((widget->getId() == ID_GRID) || (widget->getId() == ID_ALPHA_S) || (widget->getId() == ID_ALPHA_N)) {
- paintArea->refresh();
- }
- // Save config settings
- config->write(TILEPAINT_ANTIALIAS, *antiAliasPtr);
- config->write(TILEPAINT_TOLERANCE, *tolerancePtr);
- config->write(TILEPAINT_GRID, *gridPtr);
- }
- }
- void TilePaintTools::tileRedraw() { start_func
- assert(findWidget(ID_PREVIEW));
- // (doesn't throw exceptions)
- findWidget(ID_PREVIEW)->load();
- }
- int TilePaintTools::wantsToBeDeleted() const { start_func
- return 1;
- }
- FrameWindow* TilePaintTools::createWindowed() { start_func
- // Prevent duplication
- if (myFrame) {
- return myFrame;
- }
- // We remember the frame pointer even though it'll delete itself
- myFrame = new FrameWindow("Tools", FrameWindow::RESIZING_SNAP, FrameWindow::FRAMETYPE_DIALOG, this, FrameWindow::TITLEBAR_TOOL, 0);
- return myFrame;
- }
- TilePaintTools::TilePaintTools(TilePaint* tPaintArea, SDL_Surface** tileSource, int* tool, int* alphaBlend, int* antiAlias, int* tolerance, int* grid, int* dots) : Dialog(blankString, 1, 0, 1) { start_func
- myFrame = NULL;
- paintArea = tPaintArea;
- toolPtr = tool;
- antiAliasPtr = antiAlias;
- alphaBlendPtr = alphaBlend;
- tolerancePtr = tolerance;
- gridPtr = grid;
- dotsPtr = dots;
- Widget* w = NULL;
- WNumberBox* n = NULL;
-
- toolSelect = new ToolSelect(getIconSurface(), TOOLSELECT_NUM_TOOLS, toolIcons);
- dotsSelect = new ToolSelect(getIconSurface(), TOOLSELECT_NUM_DOTS, dotsIcons);
-
- int x = 0;
- int y = 0;
- toolSelect->getToolIcon(*toolPtr, x, y);
- w = new WButton(ID_TOOL, getIconSurface(), x, y, 20, 20, Dialog::BUTTON_NOTHING, TOOLS_CHOOSE);
- w->setToolTip("Change tool");
- w->addTo(this);
-
- w = new WCheckBox(ID_ANTIALIAS, "Smooth", antiAlias, 1);
- w->setToolTip("Draw smooth lines and circles (antialiased)");
- w->addTo(this);
-
- arrangeRow();
- w = new WStatic(ID_ALPHALABEL, "Blend %:");
- w->addTo(this);
-
- w = n = new WNumberBox(ID_ALPHA_N, alphaBlend, 0, 100);
- w->setToolTip("Blend controls translucency of tools and pasting");
- w->addTo(this);
-
- w = new WSlider(ID_ALPHA_S, 0, 100, alphaBlend);
- w->setToolTip("Blend controls translucency of tools and pasting");
- dynamic_cast<WSlider*>(w)->linkTo(n);
- w->addTo(this);
-
- w = new WStatic(ID_TOLERANCELABEL, "Tolerance:");
- w->addTo(this);
-
- w = n = new WNumberBox(ID_TOLERANCE_N, tolerance, 0, 100);
- w->setToolTip("Higher tolerance will affect a wider range of color");
- w->addTo(this);
-
- w = new WSlider(ID_TOLERANCE_S, 0, 100, tolerance);
- w->setToolTip("Higher tolerance will affect a wider range of color");
- dynamic_cast<WSlider*>(w)->linkTo(n);
- w->addTo(this);
-
- makePretty(3);
- w = new WButton(ID_COPY, getIconSurface(), 60, 20, 20, 20, Dialog::BUTTON_NOTHING, EDIT_COPY);
- w->setToolTip("Copy");
- w->addTo(this);
-
- w = new WButton(ID_PASTE, getIconSurface(), 80, 20, 20, 20, Dialog::BUTTON_NOTHING, EDIT_PASTE);
- w->setToolTip("Paste (as new selection)");
- w->addTo(this);
-
- w = new WCheckBox(ID_GRID, getIconSurface(), 0, 100, 20, 20, grid, 1);
- w->setToolTip("Show or hide grid");
- w->addTo(this);
-
- arrangeRow();
- w = new WButton(ID_ZOOMIN, getIconSurface(), 0, 80, 20, 20, Dialog::BUTTON_NOTHING, VIEW_ZOOMIN);
- w->setToolTip("Zoom in");
- w->addTo(this);
-
- w = new WButton(ID_ZOOMOUT, getIconSurface(), 20, 80, 20, 20, Dialog::BUTTON_NOTHING, VIEW_ZOOMOUT);
- w->setToolTip("Zoom out");
- w->addTo(this);
-
- w = new WButton(ID_PREV, getIconSurface(), 60, 80, 20, 20, Dialog::BUTTON_NOTHING, VIEW_PREV);
- w->setToolTip("Previous image");
- w->addTo(this);
-
- w = new WButton(ID_NEXT, getIconSurface(), 80, 80, 20, 20, Dialog::BUTTON_NOTHING, VIEW_NEXT);
- w->setToolTip("Next image");
- w->addTo(this);
- dotsSelect->getToolIcon(*dotsPtr, x, y);
- w = new WButton(ID_DOTS, getIconSurface(), x, y, 20, 20, Dialog::BUTTON_NOTHING, VIEW_DOTS_CHOOSE);
- w->setToolTip("Control display of alpha dots");
- w->addTo(this);
-
- arrangeRow();
-
- // Request initial height based on tile, although this will inevitably be resized
- int previewHeight = 96;
- if (*tileSource) previewHeight = (*tileSource)->h * 3;
- w = new WPreview(ID_PREVIEW, tileSource, 166, previewHeight, 1, 0);
- w->setToolTip("Preview");
- w->addTo(this);
-
- arrangeRow();
-
- // Our height if preview is 0 pixels high
- minHeight = height - previewHeight;
-
- adjustForTool();
- runAsPanel();
- }
- TilePaintTools::~TilePaintTools() { start_func
- delete toolSelect;
- delete dotsSelect;
- }
- void TilePaintTools::resize(int newWidth, int newHeight, int newViewWidth, int newViewHeight, int fromParent) { start_func
- if (newViewHeight == -1) newViewHeight = viewHeight;
-
- if (newViewHeight >= 0) {
- // Resize tile preview to fit
- WPreview* widget = dynamic_cast<WPreview*>(findWidget(ID_PREVIEW));
- if (widget) {
- int previewHeight = newViewHeight - minHeight;
- if (previewHeight > 0) {
- widget->changeSize(166, previewHeight);
- // Doesn't throw exceptions
- widget->load();
- newHeight = newViewHeight;
- }
- else {
- widget->changeSize(166, 0);
- // Doesn't throw exceptions
- widget->load();
- newHeight = minHeight;
- }
- }
- }
- Window::resize(newWidth, newHeight, newViewWidth, newViewHeight, fromParent);
- }
- // Tile edit window- Main
- TilePaint::TilePaint(TileSetEdit* myTileset, int myTile, int myIsColl) throw_File : Window() { start_func
- assert(myTileset);
- assert(myTile > 0);
- assert(myTile <= (myIsColl ? myTileset->getCollisionCount() : myTileset->getCount()));
-
- cursorX = cursorY = virtualCursorX = virtualCursorY = 0;
- hideCursor = 0;
- haveFocus = partialFocus = 0;
- toolActive = startToolOnMove = 0;
- dirtyRange.w = 0;
- selectionRect.w = 0;
- selectionMode = SELECTION_OUTLINE;
- selectionXOffs = 0;
- selectionYOffs = 0;
-
- tileset = myTileset;
- world = tileset->getWorldEdit();
- isColl = myIsColl;
-
- // Intentionally doesn't remember last tool selected
- tool = TOOLS_PEN;
- // Intentionally doesn't remember last alpha blend
- alphaBlend = 100;
- // Recall last settings
- antiAlias = config->readNum(TILEPAINT_ANTIALIAS) ? 1 : 0;
- tolerance = config->readNum(TILEPAINT_TOLERANCE);
- if (tolerance < 0) tolerance = 0;
- if (tolerance > 100) tolerance = 100;
- if (isColl) {
- antiAlias = 0;
- tolerance = 100;
- }
- enableGrid = config->readNum(TILEPAINT_GRID) ? 1 : 0;
- drawDots = config->readNum(TILEPAINT_DOTS);
- if ((drawDots != VIEW_DOTS_TRANS) && (drawDots != VIEW_DOTS_ALPHA)) drawDots = VIEW_DOTS_NONE;
- pixelSize = config->readNum(TILEPAINT_ZOOM);
- if (pixelSize >= MAX_ZOOMGRID) gridSize = enableGrid ? 1 : 0;
- else gridSize = 0;
- myFrame = NULL;
- colorbar = NULL;
- tools = NULL;
- tile = NULL;
- alphaWorkspace = NULL;
- selection = NULL;
- backupSelection = NULL;
- tileset->markLock(); // Exception point
-
- FrameWindow* toolsFrame = NULL;
- FrameWindow* colorbarFrame = NULL;
-
- currentTile = myTile; // So changetile isn't called
- reloadTileStats();
- changeTile(myTile);
- colorbar = new ColorSelect(&colors, tileset->getDefaultTransparent());
- tools = new TilePaintTools(this, &tile, &tool, &alphaBlend, &antiAlias, &tolerance, &enableGrid, &drawDots);
- colorbarFrame = colorbar->createWindowed();
- toolsFrame = tools->createWindowed();
-
- myFrame = new FrameWindow(blankString, FrameWindow::RESIZING_NORMAL, FrameWindow::FRAMETYPE_BEVEL_BK, this);
- myFrame->setAutoCenter(1);
- updateTitlebar();
- myFrame->addToolPanel(colorbarFrame, FrameWindow::CLIENT_RIGHT);
- myFrame->addToolPanel(toolsFrame, FrameWindow::CLIENT_RIGHT);
- myFrame->show(FrameWindow::SHOW_CASCADE, FrameWindow::SHOW_CASCADE, FrameWindow::SHOW_CURRMIN, FrameWindow::SHOW_CURRMIN);
-
- // Disabled/etc status on various tools
- if (pixelSize == 1) tools->findWidget(TilePaintTools::ID_ZOOMOUT)->disable();
- if (pixelSize >= MAX_ZOOM) tools->findWidget(TilePaintTools::ID_ZOOMIN)->disable();
- tools->findWidget(TilePaintTools::ID_COPY)->disable();
- }
- TilePaint::~TilePaint() { start_func
- if (tile) SDL_FreeSurface(tile);
- if (alphaWorkspace) SDL_FreeSurface(alphaWorkspace);
- if (selection) SDL_FreeSurface(selection);
- if (backupSelection) SDL_FreeSurface(backupSelection);
- if (tileset) tileset->markUnlock();
- }
- void TilePaint::setDirtyRect(const Rect& rect, int selectionFeather) { start_func
- // Clip
- Rect bound = { 0, 0, tileWidth, tileHeight };
- if (intersectRects(bound, rect)) {
- // Scale to pixel size
- bound.x *= pixelSize;
- bound.y *= pixelSize;
- bound.w = bound.w * pixelSize + 1;
- bound.h = bound.h * pixelSize + 1;
-
- // Feather for selection modification?
- if (selectionFeather) {
- if (bound.x > 0) {
- --bound.x;
- ++bound.w;
- }
- if (bound.y > 0) {
- --bound.y;
- ++bound.h;
- }
- // We don't bother checking if our w/h goes over the limit-
- // this will get clipped; but negative x/y is too odd to allow, above
- ++bound.w;
- ++bound.h;
- }
- // Add rectangle into dirty range
- boundRects(dirtyRange, bound);
- setDirty();
- }
- }
- void TilePaint::setDirtyGlyphWidth(int x1, int x2) { start_func
- // Create a rectangle
- if (x1 > x2) swap(x1, x2);
- Rect glyph = { x1 * pixelSize - GLYPH_SIZE_POINTER_HEIGHT, 0, (x2 - x1) * pixelSize + 1 + GLYPH_SIZE_POINTER_HEIGHT * 2, height };
- boundRects(dirtyRange, glyph);
- setDirty();
- }
- void TilePaint::setDirtyBox(int x1, int y1, int x2, int y2, int selectionFeather) { start_func
- // Create a rectangle
- // Add rectangle into dirty range
- setDirtyRect(createRect(x1, y1, x2, y2), selectionFeather);
- }
- void TilePaint::changeTile(int tileNum) { start_func
- assert(tile);
- assert(tileset);
- assert(tileNum > 0);
- assert(tileNum <= (isColl ? tileset->getCollisionCount() : tileset->getCount()));
- currentTile = tileNum;
- refreshTile();
- if (tools) tools->tileRedraw();
- setDirty(1);
- updateTitlebar();
- }
- void TilePaint::refreshTile() { start_func
- assert(tile);
- assert(tileset);
- assert(currentTile > 0);
- assert(currentTile <= (isColl ? tileset->getCollisionCount() : tileset->getCount()));
- if (isColl) tileset->loadColl(currentTile, tile);
- else tileset->loadTile(currentTile, tile);
- if (isFont) glyphWidth = tileset->getGlyphWidth(currentTile);
- }
- void TilePaint::applyTile() { start_func
- assert(tile);
- assert(tileset);
- assert(currentTile > 0);
- assert(currentTile <= (isColl ? tileset->getCollisionCount() : tileset->getCount()));
- if (isColl) tileset->saveTile(currentTile, tile, this);
- else tileset->saveTile(currentTile, tile, this);
- tools->tileRedraw();
- }
- void TilePaint::applyGlyphWidth() { start_func
- assert(currentTile > 0);
- // (can't be a collision map)
- assert(currentTile <= tileset->getCount());
- tileset->setGlyphWidth(currentTile, glyphWidth, this);
- }
- void TilePaint::setGlyphWidth(int gX) { start_func
- if (glyphWidth != gX) {
- if (gX < 0) gX = 0;
- if (gX > tileWidth) gX = tileWidth;
- setDirtyGlyphWidth(gX, glyphWidth);
- glyphWidth = gX;
- }
- }
- void TilePaint::changePixelSizing(int newPixelSize, int newGridSize) { start_func
- assert(newPixelSize > 0);
- assert(newGridSize >= 0);
- assert(newPixelSize > newGridSize);
- pixelSize = newPixelSize;
- gridSize = newGridSize;
- config->write(TILEPAINT_ZOOM, pixelSize);
-
- resize(tileWidth * pixelSize + 1, tileHeight * pixelSize + 1 + (isFont ? GLYPH_SIZE_POINTER_HEIGHT + GLYPH_SIZE_POINTER_MARGIN : 0));
- if (myFrame) myFrame->requestViewSize(width, height);
- }
- void TilePaint::reloadTileStats() { start_func
- int oldWidth = tileWidth;
- int oldHeight = tileHeight;
- if (isColl) {
- numTiles = tileset->getCollisionCount();
- // Even if fonts can have maps, we don't want glyphs on maps!
- isFont = 0;
- }
- else {
- numTiles = tileset->getCount();
- isFont = tileset->getIsFont();
- }
- tileWidth = tileset->getWidth();
- tileHeight = tileset->getHeight();
- // Close if no tiles left
- if (numTiles == 0) {
- closeWindow();
- return;
- }
- // If numtiles > 0, make sure current tile still exists
- else if (numTiles < currentTile) {
- changeTile(numTiles);
- }
- else {
- // Update titlebar (changetile would've done so, above)
- updateTitlebar();
- }
-
- // Ensure within bounds
- moveCursor(cursorX, cursorY);
-
- // Reallocate surfaces
- SDL_Surface* newTile = NULL;
-
- newTile = createSurface32(tileWidth, tileHeight);
- if (tile) {
- SDL_FreeSurface(tile);
- }
- tile = newTile;
- newTile = NULL;
- newTile = createSurface32(tileWidth, tileHeight);
- if (alphaWorkspace) {
- SDL_FreeSurface(alphaWorkspace);
- }
- alphaWorkspace = newTile;
- newTile = NULL;
- SDL_SetAlpha(alphaWorkspace, SDL_SRCALPHA, 255);
- // Selection must be filled/copied over
- newTile = createSurface32(tileWidth, tileHeight);
- sge_FilledRect(newTile, 0, 0, tileWidth, tileHeight, mapColor32(0, 0, 0, 0));
- if (selection) {
- blit(0, 0, selection, 0, 0, newTile, min(oldWidth, tileWidth), min(oldHeight, tileHeight));
- SDL_FreeSurface(selection);
- // Clip selection rect also
- Rect newSize = { 0, 0, tileWidth, tileHeight };
- intersectRects(selectionRect, newSize);
- }
- selection = newTile;
- newTile = NULL;
- newTile = createSurface32(tileWidth, tileHeight);
- sge_FilledRect(newTile, 0, 0, tileWidth, tileHeight, mapColor32(0, 0, 0, 0));
- if (backupSelection) {
- blit(0, 0, backupSelection, 0, 0, newTile, min(oldWidth, tileWidth), min(oldHeight, tileHeight));
- SDL_FreeSurface(backupSelection);
- }
- backupSelection = newTile;
- newTile = NULL;
-
- resize(tileWidth * pixelSize + 1, tileHeight * pixelSize + 1 + (isFont ? GLYPH_SIZE_POINTER_HEIGHT + GLYPH_SIZE_POINTER_MARGIN : 0));
- if (myFrame) {
- myFrame->setScroll(pixelSize, pixelSize);
- myFrame->requestViewSize(width, height);
- }
- }
- void TilePaint::updateTitlebar() { start_func
- if (myFrame) {
- if (isColl) myFrame->setTitle(formatString("%s : %s : Collision Map %d / %d", world->getTitle().c_str(), tileset->getName().c_str(), currentTile, numTiles));
- else if (isFont) myFrame->setTitle(formatString("%s : %s : Glyph %d / %d (%c)", world->getTitle().c_str(), tileset->getName().c_str(), currentTile, numTiles, currentTile + 31));
- else myFrame->setTitle(formatString("%s : %s : Image %d / %d", world->getTitle().c_str(), tileset->getName().c_str(), currentTile, numTiles));
- }
- }
- int TilePaint::event(int hasFocus, const SDL_Event* event) { start_func
- int changed = 0;
- int clickX, clickY;
- ObjChange* obj;
- switch (event->type) {
- case SDL_CLOSE:
- // Merge any existing selection
- try {
- mergeSelection();
- }
- catch (UndoException& e) {
- }
- return 1;
-
- case SDL_SPECIAL:
- // Refresh selection rectangle?
- if ((event->user.code == SDL_IDLEPHASE) && (partialFocus)) {
- Rect rect = { selectionRect.x + selectionXOffs, selectionRect.y + selectionYOffs, selectionRect.w, selectionRect.h };
- setDirtyRect(rect);
- }
- // Refresh cursor?
- if (((event->user.code == SDL_IDLECURSOR) || (event->user.code == SDL_IDLEPHASE)) && (haveFocus)) {
- Rect rect = { cursorX, cursorY, 1, 1 };
- setDirtyRect(rect);
- }
- return 1;
- case SDL_COMMAND:
- switch (event->user.code) {
- case VIEW_NEXT:
- // Merge any existing selection
- try {
- mergeSelection();
- }
- catch (UndoException& e) {
- return 1;
- }
- cancelTool();
- if (currentTile < numTiles) changeTile(currentTile + 1);
- else changeTile(1);
- return 1;
- case VIEW_PREV:
- // Merge any existing selection
- try {
- mergeSelection();
- }
- catch (UndoException& e) {
- return 1;
- }
- cancelTool();
- if (currentTile > 1) changeTile(currentTile - 1);
- else changeTile(numTiles);
- return 1;
-
- case VIEW_ZOOMOUT:
- zoomOut();
- return 1;
-
- case VIEW_ZOOMIN:
- zoomIn();
- return 1;
-
- case EDIT_UNDO:
- // finish instead of cancel- this causes undo to undo current
- // tool if one is being used
- finishTool();
- // (let world handle from here)
- break;
-
- case EDIT_REDO:
- cancelTool();
- // (let world handle from here)
- break;
-
- case EDIT_COPY:
- copySelection();
- return 1;
-
- case EDIT_CUT:
- try {
- world->undo.preUndoBlock();
- copySelection();
- deleteSelection();
- clearSelection();
- world->undo.postUndoBlock();
- }
- catch (UndoException& e) {
- }
- return 1;
-
- case EDIT_DELETE:
- try {
- deleteSelection();
- }
- catch (UndoException& e) {
- }
- return 1;
-
- case EDIT_SELECTALL:
- try {
- world->undo.preUndoBlock();
- // Merge any floating
- mergeSelection();
- // Store undo for entire selection
- undoStoreSelect(0, 0, tileWidth, tileHeight);
- world->undo.postUndoBlock();
- // Select all
- sge_FilledRect(selection, 0, 0, tileWidth, tileHeight, mapColor32(0, 0, 0, 255));
- selectionRect.x = 0;
- selectionRect.y = 0;
- selectionRect.w = tileWidth;
- selectionRect.h = tileHeight;
- setDirty(1);
- tools->findWidget(TilePaintTools::ID_COPY)->enable();
- }
- catch (UndoException& e) {
- }
- return 1;
-
- case EDIT_DESELECTALL:
- cancelTool();
- try {
- doneSelection();
- }
- catch (UndoException& e) {
- }
- return 1;
-
- case EDIT_PASTE:
- try {
- pasteSelection();
- }
- catch (UndoException& e) {
- return 1;
- }
-
- // Make sure a selection tool is current
- if ((!toolActive) && (tool != TOOLS_SELECT) && (tool != TOOLS_SELECTELLIPSE) && (tool != TOOLS_WAND)) {
- desktop->broadcastEvent(SDL_COMMAND, TOOLS_SELECT);
- desktop->broadcastEvent(SDL_COMMAND, CMD_RELEASE);
- }
-
- return 1;
-
- case EDIT_SETGLYPHWIDTH:
- if (isFont) {
- try {
- undoStoreGlyph();
- }
- catch (UndoException& e) {
- return 1;
- }
- setGlyphWidth(cursorX + 1);
- applyGlyphWidth();
- return 1;
- }
- break;
-
- case CMD_RELEASE:
- finishTool(); // Clears startToolOnMove too; safe even if no tool
- moveCursor(cursorX, cursorY);
- return 1;
- case TOOLS_NEXTCOLOR:
- colorbar->colorSelection(ColorSelect::SELECTED_FG,
- colorbar->colorSelection(ColorSelect::SELECTED_FG) + 1);
- return 1;
- case TOOLS_PREVCOLOR:
- colorbar->colorSelection(ColorSelect::SELECTED_FG,
- colorbar->colorSelection(ColorSelect::SELECTED_FG) - 1);
- return 1;
- case TOOLS_EDITCOLOR:
- colorbar->editColor(colorbar->colorSelection(ColorSelect::SELECTED_FG));
- return 1;
- }
-
- if (world->commandEvent(event->user.code)) return 1;
- break;
-
- case SDL_OBJECTCHANGE:
- obj = (ObjChange*)event->user.data1;
- if ((event->user.code & OBJ_TILESET) && (obj->obj == tileset)) {
- if (event->user.code & OBJMOD_DEFTRANS) {
- colorbar->changeDefaultTransparent(tileset->getDefaultTransparent());
- }
- if (event->user.code & OBJMOD_DELETE) {
- tileset = NULL;
- closeWindow();
- }
- if (event->user.code & OBJMOD_NAME) {
- updateTitlebar();
- }
- if (event->user.code & (OBJMOD_WIDTH | OBJMOD_HEIGHT | OBJMOD_COUNT | OBJMOD_COUNTCOLL)) {
- reloadTileStats();
- if (numTiles) {
- cancelTool(); // After reloading stats, so refresh works
- // Reload tile, resizing may have been from an undo
- refreshTile();
- }
- }
- if (event->user.code & OBJMOD_GLYPHW) {
- if (obj->info1 == currentTile) {
- // Clear tool, tile changed from outside source
- cancelTool();
- refreshTile();
- tools->tileRedraw();
- setDirty(1);
- }
- }
- if (event->user.code & OBJMOD_TILE) {
- if ((!isColl) && (currentTile >= obj->info1) && (currentTile <= obj->info2)) {
- // Clear tool, tile changed from outside source
- cancelTool();
- refreshTile();
- tools->tileRedraw();
- setDirty(1);
- }
- }
- if (event->user.code & OBJMOD_COLL) {
- if ((isColl) && (currentTile >= obj->info1) && (currentTile <= obj->info2)) {
- // Clear tool, coll map changed from outside source
- cancelTool();
- refreshTile();
- tools->tileRedraw();
- setDirty(1);
- }
- }
- }
- if ((event->user.code & OBJ_WORLD) && (obj->obj == world)) {
- if (event->user.code & OBJMOD_DELETE) {
- tileset = NULL;
- closeWindow();
- }
- if (event->user.code & OBJMOD_NAME) {
- updateTitlebar();
- }
- }
- return 1;
-
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONDBL:
- if ((event->button.button == SDL_BUTTON_LEFT) || (event->button.button == SDL_BUTTON_RIGHT)) {
- hideCursor = 1;
- // Signed as it could go off the edge
- clickX = (Sint16)event->button.x / pixelSize;
- clickY = (Sint16)event->button.y / pixelSize;
- // Glyph width?
- if ((clickY >= tileHeight) && (isFont)) {
- startToolGlyphWidthDrag();
- }
- // If unmodified selection-tool left-click and within selection, this is a selection drag
- else if ((!toolActive) &&
- ((tool == TOOLS_SELECT) || (tool == TOOLS_SELECTELLIPSE) || (tool == TOOLS_WAND)) &&
- !(SDL_GetModState() & (KMOD_CTRL | KMOD_ALT)) &&
- (event->button.button == SDL_BUTTON_LEFT) &&
- (isInSelection(clickX, clickY))) {
-
- startToolOnMove = 0;
- moveCursor(clickX, clickY);
- startToolSelectionDrag();
- }
- else {
- moveCursor(clickX, clickY);
- startTool(event->button.button == SDL_BUTTON_LEFT ? ColorSelect::SELECTED_FG : ColorSelect::SELECTED_BK);
- }
- return 1;
- }
- else if (event->button.button == SDL_BUTTON_WHEELUP) {
- zoomIn();
- return 1;
- }
- else if (event->button.button == SDL_BUTTON_WHEELDOWN) {
- zoomOut();
- return 1;
- }
- break;
-
- case SDL_MOUSEBUTTONUP:
- finishTool();
-
- // Force cursor back into area, no more virtual
- moveCursor(cursorX, cursorY);
- return 1;
-
- case SDL_MOUSEMOTION:
- if ((event->motion.state & SDL_BUTTON_LMASK) || (event->motion.state & SDL_BUTTON_RMASK)) {
- hideCursor = 1;
- // Signed as it could go off the edge
- moveCursor(((Sint16)event->motion.x) / pixelSize, ((Sint16)event->motion.y) / pixelSize);
- }
- else {
- // Update mouse pointer
- mousePointer(((Sint16)event->motion.x) / pixelSize, ((Sint16)event->motion.y) / pixelSize);
- }
- return 1;
- case SDL_MOUSEFOCUS:
- if (event->user.code & 1) {
- hover = 1;
- mousePointer();
- }
- else {
- hover = 0;
- selectMouse(MOUSE_NORMAL);
- }
- return 1;
-
- case SDL_INPUTFOCUS:
- if (event->user.code & 1) {
- if (!haveFocus) {
- hideCursor = 0;
- haveFocus = partialFocus = 1;
- changed = 1;
- }
- }
- else if (event->user.code & 2) {
- if (!partialFocus) {
- partialFocus = 1;
- changed = 1;
- }
- }
- else {
- if (partialFocus) {
- partialFocus = 0;
- changed = 1;
- }
- }
- if (!(event->user.code & 1)) {
- if (haveFocus) {
- cancelTool();
- haveFocus = 0;
- changed = 1;
- }
- }
-
- if (changed) {
- // Refresh selection rectangle and cursor
- Rect rect = { selectionRect.x + selectionXOffs, selectionRect.y + selectionYOffs, selectionRect.w, selectionRect.h };
- Rect rect2 = { cursorX, cursorY, 1, 1 };
- setDirtyRect(rect);
- setDirtyRect(rect2);
- }
- return 1;
- case SDL_KEYUP:
- switch (event->key.keysym.sym) {
- case SDLK_LSHIFT:
- case SDLK_RSHIFT:
- case SDLK_SPACE:
- finishTool();
- // Force cursor back into area, no more virtual
- moveCursor(cursorX, cursorY);
- return 1;
-
- case SDLK_LALT:
- case SDLK_RALT:
- case SDLK_LCTRL:
- case SDLK_RCTRL:
- modifyTool();
- return 1;
-
- default:
- break;
- }
- break;
- case SDL_KEYDOWN:
- hideCursor = 0;
- // We can't stick modifiers in due to the numerous combinations that
- // could occur of ctrl/shift/alt in use of various tools
- switch (event->key.keysym.sym) {
- case SDLK_KP_ENTER:
- case SDLK_RETURN:
- // Merge any existing selection
- try {
- mergeSelection();
- }
- catch (UndoException& e) {
- }
- return 1;
- case SDLK_LALT:
- case SDLK_RALT:
- case SDLK_LCTRL:
- case SDLK_RCTRL:
- modifyTool();
- return 1;
- case SDLK_SPACE:
- startTool(ColorSelect::SELECTED_FG);
- return 1;
- case SDLK_LSHIFT:
- startToolOnMove = 1;
- return 1;
-
- // @TODO: This should probably end up as a configurable shortcut somehow
- case SDLK_RSHIFT:
- startTool(ColorSelect::SELECTED_BK);
- return 1;
-
- case SDLK_RIGHT:
- if (selectionMode != SELECTION_OUTLINE) {
- if (event->key.keysym.mod & KMOD_CTRL) moveSelection(tileWidth - selectionRect.w - selectionRect.x, selectionYOffs);
- else moveSelection(selectionXOffs + 1, selectionYOffs);
- }
- else {
- if (event->key.keysym.mod & KMOD_CTRL) moveCursor(tileWidth - 1, virtualCursorY);
- else moveCursor(virtualCursorX + 1, virtualCursorY);
- }
- return 1;
-
- case SDLK_END:
- if (selectionMode != SELECTION_OUTLINE) {
- if (event->key.keysym.mod & KMOD_CTRL) moveSelection(tileWidth - selectionRect.w - selectionRect.x, tileHeight - selectionRect.h - selectionRect.y);
- else moveSelection(tileWidth - selectionRect.w - selectionRect.x, selectionYOffs);
- }
- else {
- if (event->key.keysym.mod & KMOD_CTRL) moveCursor(tileWidth - 1, tileHeight - 1);
- else moveCursor(tileWidth - 1, virtualCursorY);
- }
- return 1;
-
- case SDLK_LEFT:
- if (selectionMode != SELECTION_OUTLINE) {
- if (event->key.keysym.mod & KMOD_CTRL) moveSelection(-selectionRect.x, selectionYOffs);
- else moveSelection(selectionXOffs - 1, selectionYOffs);
- }
- else {
- if (event->key.keysym.mod & KMOD_CTRL) moveCursor(0, virtualCursorY);
- else moveCursor(virtualCursorX - 1, virtualCursorY);
- }
- return 1;
- case SDLK_HOME:
- if (selectionMode != SELECTION_OUTLINE) {
- if (event->key.keysym.mod & KMOD_CTRL) moveSelection(-selectionRect.x, -selectionRect.y);
- else moveSelection(-selectionRect.x, selectionYOffs);
- }
- else {
- if (event->key.keysym.mod & KMOD_CTRL) moveCursor(0, 0);
- else moveCursor(0, virtualCursorY);
- }
- return 1;
-
- case SDLK_DOWN:
- if (selectionMode != SELECTION_OUTLINE) {
- if (event->key.keysym.mod & KMOD_CTRL) moveSelection(selectionXOffs, tileHeight - selectionRect.h - selectionRect.y);
- else moveSelection(selectionXOffs, selectionYOffs + 1);
- }
- else {
- if (event->key.keysym.mod & KMOD_CTRL) moveCursor(virtualCursorX, tileHeight - 1);
- else moveCursor(virtualCursorX, virtualCursorY + 1);
- }
- return 1;
- case SDLK_UP:
- if (selectionMode != SELECTION_OUTLINE) {
- if (event->key.keysym.mod & KMOD_CTRL) moveSelection(selectionXOffs, -selectionRect.y);
- else moveSelection(selectionXOffs, selectionYOffs - 1);
- }
- else {
- if (event->key.keysym.mod & KMOD_CTRL) moveCursor(virtualCursorX, 0);
- else moveCursor(virtualCursorX, virtualCursorY - 1);
- }
- return 1;
- case SDLK_PAGEDOWN:
- if (selectionMode != SELECTION_OUTLINE) {
- moveSelection(selectionXOffs, selectionYOffs + (viewHeight / pixelSize - 1));
- }
- else {
- moveCursor(virtualCursorX, virtualCursorY + (viewHeight / pixelSize - 1));
- }
- return 1;
- case SDLK_PAGEUP:
- if (selectionMode != SELECTION_OUTLINE) {
- moveSelection(selectionXOffs, selectionYOffs - (viewHeight / pixelSize - 1));
- }
- else {
- moveCursor(virtualCursorX, virtualCursorY - (viewHeight / pixelSize - 1));
- }
- return 1;
-
- default:
- break;
- }
- break;
- }
- return 0;
- }
- void TilePaint::zoomOut() { start_func
- if (pixelSize > MAX_ZOOMGRID) changePixelSizing(pixelSize - 1, enableGrid ? 1 : 0);
- else if (pixelSize > 1) changePixelSizing(pixelSize - 1, 0);
- if (pixelSize == 1) tools->findWidget(TilePaintTools::ID_ZOOMOUT)->disable();
- tools->findWidget(TilePaintTools::ID_ZOOMIN)->enable();
- }
-
- void TilePaint::zoomIn() { start_func
- if (pixelSize < MAX_ZOOMGRID - 1) changePixelSizing(pixelSize + 1, 0);
- else if (pixelSize < MAX_ZOOM) changePixelSizing(pixelSize + 1, enableGrid ? 1 : 0);
- if (pixelSize == MAX_ZOOM) tools->findWidget(TilePaintTools::ID_ZOOMIN)->disable();
- tools->findWidget(TilePaintTools::ID_ZOOMOUT)->enable();
- }
- void TilePaint::moveSelection(int newX, int newY) { start_func
- // No dragging of outlines allowed
- if (selectionMode == SELECTION_OUTLINE) return;
-
- if ((newX != selectionXOffs) || (newY != selectionYOffs)) {
- // Dirty old
- Rect rect = { selectionRect.x + selectionXOffs, selectionRect.y + selectionYOffs, selectionRect.w, selectionRect.h };
- setDirtyRect(rect);
-
- // Move (no limits to where it can move to)
- selectionXOffs = newX;
- selectionYOffs = newY;
-
- // Dirty new
- rect.x = selectionRect.x + newX;
- rect.y = selectionRect.y + newX;
- setDirtyRect(rect);
- }
- }
- void TilePaint::moveCursor(int newX, int newY) { start_func
- int oldX = cursorX;
- int oldY = cursorY;
- int doTool = 0;
-
- if (startToolOnMove) startTool(ColorSelect::SELECTED_FG);
- // This alone doesn't make anything dirty; normally, this isn't used;
- // anything that does use it, dirties; we don't track virtual cursor
- // if no active tool
- if (toolActive) {
- if ((newX != virtualCursorX) || (virtualCursorY != newY)) {
- virtualCursorX = newX;
- virtualCursorY = newY;
-
- // Tool
- doTool = 1;
- }
- }
- if (newX < 0) newX = 0;
- if (newX >= tileWidth) newX = tileWidth - 1;
- if (newY < 0) newY = 0;
- if (newY >= tileHeight) newY = tileHeight - 1;
-
- if ((newX != cursorX) || (newY != cursorY)) {
- cursorX = newX;
- cursorY = newY;
- // Scroll?
- if (myFrame) myFrame->scrollToView(cursorX * pixelSize,
- cursorY * pixelSize,
- pixelSize, pixelSize);
- // Dirty
- setDirtyBox(oldX, oldY, cursorX, cursorY);
- }
- if (doTool) dragTool();
- // No active tool, we track virtual cursor, but to CLIPPED coordinates
- else if (!toolActive) {
- virtualCursorX = newX;
- virtualCursorY = newY;
- }
- }
- void TilePaint::startToolGlyphWidthDrag() { start_func
- assert(tile);
-
- if (toolActive) return;
-
- toolActive = TOOLS_GLYPHWIDTHDRAG;
- mousePointer();
- dragTool(1);
- }
- void TilePaint::startToolSelectionDrag() { start_func
- assert(tile);
- startToolOnMove = 0;
- if (toolActive) return;
- toolActive = TOOLS_SELECTDRAG;
- toolStartX = virtualCursorX;
- toolStartY = virtualCursorY;
- toolCtrl = SDL_GetModState() & KMOD_CTRL;
- toolAlt = SDL_GetModState() & KMOD_ALT;
- mousePointer();
- dragTool(1);
- }
- void TilePaint::startTool(int fgbk) { start_func
- assert(tile);
- startToolOnMove = 0;
- if (toolActive) return;
- // Merge any existing selection
- try {
- mergeSelection();
- }
- catch (UndoException& e) {
- return;
- }
- toolMinX = virtualCursorX;
- toolMinY = virtualCursorY;
- toolMaxX = virtualCursorX;
- toolMaxY = virtualCursorY;
-
- toolFgBk = fgbk;
- toolActive = tool;
- toolStartX = virtualCursorX;
- toolStartY = virtualCursorY;
- toolAlpha = alphaBlend;
- toolAlias = antiAlias;
- // Scale tolerance to 500, the max two colors can differ is 1019
- toolTolerance = tolerance * 5;
- toolCtrl = SDL_GetModState() & KMOD_CTRL;
- toolAlt = SDL_GetModState() & KMOD_ALT;
- if (toolFgBk == ColorSelect::SELECTED_FG) {
- toolColor = mapColor32(colors.fg.r, colors.fg.g, colors.fg.b, colors.fg.a * toolAlpha / 100);
- }
- else {
- toolColor = mapColor32(colors.bk.r, colors.bk.g, colors.bk.b, colors.bk.a * toolAlpha / 100);
- }
-
- mousePointer();
- dragTool(1);
- }
- void TilePaint::modifyTool() { start_func
- if (toolActive) {
- toolCtrl = SDL_GetModState() & KMOD_CTRL;
- toolAlt = SDL_GetModState() & KMOD_ALT;
- // Selection tools need entire area dirtied because this may cause
- // a deleted selection to reappear
- if ((toolActive == TOOLS_SELECT) || (toolActive == TOOLS_SELECTELLIPSE) || (toolActive == TOOLS_WAND)) {
- setDirty(1);
- }
-
- // Selection dragging changes selection type
- if ((toolActive == TOOLS_SELECTDRAG) && (selectionMode != SELECTION_OUTLINE)) {
- if ((toolCtrl) || (toolAlt)) selectionMode = SELECTION_OPAQUE;
- else selectionMode = SELECTION_ALPHA;
- }
- dragTool();
- }
- // Always update mouse pointer even if no active tool
- mousePointer();
- }
- void TilePaint::dragTool(int firstTime, int lastTime) { start_func
- assert(tile);
-
- // Selection tools merely clear, on right-click
- if ((firstTime) && (toolFgBk == ColorSelect::SELECTED_BK) &&
- ((toolActive == TOOLS_SELECT) ||
- (toolActive == TOOLS_SELECTELLIPSE) ||
- (toolActive == TOOLS_WAND))) {
- try {
- doneSelection();
- }
- catch (UndoException& e) {
- }
- toolActive = 0;
- return;
- }
-
- if (toolActive) {
- int rX, rY;
- int slope1, slope2;
- SDL_Surface* drawTo;
- Rect rect;
- Rect tileBound = { 0, 0, tileWidth, tileHeight };
- Uint8* data;
- int nonDraw = 0;
- if ((toolActive == TOOLS_SELECT) || (toolActive == TOOLS_SELECTELLIPSE) ||
- (toolActive == TOOLS_DROPPER) || (toolActive == TOOLS_WAND) ||
- (toolActive == TOOLS_SELECTDRAG) || (toolActive == TOOLS_GLYPHWIDTHDRAG)) {
- nonDraw = 1;
- }
- if ((tool != TOOLS_PEN) && (!nonDraw)) refreshTile();
- if (((toolAlpha < 100) || ((selectionMode == SELECTION_OUTLINE) && (selectionRect.w))) && (!nonDraw)) {
- // If we're drawing using alpha, start with transparency
- if (toolAlpha < 100) drawRect(0, 0, alphaWorkspace->w, alphaWorkspace->h, mapColor32(0, 0, 0, 0), alphaWorkspace);
- // ...otherwise start with current data
- else blit(0, 0, tile, 0, 0, alphaWorkspace, alphaWorkspace->w, alphaWorkspace->h);
- drawTo = alphaWorkspace;
- }
- else {
- drawTo = tile;
- }
-
- // So that undo warning boxes don't cancel us!
- int tool = toolActive;
- if (lastTime) toolActive = 0;
-
- try {
- switch (tool) {
- case TOOLS_GLYPHWIDTHDRAG:
- if (lastTime) {
- refreshTile();
- undoStoreGlyph();
- setGlyphWidth(virtualCursorX);
- applyGlyphWidth();
- }
- else {
- setGlyphWidth(virtualCursorX);
- }
- break;
-
- case TOOLS_SELECTDRAG:
- // Dirty current selection area
- setDirtyBox(selectionRect.x + selectionXOffs, selectionRect.y + selectionYOffs,
- selectionRect.x + selectionRect.w - 1 + selectionXOffs,
- selectionRect.y + selectionRect.h - 1 + selectionYOffs);
-
- // Float selection?
- if (firstTime) {
- floatSelection();
- }
- else {
- // Move selection
- selectionXOffs += virtualCursorX - toolLastX;
- selectionYOffs += virtualCursorY - toolLastY;
-
- // Dirty new area also
- setDirtyBox(selectionRect.x + selectionXOffs, selectionRect.y + selectionYOffs,
- selectionRect.x + selectionRect.w - 1 + selectionXOffs,
- selectionRect.y + selectionRect.h - 1 + selectionYOffs);
- }
- break;
-
- case TOOLS_WAND:
- case TOOLS_SELECT:
- case TOOLS_SELECTELLIPSE:
- // Keep a backup copy of old selection
- if (firstTime) {
- blit(0, 0, selection, 0, 0, backupSelection, tileWidth, tileHeight);
- backupSelectionRect = selectionRect;
- }
- // Refresh from backup if dragging with ctrl/alt
- else if ((toolCtrl) || (toolAlt)) {
- blit(0, 0, backupSelection, 0, 0, selection, tileWidth, tileHeight);
- selectionRect = backupSelectionRect;
- }
-
- if (tool == TOOLS_WAND) {
- // We get rectangle from previous time
- if (!firstTime) {
- rect.x = toolMinX;
- rect.y = toolMinY;
- rect.w = toolMaxX - toolMinX + 1;
- rect.h = toolMaxY - toolMinY + 1;
-
- // Mark previous rect dirty
- setDirtyRect(rect, 1);
- }
- else {
- rect.w = 0;
- }
- }
- else if (tool == TOOLS_SELECT) {
- rect = createRect(toolStartX, toolStartY, virtualCursorX, virtualCursorY);
- }
- else {
- rX = abs(toolStartX - virtualCursorX);
- rY = abs(toolStartY - virtualCursorY);
-
- // Special case
- if (rX < 1) rX = 1;
- if (rY < 1) rY = 1;
-
- rect = createRect(toolStartX - rX, toolStartY - rY, toolStartX + rX, toolStartY + rY);
- }
-
- // We can't have a selection rect that's bigger than the selection surface
- intersectRects(rect, tileBound);
-
- // Undo?
- if (lastTime) {
- // If we're clearing selection, we must do extra work here
- if ((!toolCtrl) && (!toolAlt)) {
- // Refresh from backup
- blit(0, 0, backupSelection, 0, 0, selection, tileWidth, tileHeight);
- selectionRect = backupSelectionRect;
- // Add into rectangle the area we're selecting
- boundRects(selectionRect, rect);
- // Clear it AND store undo
- clearSelection();
- }
- else {
- // Just undo the area we're adding/deleting from
- if (rect.w) undoStoreSelect(rect.x, rect.y, rect.w, rect.h);
- }
- }
- // Clear selection if no ctrl/alt
- else if ((!toolCtrl) && (!toolAlt)) clearSelection(0);
-
- // Draw
- if (tool == TOOLS_WAND) {
- // Non-contiguous always works
- if (!toolAlias) {
- rect = floodFillNonContiguous32(tile, selection, virtualCursorX, virtualCursorY, mapColor32(0, 0, 0, toolAlt ? 0 : 255), toolTolerance);
- }
- else {
- // Use alpha workspace as temp area, use 255/255/255 as filler color
- drawRect(0, 0, alphaWorkspace->w, alphaWorkspace->h, mapColor32(255, 255, 255, 255), alphaWorkspace);
- rect = floodFill32(tile, alphaWorkspace, virtualCursorX, virtualCursorY, mapColor32(0, 0, 0, toolAlt ? 0 : 255), toolTolerance);
- SDL_SetAlpha(alphaWorkspace, 0, 255);
- SDL_SetColorKey(alphaWorkspace, SDL_SRCCOLORKEY, mapColor32(255, 255, 255, 255));
- blit(0, 0, alphaWorkspace, 0, 0, selection, tileWidth, tileHeight);
- SDL_SetColorKey(alphaWorkspace, 0, 0);
- SDL_SetAlpha(alphaWorkspace, SDL_SRCALPHA, 255);
- }
-
- // Remember min/max for undo next time
- if (rect.w) {
- toolMinX = rect.x;
- toolMinY = rect.y;
- toolMaxX = rect.x + rect.w - 1;
- toolMaxY = rect.y + rect.h - 1;
- }
- else {
- // Causes no undo area or undirty to occur next frame
- toolMinX = toolMaxX = -1;
- }
- }
- else if (tool == TOOLS_SELECT) {
- sge_FilledRect(selection, toolStartX, toolStartY, virtualCursorX, virtualCursorY, mapColor32(0, 0, 0, toolAlt ? 0 : 255));
- }
- else {
- sge_FilledEllipse(selection, toolStartX, toolStartY, rX, rY, mapColor32(0, 0, 0, toolAlt ? 0 : 255));
- }
- setDirtyRect(rect, 1);
-
- // Add to overall selection bounding box
- if (!toolAlt) boundRects(selectionRect, rect);
- // ...or fix selection rectangle if removing stuff
- else fixSelectionRect();
-
- // Previous
- if (!firstTime) {
- if (tool == TOOLS_WAND) {
- // (was dirtied above, at beginning)
- }
- else if (tool == TOOLS_SELECT) {
- setDirtyBox(toolStartX, toolStartY, toolLastX, toolLastY, 1);
- }
- else {
- rX = abs(toolStartX - toolLastX);
- rY = abs(toolStartY - toolLastY);
- if (rX < 1) rX = 1;
- if (rY < 1) rY = 1;
- setDirtyBox(toolStartX - rX, toolStartY - rY, toolStartX + rX, toolStartY + rY, 1);
- }
- }
-
- // Allow copy now?
- if (lastTime) {
- if (selectionRect.w) tools->findWidget(TilePaintTools::ID_COPY)->enable();
- else tools->findWidget(TilePaintTools::ID_COPY)->disable();
- }
- break;
-
- case TOOLS_DROPPER:
- data = ((Uint8*)tile->pixels) + cursorX * 4 + cursorY * tile->pitch;
- colorbar->addColor(toolFgBk, data[0], data[1], data[2], data[3], !firstTime);
- break;
-
- case TOOLS_PEN:
- // We don't want to draw the previous pixel twice; this is more important
- // than the slight degradation in line quality, as lines are only used
- // if the mouse moves "too fast"
- if (!lastTime) {
- if (toolStartX > virtualCursorX) --toolStartX;
- else if (toolStartX < virtualCursorX) ++toolStartX;
- if (toolStartY > virtualCursorY) --toolStartY;
- else if (toolStartY < virtualCursorY) ++toolStartY;
- sge_Line(drawTo, toolStartX, toolStartY, virtualCursorX, virtualCursorY, toolColor);
- setDirtyBox(toolStartX, toolStartY, virtualCursorX, virtualCursorY);
- }
-
- // Track area covered for undo
- if (virtualCursorX < toolMinX) toolMinX = virtualCursorX;
- if (virtualCursorX > toolMaxX) toolMaxX = virtualCursorX;
- if (virtualCursorY < toolMinY) toolMinY = virtualCursorY;
- if (virtualCursorY > toolMaxY) toolMaxY = virtualCursorY;
- if (toolStartX < toolMinX) toolMinX = toolStartX;
- if (toolStartX > toolMaxX) toolMaxX = toolStartX;
- if (toolStartY < toolMinY) toolMinY = toolStartY;
- if (toolStartY > toolMaxY) toolMaxY = toolStartY;
-
- toolStartX = virtualCursorX;
- toolStartY = virtualCursorY;
-
- if (lastTime) undoStoreBlitBox(toolMinX, toolMinY, toolMaxX, toolMaxY);
- else if (tools) tools->tileRedraw();
- break;
-
- case TOOLS_FILL:
- // Undo based on rectangle from last time
- if (lastTime) undoStoreBlitBox(toolMinX, toolMinY, toolMaxX, toolMaxY);
-
- // Dirty previous rectangle
- if (!firstTime) setDirtyBox(toolMinX, toolMinY, toolMaxX, toolMaxY);
-
- // Non-contiguous always works
- if (!toolAlias) {
- rect = floodFillNonContiguous32(tile, drawTo, virtualCursorX, virtualCursorY, toolColor, toolTolerance);
- }
- // Possible situations-
- // Drawing to tile- works OK if 0 tolerance (fills directly on surface)
- // Drawing to alpha 100%- works OK if 0 tolerance (fills directly on copy of surface)
- // Drawing to alpha <100%- works OK always (0,0,0,0 doesn't fill, but would have no effect anyways)
- // Situations that don't work OK- we must draw to a temp surface and colorkey-blit over
- else if ((toolTolerance > 0) && ((drawTo == tile) || ((drawTo == alphaWorkspace) && (toolAlpha == 100)))) {
- // Use bitwise complement for background, so there can't be a conflict
- drawRect(0, 0, backupSelection->w, backupSelection->h, ~toolColor, backupSelection);
- rect = floodFill32(tile, backupSelection, virtualCursorX, virtualCursorY, toolColor, toolTolerance);
- SDL_SetColorKey(backupSelection, SDL_SRCCOLORKEY, ~toolColor);
- blit(0, 0, backupSelection, 0, 0, drawTo, tileWidth, tileHeight);
- SDL_SetColorKey(backupSelection, 0, 0);
- }
- else {
- rect = floodFill32(tile, drawTo, virtualCursorX, virtualCursorY, toolColor, toolTolerance);
- }
- setDirtyRect(rect);
-
- // Remember min/max for undo on last time
- if (rect.w) {
- toolMinX = rect.x;
- toolMinY = rect.y;
- toolMaxX = rect.x + rect.w - 1;
- toolMaxY = rect.y + rect.h - 1;
- }
- else {
- // Causes no undo area or undirty to occur next frame
- toolMinX = toolMaxX = -1;
- }
- break;
-
- case TOOLS_LINE:
- case TOOLS_RECT:
- case TOOLS_RECTFILL:
- // @TODO: we changed this line, haven't tested it yet
- if (lastTime) undoStoreBlitBox(toolStartX, toolStartY, virtualCursorX, virtualCursorY);
-
- rX = virtualCursorX;
- rY = virtualCursorY;
-
- // Limit to square or straight line?
- if (toolCtrl) {
- if (tool == TOOLS_LINE) {
- // Determine approximate slope of line
- slope1 = abs(toolStartX - rX);
- slope2 = abs(toolStartY - rY);
- // (we only care, if both sizes are > 0)
- if ((slope1) && (slope2)) {
- if (slope1 > slope2) swap(slope1, slope2);
- // slope1/slope2 will be a fraction between 0 (flat) and
- // 1 (diagonal of 45deg multiple); cutoff point is 0.5
- if (slope1 * 2 / slope2 >= 1) {
- // Square
- if (abs(toolStartX - rX) < abs(toolStartY - rY)) {
- rY = toolStartY + abs(toolStartX - rX) * (toolStartY < rY ? 1 : -1);
- }
- else {
- rX = toolStartX + abs(toolStartY - rY) * (toolStartX < rX ? 1 : -1);
- }
- }
- else {
- // Flat line
- if (abs(toolStartX - rX) < abs(toolStartY - rY)) {
- rX = toolStartX;
- }
- else {
- rY = toolStartY;
- }
- }
- }
- }
- else {
- // Square
- if (abs(toolStartX - rX) < abs(toolStartY - rY)) {
- rY = toolStartY + abs(toolStartX - rX) * (toolStartY < rY ? 1 : -1);
- }
- else {
- rX = toolStartX + abs(toolStartY - rY) * (toolStartX < rX ? 1 : -1);
- }
- }
- }
-
- if (tool == TOOLS_LINE) {
- if (toolAlias) sge_AALine(drawTo, toolStartX, toolStartY, rX, rY, toolColor);
- else sge_Line(drawTo, toolStartX, toolStartY, rX, rY, toolColor);
- }
- else if (tool == TOOLS_RECT) sge_Rect(drawTo, toolStartX, toolStartY, rX, rY, toolColor);
- else sge_FilledRect(drawTo, toolStartX, toolStartY, rX, rY, toolColor);
- setDirtyBox(toolStartX, toolStartY, rX, rY);
- // (no need to limit based on toolCtrl, as a limited area will always
- // be smaller than this area we use here)
- if (!firstTime) setDirtyBox(toolStartX, toolStartY, toolLastX, toolLastY);
- break;
-
- case TOOLS_ELLIPSE:
- case TOOLS_ELLIPSEFILL:
- rX = abs(toolStartX - virtualCursorX);
- rY = abs(toolStartY - virtualCursorY);
-
- // Special case
- if (rX < 1) rX = 1;
- if (rY < 1) rY = 1;
-
- // Circle?
- if (toolCtrl) {
- rX = min(rX, rY);
- rY = rX;
- }
-
- if (lastTime) undoStoreBlitBox(toolStartX - rX, toolStartY - rY, toolStartX + rX, toolStartY + rY);
-
- if (tool == TOOLS_ELLIPSE) {
- if (toolAlias) sge_AAEllipse(drawTo, toolStartX, toolStartY, rX, rY, toolColor);
- else sge_Ellipse(drawTo, toolStartX, toolStartY, rX, rY, toolColor);
- }
- else {
- if (toolAlias) sge_AAFilledEllipse(drawTo, toolStartX, toolStartY, rX, rY, toolColor);
- else sge_FilledEllipse(drawTo, toolStartX, toolStartY, rX, rY, toolColor);
- }
-
- setDirtyBox(toolStartX - rX, toolStartY - rY, toolStartX + rX, toolStartY + rY);
-
- // Previous
- if (!firstTime) {
- rX = abs(toolStartX - toolLastX);
- rY = abs(toolStartY - toolLastY);
- if (rX < 1) rX = 1;
- if (rY < 1) rY = 1;
- // (no need to limit to a circle based on toolCtrl, this will always
- // cover the minimum area needed)
- setDirtyBox(toolStartX - rX, toolStartY - rY, toolStartX + rX, toolStartY + rY);
- }
- break;
- }
- }
- catch (UndoException& e) {
- toolActive = tool;
- cancelTool();
- return;
- }
-
- if (drawTo == alphaWorkspace) {
- // Clip to selection, alpha blit, or both?
- if ((selectionMode == SELECTION_OUTLINE) && (selectionRect.w)) {
- if (toolAlpha < 100) maskAlphaBlit32(0, 0, alphaWorkspace, 0, 0, tile, 0, 0, selection, 100, tileWidth, tileHeight);
- else maskBlit32(0, 0, alphaWorkspace, 0, 0, tile, 0, 0, selection, tileWidth, tileHeight);
- }
- else alphaBlit32(0, 0, alphaWorkspace, 0, 0, tile, tileWidth, tileHeight);
- }
-
- if ((lastTime) && (!nonDraw)) {
- applyTile();
- }
- else if (!nonDraw) tools->tileRedraw();
-
- toolLastX = virtualCursorX;
- toolLastY = virtualCursorY;
- }
- }
- void TilePaint::cancelTool() { start_func
- assert(tile);
-
- startToolOnMove = 0;
- if (toolActive) {
- int rX;
- int rY;
-
- switch (toolActive) {
- case TOOLS_GLYPHWIDTHDRAG:
- rX = glyphWidth;
- refreshTile();
- setDirtyGlyphWidth(rX, glyphWidth);
- // The cursor may appear, and the above won't necessarily cover it
- setDirtyBox(cursorX, cursorY, cursorX, cursorY);
- break;
- case TOOLS_SELECT:
- case TOOLS_SELECTELLIPSE:
- case TOOLS_WAND:
- // Refresh from backup, dirty all
- blit(0, 0, backupSelection, 0, 0, selection, tileWidth, tileHeight);
- selectionRect = backupSelectionRect;
- setDirty(1);
- break;
- case TOOLS_PEN:
- case TOOLS_FILL:
- refreshTile();
- tools->tileRedraw();
- setDirtyBox(toolMinX, toolMinY, toolMaxX, toolMaxY);
- break;
-
- case TOOLS_LINE:
- case TOOLS_RECT:
- case TOOLS_RECTFILL:
- refreshTile();
- tools->tileRedraw();
- setDirtyBox(toolStartX, toolStartY, toolLastX, toolLastY);
- break;
-
- case TOOLS_ELLIPSE:
- case TOOLS_ELLIPSEFILL:
- refreshTile();
- tools->tileRedraw();
- rX = abs(toolStartX - toolLastX);
- rY = abs(toolStartY - toolLastY);
- if (rX < 1) rX = 1;
- if (rY < 1) rY = 1;
- setDirtyBox(toolStartX - rX, toolStartY - rY, toolStartX + rX, toolStartY + rY);
- break;
- }
-
- mousePointer();
- toolActive = 0;
- }
- }
- void TilePaint::finishTool() { start_func
- assert(tile);
- startToolOnMove = 0;
- if (toolActive) {
- dragTool(0, 1);
- mousePointer();
- // toolActive = 0 taken care of by dragtool now
- }
- }
- void TilePaint::display(SDL_Surface* destSurface, Rect& toDisplay, const Rect& clipArea, int xOffset, int yOffset) { start_func
- assert(destSurface);
- if (visible) {
- // If dirty, redraw range or all
- if (dirty) {
- if (totalDirty) {
- getRect(toDisplay);
- toDisplay.x += xOffset;
- toDisplay.y += yOffset;
- }
- else {
- dirtyRange.x += x + xOffset;
- dirtyRange.y += y + yOffset;
- // Range must include requested update area as well
- boundRects(toDisplay, dirtyRange);
- }
- dirty = totalDirty = 0;
- dirtyRange.w = 0;
- intersectRects(toDisplay, clipArea);
- }
- xOffset += x;
- yOffset += y;
-
- // Anything to draw?
- if (toDisplay.w) {
- SDL_SetClipRect(destSurface, &toDisplay);
- SDL_FillRect(destSurface, &toDisplay, guiPacked[COLOR_BKFILL]);
- // position of original pixel
- int opX = max(0, (toDisplay.x - xOffset) / pixelSize);
- int pY = max(0, (toDisplay.y - yOffset) / pixelSize);
-
- // drawn position
- int odX = opX * pixelSize + xOffset;
- int dY = pY * pixelSize + yOffset;
-
- // source material
- int pitch = tile->pitch;
- const Uint8* source = (Uint8*)tile->pixels + opX * 4 + pY * pitch;
- int selPitch = selection->pitch;
- const Uint8* selSrc = (Uint8*)selection->pixels + (opX - selectionXOffs) * 4 + (pY - selectionYOffs) * selPitch;
-
- // limits
- int lastY = toDisplay.y + toDisplay.h;
- int lastX = toDisplay.x + toDisplay.w;
-
- // Area we can legally check for selection (outside this area,
- // pointer is not gaurunteed to point to anything)
- int selX1 = -1;
- int selX2 = -1;
- int selY1 = -1;
- int selY2 = -1;
- if (selectionRect.w) {
- selX1 = selectionRect.x + selectionXOffs;
- selX2 = selectionRect.x + selectionRect.w - 1 + selectionXOffs;
- selY1 = selectionRect.y + selectionYOffs;
- selY2 = selectionRect.y + selectionRect.h - 1 + selectionYOffs;
- }
-
- // Temp storage for alpha selections
- Uint8 selTemp[4];
-
- // Draw right/bottom grid line first, because pixels may overwrite
- // this with selection lines
- // Right/bottom grid is always drawn even if grid is "off"
- if (xOffset + tileWidth * pixelSize < lastX) {
- drawVLine(yOffset, yOffset + tileHeight * pixelSize,
- xOffset + tileWidth * pixelSize, guiPacked[COLOR_GRID], destSurface);
- }
- if (yOffset + tileHeight * pixelSize < lastY) {
- drawHLine(xOffset, xOffset + tileWidth * pixelSize,
- yOffset + tileHeight * pixelSize, guiPacked[COLOR_GRID], destSurface);
- }
-
- for (; (dY < lastY) && (pY < tileHeight); dY += pixelSize, ++pY) {
- int pX = opX;
- int dX = odX;
- for (; (dX < lastX) && (pX < tileWidth); dX += pixelSize, ++pX, source += 4, selSrc += 4) {
- const Uint8* data = source;
-
- int drawT = gridSize;
- int drawB = 0;
- int drawL = gridSize;
- int drawR = 0;
-
- // Selection?
- if ((pX >= selX1) && (pX <= selX2) && (pY >= selY1) && (pY <= selY2)) {
- if (selSrc[3]) {
- // Modify data?
- if (selectionMode == SELECTION_OPAQUE) {
- data = selSrc;
- }
- else if (selectionMode == SELECTION_ALPHA) {
- int alpha = selSrc[3];
- int blend = alphaBlend;
-
- // Adjust alpha based on alpha option
- alpha = alpha * blend / 100;
-
- // Special cases
- if ((alpha == 255) || ((source[3] == 0) && (blend == 100))) {
- data = selSrc;
- }
- else {
- data = selTemp;
-
- // Scale RGB blend based on alpha of destination
- int destAlpha = source[3];
- int rgbScale = alpha;
- if (destAlpha < alpha) rgbScale = alpha + (256 - alpha) * (alpha - source[3]) / 255;
-
- selTemp[0] = (source[0] + ((selSrc[0] - source[0]) * rgbScale >> 8)) & 0xFF;
- selTemp[1] = (source[1] + ((selSrc[1] - source[1]) * rgbScale >> 8)) & 0xFF;
- selTemp[2] = (source[2] + ((selSrc[2] - source[2]) * rgbScale >> 8)) & 0xFF;
- selTemp[3] = (source[3] + ((255 - source[3]) * alpha >> 8)) & 0xFF;
- }
- }
-
- // Selection rectangle
- if (partialFocus) {
- if ((pX == selX1) || !(selSrc[-1])) drawL = 2;
- if ((pX == selX2) || !(selSrc[7])) drawR = 2;
- if ((pY == selY1) || !(selSrc[-selPitch + 3])) drawT = 2;
- if ((pY == selY2) || !(selSrc[selPitch + 3])) drawB = 2;
- }
- }
- }
- // 0 alpha shows different
- if (data[3] == 0) {
- drawRect(dX, dY, pixelSize, pixelSize, guiPacked[COLOR_TRANSPARENT1], destSurface);
- if ((drawDots == VIEW_DOTS_ALPHA) && (pixelSize - gridSize > 2)) {
- drawRect(dX + 1 + gridSize, dY + 1 + gridSize, pixelSize - 2 - gridSize, pixelSize - 2 - gridSize,
- SDL_MapRGB(destSurface->format, 0, 0, 0), destSurface);
- }
- else if ((drawDots == VIEW_DOTS_TRANS) && (pixelSize > 1)) {
- drawPixel(dX + pixelSize/2, dY + pixelSize/2, guiPacked[COLOR_TRANSPARENT2], destSurface);
- }
- }
- else if (data[3] == 255) {
- drawRect(dX, dY, pixelSize, pixelSize,
- SDL_MapRGB(destSurface->format, data[0], data[1], data[2]), destSurface);
- if ((drawDots == VIEW_DOTS_ALPHA) && (pixelSize - gridSize > 2)) {
- drawRect(dX + 1 + gridSize, dY + 1 + gridSize, pixelSize - 2 - gridSize, pixelSize - 2 - gridSize,
- SDL_MapRGB(destSurface->format, 255, 255, 255), destSurface);
- }
- }
- else {
- drawRect(dX, dY, pixelSize, pixelSize,
- SDL_MapRGB(destSurface->format, data[0] * data[3] >> 8, data[1] * data[3] >> 8, data[2] * data[3] >> 8), destSurface);
- if ((drawDots == VIEW_DOTS_ALPHA) && (pixelSize - gridSize > 2)) {
- drawRect(dX + 1 + gridSize, dY + 1 + gridSize, pixelSize - 2 - gridSize, pixelSize - 2 - gridSize,
- SDL_MapRGB(destSurface->format, data[3], data[3], data[3]), destSurface);
- }
- }
-
- // Grid assumes 1-thickness lines
- if (drawT == 1) drawHLine(dX, dX + pixelSize - 1, dY, guiPacked[COLOR_GRID], destSurface);
- else if (drawT == 2) drawAntsHLine(dX, dX + pixelSize - 1, dY, desktop->currentSelectionPhase(), destSurface);
- if (drawL == 1) drawVLine(dY + 1, dY + pixelSize - 1, dX, guiPacked[COLOR_GRID], destSurface);
- else if (drawL == 2) drawAntsVLine(dY, dY + pixelSize - 1, dX, desktop->currentSelectionPhase(), destSurface);
- // (B/R can only be == 2 right now)
- if (drawB) drawAntsHLine(dX, dX + pixelSize - 1, dY + pixelSize - 1, desktop->currentSelectionPhase(), destSurface);
- if (drawR) drawAntsVLine(dY, dY + pixelSize - 1, dX + pixelSize - 1, desktop->currentSelectionPhase(), destSurface);
- }
- source += pitch - (pX - opX) * 4;
- selSrc += selPitch - (pX - opX) * 4;
- }
-
- // Cursor
- if ((haveFocus) && (!hideCursor)) {
- int cX = xOffset + cursorX * pixelSize;
- int cY = yOffset + cursorY * pixelSize;
-
- if ((cX < toDisplay.x + toDisplay.w) && (cY < toDisplay.y + toDisplay.h) &&
- (cX + pixelSize + gridSize > toDisplay.x) &&
- (cY + pixelSize + gridSize > toDisplay.y)) {
- drawSelectRect(cX, cY, pixelSize + gridSize, pixelSize + gridSize,
- guiPacked[COLOR_TILECURSOR], destSurface, desktop->currentCursorAlpha());
- }
- }
-
- // Glyph width
- if (isFont) {
- int atX = xOffset + glyphWidth * pixelSize;
- int atY = yOffset + tileHeight * pixelSize;
- drawVLine(yOffset, atY,
- atX, guiPacked[COLOR_GLYPHWIDTH], destSurface);
- drawLine(atX, atY + GLYPH_SIZE_POINTER_MARGIN, atX + GLYPH_SIZE_POINTER_HEIGHT,
- atY + GLYPH_SIZE_POINTER_MARGIN + GLYPH_SIZE_POINTER_HEIGHT,
- guiPacked[COLOR_GLYPHWIDTH], destSurface);
- drawLine(atX, atY + GLYPH_SIZE_POINTER_MARGIN, atX - GLYPH_SIZE_POINTER_HEIGHT,
- atY + GLYPH_SIZE_POINTER_MARGIN + GLYPH_SIZE_POINTER_HEIGHT,
- guiPacked[COLOR_GLYPHWIDTH], destSurface);
- drawHLine(atX - GLYPH_SIZE_POINTER_HEIGHT, atX + GLYPH_SIZE_POINTER_HEIGHT,
- atY + GLYPH_SIZE_POINTER_MARGIN + GLYPH_SIZE_POINTER_HEIGHT,
- guiPacked[COLOR_GLYPHWIDTH], destSurface);
- }
- }
- }
- }
- void TilePaint::undoStoreBlitBox(int x1, int y1, int x2, int y2) throw_Undo { start_func
- if (x1 > x2) swap(x1, x2);
- if (y1 > y2) swap(y1, y2);
- undoStoreBlit(x1, y1, x2 - x1 + 1, y2 - y1 + 1);
- }
- void TilePaint::undoStoreBlit(int x, int y, int w, int h) throw_Undo { start_func
- if (isColl) world->undo.storeUndoColl(tileset->getId(), currentTile, x, y, w, h, myFrame);
- else world->undo.storeUndoTile(tileset->getId(), currentTile, x, y, w, h, myFrame);
- }
- void TilePaint::undoStoreGlyph() throw_Undo { start_func
- world->undo.storeUndoTileGlyph(tileset->getId(), currentTile, glyphWidth, myFrame);
- }
- void TilePaint::undoStoreSelect(int x, int y, int w, int h) throw_Undo { start_func
- world->undo.storeUndoPaintSelection(&selection, x, y, w, h, selectionXOffs, selectionYOffs, selectionMode, myFrame);
- }
- void TilePaint::clearSelection(int storeUndo) throw_Undo { start_func
- assert(selection);
- if (selectionRect.w) {
- if (storeUndo) undoStoreSelect(selectionRect.x, selectionRect.y, selectionRect.w, selectionRect.h);
- SDL_FillRect(selection, &selectionRect, mapColor32(0, 0, 0, 0));
- // Add in offset so proper area is dirtied
- selectionRect.x += selectionXOffs;
- selectionRect.y += selectionYOffs;
- // (don't need to set feather because we're clearing -entire- selection)
- setDirtyRect(selectionRect);
-
- selectionRect.w = 0;
- selectionXOffs = selectionYOffs = 0;
- selectionMode = SELECTION_OUTLINE;
- tools->findWidget(TilePaintTools::ID_COPY)->disable();
-
- // Was selection oversized? if so, correct this
- if ((selection->w > tileWidth) || (selection->h > tileHeight)) {
- // Ideally, if we free then alloc, this shouldn't fail
- SDL_FreeSurface(selection);
- selection = NULL;
- selection = createSurface32(tileWidth, tileHeight);
- sge_FilledRect(selection, 0, 0, tileWidth, tileHeight, mapColor32(0, 0, 0, 0));
- }
- }
- }
- void TilePaint::floatSelection() throw_Undo { start_func
- if ((selectionMode == SELECTION_OUTLINE) && (selectionRect.w)) {
- Uint32 bkColor = mapColor32(colors.bk.r, colors.bk.g, colors.bk.b, colors.bk.a);
- world->undo.preUndoBlock();
- undoStoreBlit(selectionRect.x, selectionRect.y, selectionRect.w, selectionRect.h);
- undoStoreSelect(selectionRect.x, selectionRect.y, selectionRect.w, selectionRect.h);
- world->undo.postUndoBlock();
- maskBlit32(selectionRect.x, selectionRect.y, tile, selectionRect.x, selectionRect.y, selection, selectionRect.x, selectionRect.y, selection, selectionRect.w, selectionRect.h, 1, bkColor);
- selectionMode = SELECTION_ALPHA;
- setDirtyRect(selectionRect);
- // (we fix the rect because we may have floated transparents, so the
- // actual selection may have reduced in size)
- fixSelectionRect();
- applyTile();
- // (even possible that there's no selection now)
- if (!selectionRect.w) tools->findWidget(TilePaintTools::ID_COPY)->disable();
- }
- }
- void TilePaint::doneSelection() throw_Undo { start_func
- if (selectionMode == SELECTION_OUTLINE) clearSelection();
- else mergeSelection();
- }
- void TilePaint::pasteSelection() throw_Undo { start_func
- if (canConvertClipboard(CLIPBOARD_IMAGE)) {
- world->undo.preUndoBlock();
- doneSelection();
-
- int w;
- int h;
-
- clipboardPasteImageSize(&w, &h);
-
- // Do we need a larger selection surface?
- if ((w > tileWidth) || (h > tileHeight)) {
- // (if this fails, nothing's been affected yet)
- SDL_Surface* newSel = createSurface32(max(tileWidth, w), max(tileHeight, h));
- if (selection) SDL_FreeSurface(selection);
- selection = newSel;
- sge_FilledRect(selection, 0, 0, selection->w, selection->h, mapColor32(0, 0, 0, 0));
- // (no need to undo this on exception, larger selection buffer doesn't harm us)
- }
- undoStoreSelect(0, 0, w, h);
- clipboardPasteImage(selection, 0, 0);
- world->undo.postUndoBlock();
- selectionRect.x = 0;
- selectionRect.y = 0;
- selectionRect.w = w;
- selectionRect.h = h;
- selectionMode = SELECTION_ALPHA;
-
- // Possible nothing was actually pasted
- fixSelectionRect();
- if (selectionRect.w) {
- tools->findWidget(TilePaintTools::ID_COPY)->enable();
-
- // @TODO: Move selection to ensure it's visible
- }
- // Dirty
- setDirtyRect(selectionRect);
- }
- }
- void TilePaint::copySelection() { start_func
- if (selectionRect.w) {
- if (selectionMode == SELECTION_OUTLINE) {
- // We copy to backup selection so we don't affect our outline
- sge_FilledRect(backupSelection, 0, 0, tileWidth, tileHeight, mapColor32(0, 0, 0, 0));
- maskBlit32(selectionRect.x, selectionRect.y, tile, selectionRect.x, selectionRect.y, backupSelection, selectionRect.x, selectionRect.y, selection, selectionRect.w, selectionRect.h);
- clipboardCopy(backupSelection, selectionRect.x, selectionRect.y, selectionRect.w, selectionRect.h);
- }
- else {
- // We copy what's in the floating selection
- clipboardCopy(selection, selectionRect.x, selectionRect.y, selectionRect.w, selectionRect.h);
- }
- }
- }
- void TilePaint::deleteSelection() throw_Undo { start_func
- if ((selectionMode == SELECTION_OUTLINE) && (selectionRect.w)) {
- // Delete where outline is
- Uint32 bkColor = mapColor32(colors.bk.r, colors.bk.g, colors.bk.b, colors.bk.a);
- undoStoreBlit(selectionRect.x, selectionRect.y, selectionRect.w, selectionRect.h);
- maskBlit32(selectionRect.x, selectionRect.y, tile, selectionRect.x, selectionRect.y, tile, selectionRect.x, selectionRect.y, selection, selectionRect.w, selectionRect.h, 1, bkColor);
- setDirtyRect(selectionRect);
- applyTile();
- }
- else if (selectionRect.w) {
- // Delete floating selection
- clearSelection();
- }
- }
- void TilePaint::mergeSelection() throw_Undo { start_func
- // (no tileset = closing)
- if (((selectionMode == SELECTION_OPAQUE) || (selectionMode == SELECTION_ALPHA)) && (tileset)) {
- world->undo.preUndoBlock();
- // Paste selection, with offset
- if (selectionRect.w) {
- undoStoreBlit(selectionRect.x + selectionXOffs, selectionRect.y + selectionYOffs, selectionRect.w, selectionRect.h);
- if (selectionMode == SELECTION_OPAQUE) {
- maskBlit32(selectionRect.x, selectionRect.y, selection, selectionRect.x + selectionXOffs, selectionRect.y + selectionYOffs, tile, selectionRect.x, selectionRect.y, selection, selectionRect.w, selectionRect.h);
- }
- else {
- maskAlphaBlit32(selectionRect.x, selectionRect.y, selection, selectionRect.x + selectionXOffs, selectionRect.y + selectionYOffs, tile, selectionRect.x, selectionRect.y, selection, alphaBlend, selectionRect.w, selectionRect.h);
- }
- }
-
- // Clear selection
- clearSelection();
- world->undo.postUndoBlock();
- applyTile();
- }
- }
- int TilePaint::isInSelection(int x, int y) { start_func
- if (!selectionRect.w) return 0;
- x -= selectionXOffs;
- y -= selectionYOffs;
- Uint8* source = (Uint8*)selection->pixels + y * selection->pitch + x * 4;
- return source[3];
- }
- void TilePaint::fixSelectionRect() { start_func
- assert(selection);
- int minX = -1;
- int maxX;
- int minY;
- int maxY;
-
- Uint8* source = (Uint8*)selection->pixels;
- int pitchOffs = selection->pitch - selection->w * 4;
- // We use size of selection surface insetad of tile size, on purpose
- for (int y = 0; y < selection->h; ++y) {
- for (int x = 0; x < selection->w; ++x) {
- if (source[3]) {
- if (minX == -1) {
- minX = maxX = x;
- minY = maxY = y;
- }
- else {
- if (x < minX) minX = x;
- else if (x > maxX) maxX = x;
- if (y < minY) minY = y;
- else if (y > maxY) maxY = y;
- }
- }
- source += 4;
- }
- source += pitchOffs;
- }
-
- if (minX == -1) {
- selectionRect.w = 0;
- }
- else {
- selectionRect = createRect(minX, minY, maxX, maxY);
- }
- }
- void TilePaint::mousePointer(int mouseX, int mouseY) { start_func
- lastMouseX = mouseX;
- lastMouseY = mouseY;
- mousePointer();
- }
- void TilePaint::mousePointer() { start_func
- if (!hover) return;
- if ((toolActive == TOOLS_SELECT) || (toolActive == TOOLS_SELECTELLIPSE) || (toolActive == TOOLS_WAND)) {
- if (toolAlt) {
- selectMouse(MOUSE_SUBTRACT);
- return;
- }
- else if (toolCtrl) {
- selectMouse(MOUSE_ADD);
- return;
- }
- }
- if (toolActive == TOOLS_GLYPHWIDTHDRAG) {
- selectMouse(MOUSE_HORIZ);
- return;
- }
- if (toolActive == TOOLS_SELECTDRAG) {
- selectMouse(MOUSE_FOURDIRECTION);
- return;
- }
- if ((!toolActive) && ((tool == TOOLS_SELECT) || (tool == TOOLS_SELECTELLIPSE) || (tool == TOOLS_WAND))) {
- if (SDL_GetModState() & KMOD_ALT) {
- selectMouse(MOUSE_SUBTRACT);
- return;
- }
- if (SDL_GetModState() & KMOD_CTRL) {
- selectMouse(MOUSE_ADD);
- return;
- }
-
- if (isInSelection(lastMouseX, lastMouseY)) {
- selectMouse(MOUSE_FOURDIRECTION);
- return;
- }
- }
- if ((!toolActive) && (lastMouseY >= tileHeight) && (isFont)) {
- selectMouse(MOUSE_HORIZ);
- return;
- }
-
- selectMouse(MOUSE_PIXEL);
- }
- Window::CommandSupport TilePaint::supportsCommand(int code) const { start_func
- switch (code) {
- // Options
- case VIEW_DOTS_NONE:
- case VIEW_DOTS_TRANS:
- case VIEW_DOTS_ALPHA:
- if (isColl) return Window::COMMAND_HIDE;
- return (Window::CommandSupport)(((drawDots == code) ? Window::COMMAND_SELECTED : 0) | Window::COMMAND_RADIO | Window::COMMAND_ENABLE);
-
- case VIEW_GRID:
- return (Window::CommandSupport)((enableGrid ? Window::COMMAND_SELECTED : 0) | Window::COMMAND_CHECKBOX | Window::COMMAND_ENABLE);
- case TOOLS_ANTIALIAS:
- if (isColl) return Window::COMMAND_HIDE;
- if ((tool == TOOLS_WAND) || (tool == TOOLS_FILL)) return Window::COMMAND_HIDE;
- if ((tool == TOOLS_LINE) || (tool == TOOLS_ELLIPSE) || (tool == TOOLS_ELLIPSEFILL)) {
- return (Window::CommandSupport)((antiAlias ? Window::COMMAND_SELECTED : 0) | Window::COMMAND_CHECKBOX | Window::COMMAND_ENABLE);
- }
- else return (Window::CommandSupport)((antiAlias ? Window::COMMAND_SELECTED : 0) | Window::COMMAND_CHECKBOX | Window::COMMAND_DISABLE);
- case TOOLS_CONTIGUOUS:
- if ((tool == TOOLS_WAND) || (tool == TOOLS_FILL)) {
- return (Window::CommandSupport)((antiAlias ? Window::COMMAND_SELECTED : 0) | Window::COMMAND_CHECKBOX | Window::COMMAND_ENABLE);
- }
- else return Window::COMMAND_HIDE;
- case TOOLS_DROPPER:
- if (isColl) return Window::COMMAND_HIDE;
- return (Window::CommandSupport)(((tool == code) ? Window::COMMAND_SELECTED : 0) | Window::COMMAND_RADIO | Window::COMMAND_ENABLE);
-
- case TOOLS_PEN:
- case TOOLS_LINE:
- case TOOLS_RECT:
- case TOOLS_RECTFILL:
- case TOOLS_ELLIPSE:
- case TOOLS_ELLIPSEFILL:
- case TOOLS_SELECT:
- case TOOLS_SELECTELLIPSE:
- case TOOLS_FILL:
- case TOOLS_WAND:
- return (Window::CommandSupport)(((tool == code) ? Window::COMMAND_SELECTED : 0) | Window::COMMAND_RADIO | Window::COMMAND_ENABLE);
- case VIEW_DOTS_CHOOSE:
- case TOOLS_BLENDUP:
- case TOOLS_BLENDDOWN:
- case TOOLS_EDITCOLOR:
- return isColl ? Window::COMMAND_HIDE : Window::COMMAND_ENABLE;
-
- // These are always available
- case TOOLS_CHOOSE:
- case VIEW_PREV:
- case VIEW_NEXT:
- case EDIT_SELECTALL:
- case TOOLS_SETTINGS:
- case TOOLS_NEXTCOLOR:
- case TOOLS_PREVCOLOR:
- return Window::COMMAND_ENABLE;
- case TOOLS_TOLERANCEUP:
- case TOOLS_TOLERANCEDOWN:
- if (isColl) return Window::COMMAND_HIDE;
- if ((tool == TOOLS_WAND) || (tool == TOOLS_FILL)) return Window::COMMAND_ENABLE;
- else return Window::COMMAND_DISABLE;
- case EDIT_COPY:
- case EDIT_CUT:
- case EDIT_DELETE:
- case EDIT_DESELECTALL:
- if (selectionRect.w) return Window::COMMAND_ENABLE;
- else return Window::COMMAND_DISABLE;
-
- case EDIT_PASTE:
- if (canConvertClipboard(CLIPBOARD_IMAGE)) return Window::COMMAND_ENABLE;
- else return Window::COMMAND_DISABLE;
-
- case EDIT_SETGLYPHWIDTH:
- if (isFont) return Window::COMMAND_ENABLE;
- return Window::COMMAND_HIDE;
-
- case VIEW_ZOOMIN:
- if (pixelSize >= MAX_ZOOM) return Window::COMMAND_DISABLE;
- else return Window::COMMAND_ENABLE;
-
- case VIEW_ZOOMOUT:
- if (pixelSize == 1) return Window::COMMAND_DISABLE;
- else return Window::COMMAND_ENABLE;
-
- // These aren't done yet (remember some may not be appropriate for isColl)
- case EDIT_FLIP:
- case EDIT_MIRROR:
- case EDIT_SIZEROTATE:
- case EDIT_GRADIENT:
- case EDIT_COLORIZE:
- case EDIT_FILTER:
- return Window::COMMAND_DISABLE;
- }
-
- return world->supportsCommand(code);
- }
- void TilePaint::startToolIfMove() { start_func
- startToolOnMove = 1;
- }
- void TilePaint::refresh() { start_func
- if (pixelSize >= MAX_ZOOMGRID) changePixelSizing(pixelSize, enableGrid ? 1 : 0);
- else changePixelSizing(pixelSize, 0);
- setDirty(1);
- }
- void TilePaint::undoNotify(int undoType, int undoItemId, int undoItemSubId, int uX, int uY, int uW, int uH) { start_func
- if ((undoType == UndoBuffer::UNDO_TILE) ||
- (undoType == UndoBuffer::UNDO_TILECOLL) ||
- (undoType == UndoBuffer::UNDO_TILEGLYPH)) {
- assert(tileset->getId() == undoItemId);
-
- // Ensure proper tile is selected
- changeTile(undoItemSubId);
-
- // Scroll?
- if ((myFrame) && (undoType != UndoBuffer::UNDO_TILEGLYPH)) {
- myFrame->scrollToView(uX * pixelSize, uY * pixelSize,
- uW * pixelSize, uH * pixelSize);
- }
- }
- if (undoType == UndoBuffer::UNDO_PAINTSEL) {
- // Scroll?
- if (myFrame) myFrame->scrollToView(uX * pixelSize, uY * pixelSize,
- uW * pixelSize, uH * pixelSize);
- }
- }
- void TilePaint::swapSelectionParameters(int& xoffs, int& yoffs, int& mode) { start_func
- swap(xoffs, selectionXOffs);
- swap(yoffs, selectionYOffs);
- swap(mode, selectionMode);
- // Refresh
- fixSelectionRect();
- setDirty(1);
- }
- Window::WindowType TilePaint::windowType() const { start_func
- return WINDOW_CLIENT;
- }
|