ide: IconDes code moved to ide/IconDes

This commit is contained in:
Mirek Fidler 2024-07-28 17:05:28 +02:00
parent 5a2e47a495
commit e1c1b82a11
31 changed files with 1395 additions and 1519 deletions

View file

@ -1,22 +0,0 @@
Copyright (c) 1998, 2024, The U++ Project
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 COPYRIGHT HOLDER 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.

View file

@ -1,689 +0,0 @@
#include "IconDes.h"
namespace Upp {
void IconDes::MaskSelection()
{
Slot& c = Current();
ImageBuffer ib(c.image);
Size isz = ib.GetSize();
CoFor(isz.cy, [&](int y) {
RGBA *t = ib[y];
const RGBA *e = t + isz.cx;
const RGBA *s = c.base_image[y];
const RGBA *k = c.selection[y];
while(t < e) {
if(!k->r)
*t = *s;
t++;
s++;
k++;
}
});
Current().image = ib;
Refresh();
SyncShow();
}
IconDes::Slot& IconDes::Current()
{
if(ilist.IsCursor())
return slot[ilist.GetKey()];
NEVER();
return dummy;
}
Image& IconDes::CurrentImage()
{
return doselection ? Current().selection : Current().image;
}
Size IconDes::GetImageSize()
{
return IsCurrent() ? Current().image.GetSize() : Size(0, 0);
}
bool IconDes::InImage(int x, int y)
{
if(!IsCurrent())
return false;
Size sz = GetImageSize();
return x >= 0 && x < sz.cx && y >= 0 && y < sz.cy;
}
void IconDes::SyncShow()
{
iconshow.image.Clear();
if(IsCurrent()) {
Slot& c = Current();
iconshow.image = c.image;
iconshow.flags = c.flags;
iconshow.show_downscaled = show_downscaled;
iconshow.show_synthetics = show_synthetics;
ilist.Set(2, RawToValue(MakeTuple(c.image, c.flags)));
}
iconshow.Refresh();
}
void IconDes::SetSb()
{
magnify = max(magnify, 1);
if(IsCurrent()) {
sb.SetTotal(GetImageSize());
sb.SetPage(GetSize() / magnify);
}
}
void IconDes::Scroll()
{
magnify = max(magnify, 1);
Refresh();
}
void IconDes::Layout()
{
SetSb();
}
void IconDes::SetCurrentImage(ImageBuffer& ib)
{
CurrentImage() = ib;
Refresh();
SyncShow();
}
Point IconDes::GetPos(Point p)
{
return p / max(magnify, 1) + sb;
}
void IconDes::FinishPaste()
{
CloseText();
if(IsCurrent()) {
Current().pastepos = Null;
Current().base_image.Clear();
}
Refresh();
rgbactrl.Show();
}
void IconDes::MakePaste()
{
if(!IsCurrent() || !IsPasting())
return;
Slot& c = Current();
c.image = c.base_image;
if(paste_mode == PASTE_OPAQUE)
UPP::Copy(c.image, c.pastepos, c.paste_image, c.paste_image.GetSize());
else
if(paste_mode == PASTE_BACK) {
Image h = c.image;
UPP::Copy(c.image, c.pastepos, c.paste_image, c.paste_image.GetSize());
UPP::Over(c.image, Point(0, 0), h, c.image.GetSize());
}
else
UPP::Over(c.image, c.pastepos, Premultiply(c.paste_image), c.paste_image.GetSize());
MaskSelection();
}
void IconDes::DoBuffer(Event<ImageBuffer&> tool)
{
Size isz = GetImageSize();
Image h = Current().base_image;
ImageBuffer ib(h);
tool(ib);
CurrentImage() = ib;
if(!doselection)
MaskSelection();
Refresh();
}
void IconDes::DoPainter(Event<Painter&> tool)
{
DoBuffer([&](ImageBuffer& ib) {
BufferPainter iw(ib);
iw.Co();
iw.Translate(0.5, 0.5);
tool(iw);
});
}
void IconDes::DoDraw(Event<IconDraw&> tool)
{
DoBuffer([&](ImageBuffer& ib) {
IconDraw iw(ib);
tool(iw);
});
}
void IconDes::DoTool(Event<IconDraw&> tool, Event<Painter&> aa_tool)
{
if(antialiased && !doselection)
DoPainter(aa_tool);
else
DoDraw(tool);
}
void IconDes::LineTool(Point p, dword flags)
{
RGBA c = CurrentColor();
DoTool(
[&](IconDraw& iw) {
iw.DrawLine(startpoint, p, pen, c);
if(pen == 1 && Rect(iw.image.GetSize()).Contains(p))
iw.image[p.y][p.x] = c;
},
[&](Painter& sw) {
sw.Move(startpoint).Line(p).Stroke(pen, c);
}
);
}
void IconDes::EllipseTool0(Point p, dword flags, bool fill_empty)
{
RGBA c = CurrentColor();
DoTool(
[&](IconDraw& iw) {
iw.DrawEllipse(Rect(startpoint, p), fill_empty,
doselection ? c : RGBAZero(), pen, c);
},
[&](Painter& sw) {
sw.DrawEllipse(Rect(startpoint, p).Normalized(),
fill_empty ? LtGray() : Null, pen, c);
}
);
}
void IconDes::EllipseTool(Point p, dword flags)
{
EllipseTool0(p, flags, Null);
}
void IconDes::EmptyEllipseTool(Point p, dword flags)
{
EllipseTool0(p, flags, GrayColor(128));
}
void IconDes::RadialTool(Point p, dword f)
{
DoPainter([&](Painter& iw) {
double r = Distance(startpoint, p);
iw.Circle(startpoint.x, startpoint.y, Distance(startpoint, p))
.Fill(startpoint.x, startpoint.y, startcolor, r, CurrentColor());
});
}
void IconDes::LinearTool(Point p, dword f)
{
DoPainter([&](Painter& iw) {
Pointf pf = p;
Pointf sf = startpoint;
Pointf vec = 10000 * Orthogonal(sf - pf);
iw.Move(sf - vec).Line(pf - vec).Line(pf + vec).Line(sf + vec)
.Fill(sf, startcolor, pf, CurrentColor());
});
}
void IconDes::RectTool0(Point p, dword flags, bool empty)
{
DoDraw([&](IconDraw& iw) {
rect = Rect(startpoint, p + 1).Normalized();
Size sz = rect.GetSize();
if(empty)
iw.DrawRect(rect.left, rect.top, sz.cx, sz.cy,
doselection ? CurrentColor() : RGBAZero());
iw.DrawFrame(rect.left, rect.top, sz.cx, sz.cy, CurrentColor(), pen);
});
}
void IconDes::RectTool(Point p, dword flags)
{
RectTool0(p, flags, false);
}
void IconDes::EmptyRectTool(Point p, dword flags)
{
RectTool0(p, flags, true);
}
void IconDes::Freehand(Point p, int pen)
{
DoDraw([&](IconDraw& iw) {
iw.DrawRect(p.x - pen / 2, p.y - pen / 2, pen, pen, CurrentColor());
iw.DrawLine(startpoint, p, pen, CurrentColor());
});
Current().base_image = CurrentImage();
startpoint = p;
}
void IconDes::FreehandTool(Point p, dword flags)
{
Freehand(p, pen);
}
void IconDes::DoFill(int tolerance)
{
Image src = Current().image;
ImageBuffer ib(CurrentImage());
if(!doselection) {
RGBA c = CurrentColor();
c.r += 127;
MaskFill(ib, c, 0);
}
FloodFill(src, ib, CurrentColor(), startpoint, tolerance);
SetCurrentImage(ib);
if(!doselection)
MaskSelection();
}
void IconDes::HotSpotTool(Point p, dword f)
{
if(p != Current().image.GetHotSpot()) {
ImageBuffer ib(Current().image);
ib.SetHotSpot(p);
Current().image = ib;
Refresh();
}
}
Image IconDes::MakeIconDesCursor(const Image& arrow, const Image& cmask)
{
RGBA c = CurrentColor();
c.a = 255;
Image ucmask = Unmultiply(cmask);
ImageBuffer ib(ucmask.GetSize());
const RGBA *m = ~ucmask;
RGBA *t = ~ib;
RGBA *e = ib.End();
while(t < e) {
*t = c;
t->a = m->a;
m++;
t++;
}
Image cm(ib);
Image r = arrow;
Over(r, Point(0, 0), Premultiply(cm), r.GetSize());
return r;
}
void IconDes::ColorChanged()
{
cursor_image = MakeIconDesCursor(IconDesImg::Arrow(), IconDesImg::ArrowColor());
cursor_image_free = MakeIconDesCursor(IconDesImg::Arrow(), IconDesImg::ArrowColorFree());
fill_cursor = MakeIconDesCursor(IconDesImg::Fill(), IconDesImg::FillColor());
fill_cursor2 = MakeIconDesCursor(IconDesImg::Fill2(), IconDesImg::FillColor());
fill_cursor3 = MakeIconDesCursor(IconDesImg::Fill3(), IconDesImg::FillColor());
antifill_cursor = MakeIconDesCursor(IconDesImg::Fill(), IconDesImg::AntiFill());
PasteText();
SetBar();
}
void IconDes::SetTool(void (IconDes::*_tool)(Point p, dword flags))
{
FinishPaste();
if(HasCapture())
ReleaseCapture();
tool = _tool;
SetBar();
}
RGBA IconDes::CurrentColor()
{
return rgbactrl.Get();
}
void IconDes::Paste(const Image& img)
{
FinishPaste();
if(!IsCurrent())
return;
SaveUndo();
Slot& c = Current();
c.base_image = c.image;
c.paste_image = img;
c.pastepos = Point(0, 0);
MakePaste();
SetBar();
}
Rect IconDes::SelectionRect()
{
if(!IsCurrent())
return Null;
Size isz = GetImageSize();
int minx = isz.cx - 1;
int maxx = 0;
int miny = isz.cy - 1;
int maxy = 0;
for(int y = 0; y < isz.cy; y++) {
const RGBA *k = Current().selection[y];
for(int x = 0; x < isz.cx; x++)
if((k++)->r == 255) {
if(x < minx) minx = x;
if(x > maxx) maxx = x;
if(y < miny) miny = y;
if(y > maxy) maxy = y;
}
}
return Rect(minx, miny, maxx + 1, maxy + 1);
}
Image IconDes::Copy(const Rect& r)
{
if(!IsCurrent() || r.IsEmpty())
return Image();
Slot& c = Current();
if(Rect(GetImageSize()) == r) // return whole image with correct hotspots
return c.image;
ImageBuffer ib(r.GetSize());
for(int y = r.top; y < r.bottom; y++) {
const RGBA *s = c.image[y] + r.left;
const RGBA *e = c.image[y] + r.right;
const RGBA *k = c.selection[y] + r.left;
RGBA *t = ib[y - r.top];
while(s < e) {
*t = *s;
if(!k->r)
*t = RGBAZero();
t++;
k++;
s++;
}
}
return ib;
}
void IconDes::Delete()
{
SetColor0(RGBAZero());
}
void IconDes::SetSelect(int a)
{
if(!IsCurrent())
return;
ImageBuffer ib(GetImageSize());
memset(ib, a, ib.GetLength() * sizeof(RGBA));
Current().selection = ib;
Refresh();
}
void IconDes::Select()
{
if(!IsCurrent())
return;
ReleaseCapture();
FinishPaste();
doselection = !doselection;
rgbactrl.Mask(doselection);
if(doselection && SelectionRect() == GetImageSize()) {
SetSelect(0);
rgbactrl.MaskSet(255);
}
Refresh();
SetBar();
}
void IconDes::CancelSelect()
{
ReleaseCapture();
doselection = false;
rgbactrl.Mask(false);
FinishPaste();
SetSelect(255);
SetBar();
}
void IconDes::InvertSelect()
{
if(!IsCurrent())
return;
ImageBuffer ib(Current().selection);
RGBA *s = ib;
const RGBA *e = s + ib.GetLength();
while(s < e) {
s->r = s->g = s->b = s->a = ~s->r;
s++;
}
Current().selection = ib;
Refresh();
}
void IconDes::Move()
{
if(!IsCurrent())
return;
Slot& c = Current();
selectrect = false;
if(IsPasting())
FinishPaste();
else {
doselection = false;
rgbactrl.Mask(false);
rgbactrl.Hide();
Rect r = SelectionRect();
Image m = Copy(r);
Delete();
SetSelect(255);
c.base_image = c.image;
c.paste_image = m;
c.pastepos = r.TopLeft();
MakePaste();
}
SetBar();
}
void IconDes::SelectRect()
{
doselection = false;
Select();
selectrect = true;
rect = Null;
SetBar();
}
String PackUndo(const Vector<ImageIml>& img)
{
return FastCompress(PackImlDataUncompressed(img));
}
Vector<ImageIml> UnpackUndo(const String& data)
{
return UnpackImlDataUncompressed(FastDecompress(data));
}
void IconDes::SaveUndo()
{
if(!IsCurrent())
return;
Slot& c = Current();
Vector<ImageIml> undo = UnpackUndo(c.undo);
int maxn = minmax((single_mode ? 40000000 : 2000000) / max((int)c.image.GetLength(), 1), 4, 128);
while(undo.GetCount() > maxn)
undo.Remove(0);
if(undo.GetCount() && undo.Top().image == c.image)
return;
undo.Add().image = c.image;
c.undo = PackUndo(undo);
c.redo.Clear();
SetBar();
undo.Clear();
}
void IconDes::Undo()
{
if(!IsCurrent())
return;
Slot& c = Current();
Vector<ImageIml> undo = UnpackUndo(c.undo);
if(undo.GetCount() == 0)
return;
Vector<ImageIml> redo = UnpackUndo(c.redo);
redo.Add().image = c.image;
c.image = undo.Pop().image;
c.undo = PackUndo(undo);
c.redo = PackUndo(redo);
SyncImage();
SetBar();
}
void IconDes::Redo()
{
if(!IsCurrent())
return;
Slot& c = Current();
Vector<ImageIml> redo = UnpackUndo(c.redo);
if(redo.GetCount() == 0)
return;
Vector<ImageIml> undo = UnpackUndo(c.undo);
undo.Add().image = c.image;
c.image = redo.Pop().image;
c.undo = PackUndo(undo);
c.redo = PackUndo(redo);
SyncImage();
SetBar();
}
void IconDes::SyncImage()
{
ReleaseCapture();
SyncShow();
if(IsCurrent()) {
Slot& c = Current();
SyncShow();
c.pastepos = Null;
if(c.selection.GetSize() != c.image.GetSize())
SetSelect(255);
if(single_mode)
info.SetLabel(Format("%d x %d", c.image.GetWidth(), c.image.GetHeight()));
}
selectrect = false;
SyncList();
SetBar();
Refresh();
}
void IconDes::Reset()
{
SetSelect(255);
SyncImage();
}
void IconDes::MaskFill(ImageBuffer& ib, RGBA color, int mask)
{
if(!IsCurrent())
return;
if(doselection)
Fill(ib, color, ib.GetLength());
else {
RGBA *t = ib;
RGBA *e = ib + ib.GetLength();
const RGBA *s = Current().selection;
while(t < e) {
if((s++)->r == mask)
*t = color;
t++;
}
}
}
void IconDes::SetColor0(RGBA color)
{
FinishPaste();
doselection = false;
rgbactrl.Mask(false);
SaveUndo();
ImageBuffer ib(Current().image);
MaskFill(ib, color, 255);
Refresh();
SetCurrentImage(ib);
SyncShow();
SetBar();
}
void IconDes::SetColor()
{
SetColor0(CurrentColor());
}
void IconDes::DoDelete()
{
SetColor0(RGBAZero());
}
void IconDes::BeginResize()
{
CancelSelect();
FinishPaste();
SaveUndo();
Refresh();
SyncShow();
}
void IconDes::ResizeUp()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = Magnify(c.image, 3, 3);
Reset();
}
void IconDes::ResizeDown()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = (c.image.GetSize() / 3).IsEmpty() ? CreateImage(Size(1, 1), White)
: DownSample3x(c.image);
Reset();
}
void IconDes::ResizeUp2()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = Magnify(c.image, 2, 2);
Reset();
}
void IconDes::ResizeDown2()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = (c.image.GetSize() / 3).IsEmpty() ? CreateImage(Size(1, 1), White)
: DownSample2x(c.image);
Reset();
}
void IconDes::Upscale()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = Upscale2x(c.image);
Reset();
}
void IconDes::SingleMode()
{
single_mode = true;
ilist.Ctrl::Remove();
rgbactrl.SubCtrl(&single);
Size fsz = GetTextSize("Resize", StdFont());
single.Add(info.HSizePos().TopPos(0, fsz.cy));
resize.SetLabel("Resize");
single.Add(resize.LeftPos(0, fsz.cx + 2 * fsz.cy).TopPos(4 * fsz.cy / 3, 4 * fsz.cy / 3));
resize <<= THISBACK(EditImage);
}
}

View file

@ -1,462 +0,0 @@
#ifndef _IconDes_IconDes_h_
#define _IconDes_IconDes_h_
#include <CtrlLib/CtrlLib.h>
#include <Painter/Painter.h>
#include <RichEdit/RichEdit.h>
#include <plugin/bmp/bmp.h>
namespace Upp {
#define IMAGECLASS IconDesImg
#define IMAGEFILE <IconDes/IconDes.iml>
#include <Draw/iml_header.h>
#define LAYOUTFILE <IconDes/IconDes.lay>
#include <CtrlCore/lay.h>
#define KEYNAMESPACE IconDesKeys
#define KEYGROUPNAME "Icon designer"
#define KEYFILE <IconDes/IconDes.key>
#include <CtrlLib/key_header.h>
class AlphaCtrl : public Ctrl {
public:
virtual void Layout();
virtual void Paint(Draw& w);
virtual void LeftDown(Point p, dword keyflags);
virtual void MouseMove(Point p, dword keyflags);
private:
Image img;
Color color;
int alpha;
bool mask;
int maskvalue;
void MakeImage();
void DoPoint(Point p);
public:
void SetColor(Color c);
void Set(int a);
int Get() const;
void Mask(bool m);
bool IsMask() const { return mask; }
AlphaCtrl();
};
class RGBACtrl : public Ctrl {
public:
virtual void Paint(Draw& w);
virtual void Layout();
virtual void LeftDown(Point p, dword keyflags);
virtual void MouseMove(Point p, dword keyflags);
private:
Size cbox;
Point cs;
enum { COLORCOUNT = 216 + 18 + 18 };
Color color;
ColorRampCtrl ramp;
AlphaCtrl alpha;
EditString text;
FrameRight<Button> setcolor;
Ptr<Ctrl> subctrl;
Color GetColor(int i) const;
void Ramp();
void Alpha();
void SyncText();
int DoLayout(Size sz, bool set);
public:
typedef RGBACtrl CLASSNAME;
void Set(RGBA c);
void MaskSet(int a);
RGBA Get() const;
Color GetColor() const;
int GetAlpha() const;
void Mask(bool b);
void SubCtrl(Ctrl *c);
int GetHeight(int cx);
RGBACtrl();
};
struct IconShow : public Ctrl {
Image image;
bool show_downscaled;
bool show_synthetics;
dword flags;
void Paint(Draw& w);
IconShow() { BackPaint(); }
};
void FloodFill(const Image& source, ImageBuffer& target, RGBA color, Point pt, int tolerance);
void InterpolateImage(Image& img, const Rect& _rc);
void MirrorHorz(Image& img, const Rect& rect);
void MirrorVert(Image& img, const Rect& rect);
String PackImlDataUncompressed(const Vector<ImageIml>& image);
String PackImlData(const Vector<ImageIml>& image);
struct IconDraw : DDARasterizer {
RGBA docolor;
ImageBuffer& image;
virtual void PutHorz(int x, int y, int cx);
virtual void PutVert(int x, int y, int cy);
void DrawRect(int x, int y, int cx, int cy, RGBA color);
void DrawFrame(int x, int y, int cx, int cy, RGBA color, int n);
void DrawLine(Point p1, Point p2, int width, RGBA color);
void DrawEllipse(const Rect& r, bool fill_empty, RGBA color, int pen, RGBA pencolor);
IconDraw(ImageBuffer& image) : image(image) { Cy(image.GetHeight()); }
};
class IconDes : public Ctrl {
public:
virtual void Layout();
virtual void Paint(Draw& w);
virtual void LeftDown(Point p, dword keyflags);
virtual void MouseMove(Point p, dword keyflags);
virtual void MouseEnter(Point, dword) { SyncStatus(); }
virtual void MouseLeave() { SyncStatus(); }
virtual void LeftUp(Point p, dword keyflags);
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
virtual void HorzMouseWheel(Point pt, int zdelta, dword keyflags);
virtual void RightDown(Point p, dword keyflags);
virtual bool Key(dword key, int count);
virtual Image CursorImage(Point p, dword keyflags);
private:
struct Slot {
String name;
Image image;
Image base_image;
Image selection;
Point pastepos = Null;
Image paste_image;
String undo;
String redo;
bool exp = false;
dword flags = 0;
};
enum {
PASTE_TRANSPARENT, PASTE_OPAQUE, PASTE_BACK
};
Array<Slot> slot;
Slot dummy;
int magnify;
int pen;
Point startpoint;
Point scroll_start = Null;
Point scroll_base;
RGBA startcolor = RGBAZero();
Rect m1refresh;
void (IconDes::*tool)(Point p, dword flags);
bool doselection = false;
bool selectrect = false;
int paste_mode;
bool show_synthetics = false;
bool show_downscaled = false;
bool show_grid2 = false;
bool antialiased = false;
int fill_type = 0;
ScrollBars sb;
ToolBar toolbar;
SplitterFrame leftpane;
SplitterFrame bottompane;
ParentCtrl imgs;
ArrayCtrl ilist;
EditString search;
RGBACtrl rgbactrl;
IconShow iconshow;
Image cursor_image, cursor_image_free;
Image fill_cursor, fill_cursor2, fill_cursor3, antifill_cursor;
bool single_mode;
ParentCtrl single;
Label info;
Button resize;
Array<Slot> removed;
FrameRight<Label> status;
int syncinglist = 0;
Rect rect;
struct TextDlg : WithIconDesTextLayout<TopWindow> {
typedef TextDlg CLASSNAME;
Font GetFont();
TextDlg();
};
TextDlg textdlg;
void DoBuffer(Event<ImageBuffer&> tool);
void DoPainter(Event<Painter&> tool);
void DoDraw(Event<IconDraw&> tool);
void DoTool(Event<IconDraw&> tool, Event<Painter&> aa_tool);
void LineTool(Point p, dword f);
void Freehand(Point p, int pen);
void FreehandTool(Point p, dword f);
void EllipseTool0(Point p, dword flags, bool fill_empty);
void EllipseTool(Point p, dword f);
void EmptyEllipseTool(Point p, dword f);
void RadialTool(Point p, dword f);
void LinearTool(Point p, dword f);
void RectTool0(Point p, dword f, bool empty);
void RectTool(Point p, dword f);
void EmptyRectTool(Point p, dword f);
void HotSpotTool(Point p, dword f);
void DoFill(int tolerance);
void Text();
void PasteText();
void CloseText();
bool IsCurrent() { return !IsNull(ilist.GetKey()); }
Slot& Current();
Image& CurrentImage();
void SetCurrentImage(ImageBuffer& ib);
RGBA CurrentColor();
Size GetImageSize();
bool InImage(int x, int y);
bool InImage(Point p) { return InImage(p.x, p.y); }
bool IsHotSpot() const { return tool == &IconDes::HotSpotTool; }
Image MakeIconDesCursor(const Image& arrow, const Image& cmask);
void SyncShow();
Point GetPos(Point p);
void ApplyImage(Image m, dword flags, bool alpha = false);
void SyncImage();
void Reset();
bool IsPasting() { return IsCurrent() && !IsNull(Current().pastepos); }
void MakePaste();
void Paste(const Image& img);
void FinishPaste();
void SetSelect(int a);
Rect SelectionRect();
void Select();
void InvertSelect();
void CancelSelect();
void SelectRect();
Image Copy(const Rect& r);
void Delete();
void Move();
void MaskSelection();
void SetSb();
void Scroll();
void SetTool(void (IconDes::*tool)(Point p, dword flags));
void SetMagnify(int mag);
void ZoomIn();
void ZoomOut();
void SetPen(int pen);
void MainToolBar(Bar& bar);
void SetBar();
void SaveUndo();
void Undo();
void Redo();
void DoPaste();
void DoCopy();
void DoCut();
void ColorChanged();
void MaskFill(ImageBuffer& ib, RGBA color, int mask);
void SetColor0(RGBA color);
void SetColor();
void DoDelete();
void Interpolate();
bool BeginTransform();
void MirrorX();
void MirrorY();
void SymmX();
void SymmY();
void FreeRotate();
void Rotate();
void SmoothRescale();
void KeyMove(int dx, int dy);
void BeginResize();
void ResizeUp();
void ResizeDown();
void ResizeUp2();
void ResizeDown2();
void Upscale();
void PlaceDlg(TopWindow& dlg);
void Couple(TopWindow& dlg, EditDouble& level, SliderCtrl& slider, double max, double init = 0);
void Couple(TopWindow& dlg, EditInt& level, SliderCtrl& slider, int max, int init = 0);
Image ImageStart();
void ImageSet(const Image& m);
void BlurSharpen();
void Colorize();
void Chroma();
void Contrast();
void Alpha();
void Colors();
void Smoothen();
void RemoveAlpha();
void Search();
void GoTo(int q);
void SyncList();
void ListCursor();
void PrepareImageDlg(WithImageLayout<TopWindow>& dlg);
void PrepareImageSizeDlg(WithImageSizeLayout<TopWindow>& dlg);
void SyncDlg(WithImageLayout<TopWindow>& dlg);
dword GetFlags(WithImageLayout<TopWindow>& dlg);
Slot& ImageInsert(int ii, const String& name, const Image& m, bool exp = false);
Slot& ImageInsert(const String& name, const Image& m, bool exp = false);
void Slice();
void InsertImage();
void InsertRemoved(int ii);
void EditImageSize();
void EditImage();
void RemoveImage();
void Duplicate();
void InsertPaste();
void InsertFile();
void ExportPngs();
void MoveSlot(int d);
void ChangeSlot(int d);
void DnDInsert(int line, PasteClip& d);
void Drag();
static FileSel& ImgFile();
static String FormatImageName(const Slot& c);
public:
virtual void ToolEx(Bar& bar);
virtual void ListMenuEx(Bar& bar);
void ListMenu(Bar& bar);
void EditBar(Bar& bar);
void SettingBar(Bar& bar);
void SelectBar(Bar& bar);
void ImageBar(Bar& bar);
void DrawBar(Bar& bar);
struct EditPosSlot : Moveable<EditPosSlot> {
String undo;
String redo;
String selection;
bool supersampling;
};
struct EditPos {
Vector<EditPosSlot> slot;
int cursor, sc;
};
void Clear();
Slot& AddImage(const String& name, const Image& image, bool exp);
int GetCount() const;
Image GetImage(int ii) const;
String GetName(int ii) const;
bool GetExport(int ii) const;
dword GetFlags(int ii) const;
bool FindName(const String& name);
String GetCurrentName() const;
void SyncStatus();
EditPos GetEditPos();
void SetEditPos(const EditPos& o);
void SerializeSettings(Stream& s);
void SingleMode();
bool IsSingleMode() const { return single_mode; }
typedef IconDes CLASSNAME;
IconDes();
};
struct ImlImage : ImageIml {
String name;
bool exp;
};
bool LoadIml(const String& data, Array<ImlImage>& img, int& format);
String SaveIml(const Array<ImlImage>& iml, int format, const String& eol = "\r\n");
template <class T>
inline
Image ForEachPixel(const Image& src, T op, bool co = true)
{
Size sz = src.GetSize();
ImageBuffer m(sz);
CoFor(co, sz.cy, [&](int y) {
const RGBA *s = src[y];
const RGBA *e = s + sz.cx;
RGBA *t = m[y];
while(s < e) {
*t = *s;
op(*t);
s++;
t++;
}
});
m.SetHotSpots(src);
return m;
}
template <class T>
inline
Image ForEachPixelStraight(const Image& src, T op, bool co = true)
{
return ForEachPixel(src, [&](RGBA& t) {
t = Unmultiply(t);
op(t);
t = Premultiply(t);
}, co);
}
}
#endif

View file

@ -1,31 +0,0 @@
description "Image designer\377";
uses
CtrlLib,
plugin\gif,
plugin\jpg,
Painter,
RichEdit;
file
IconDes.h options(BUILDER_OPTION) PCH,
IconDes.key,
IconDraw.cpp,
AlphaCtrl.cpp,
RGBACtrl.cpp,
ImageOp.cpp,
Paint.cpp,
Event.cpp,
IconDes.cpp,
List.cpp,
Image.cpp,
Smoothen.cpp,
Text.cpp,
Bar.cpp,
EditPos.cpp,
ImlFile.cpp,
IconDes.lay,
IconDes.iml,
Info readonly separator,
Copying;

View file

@ -50,7 +50,7 @@ struct IdeDesigner {
virtual void EditMenu(Bar& menu) = 0;
virtual int GetCharset() const { return -1; }
virtual Ctrl& DesignerCtrl() = 0;
virtual void SetFocus() { DesignerCtrl().SetFocus(); }
// virtual void SetFocus() { DesignerCtrl().SetFocus(); }
virtual ~IdeDesigner() {}
};

View file

@ -247,7 +247,7 @@ bool Ide::GotoId(const String& ref_id, const String& name, Point ref_pos, int li
}
DoEditAsText(found_path);
}
IdeIconDes *k = dynamic_cast<IdeIconDes *>(~designer);
IconDes *k = dynamic_cast<IconDes *>(~designer);
if(k) {
k->FindId(found_name);
return true;

View file

@ -1,9 +1,6 @@
#ifndef _ide_Designers_Designers_h_
#define _ide_Designers_Designers_h_
#include <HexView/HexView.h>
#include <ide/Common/Common.h>
#include <ide/IconDes/IconDes.h>
#include <ide/ide.h>
struct IdeImgView : IdeDesigner, Ctrl {
@ -21,7 +18,7 @@ struct IdeImgView : IdeDesigner, Ctrl {
typedef IdeImgView CLASSNAME;
};
struct IdePngDes : IdeIconDes {
struct IdePngDes : IconDes {
virtual void Save();
void Load(const char *filename);

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
void AlphaCtrl::Layout()
{
MakeImage();
@ -121,5 +119,3 @@ AlphaCtrl::AlphaCtrl()
mask = false;
maskvalue = 255;
}
}

View file

@ -1,10 +1,8 @@
#include "IconDes.h"
namespace Upp {
#define KEYNAMESPACE IconDesKeys
#define KEYGROUPNAME "Icon designer"
#define KEYFILE <IconDes/IconDes.key>
#define KEYFILE <ide/IconDes/IconDes.key>
#include <CtrlLib/key_source.h>
void IconDes::SetPen(int _pen)
@ -81,8 +79,6 @@ void IconDes::DoCut()
Delete();
}
void IconDes::ToolEx(Bar& bar) {}
void IconDes::EditBar(Bar& bar)
{
using namespace IconDesKeys;
@ -419,5 +415,3 @@ IconDes::IconDes()
status.Width(200);
status.NoTransparent();
}
}

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
bool IsSelection(const Image& m) {
const RGBA *s = m;
const RGBA *e = s + m.GetLength();
@ -52,5 +50,3 @@ void IconDes::SetEditPos(const EditPos& e)
}
SyncImage();
}
}

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
void IconDes::LeftDown(Point p, dword flags)
{
SetFocus();
@ -146,5 +144,3 @@ void IconDes::HorzMouseWheel(Point pt, int zdelta, dword keyflags)
{
sb.WheelX(zdelta);
}
}

View file

@ -1,108 +1,685 @@
#include "IconDes.h"
#include <plugin/bmp/bmp.h>
#include <plugin/png/png.h>
#include <ide/ide.h>
bool IdeIconDes::Load(const char *_filename)
void IconDes::MaskSelection()
{
Clear();
filename = _filename;
filetime = FileGetTime(filename);
Array<ImlImage> iml;
int f;
String s = LoadFile(filename);
EOL = GetLineEndings(s);
if(!LoadIml(s, iml, f))
Slot& c = Current();
ImageBuffer ib(c.image);
Size isz = ib.GetSize();
CoFor(isz.cy, [&](int y) {
RGBA *t = ib[y];
const RGBA *e = t + isz.cx;
const RGBA *s = c.base_image[y];
const RGBA *k = c.selection[y];
while(t < e) {
if(!k->r)
*t = *s;
t++;
s++;
k++;
}
});
Current().image = ib;
Refresh();
SyncShow();
}
IconDes::Slot& IconDes::Current()
{
if(ilist.IsCursor())
return slot[ilist.GetKey()];
NEVER();
return dummy;
}
Image& IconDes::CurrentImage()
{
return doselection ? Current().selection : Current().image;
}
Size IconDes::GetImageSize()
{
return IsCurrent() ? Current().image.GetSize() : Size(0, 0);
}
bool IconDes::InImage(int x, int y)
{
if(!IsCurrent())
return false;
format = f;
for(const ImlImage& m : iml)
AddImage(m.name, m.image, m.exp).flags = m.flags;
return true;
Size sz = GetImageSize();
return x >= 0 && x < sz.cx && y >= 0 && y < sz.cy;
}
void IdeIconDes::Save()
void IconDes::SyncShow()
{
if(format == 1) {
for(int i = 0; i < GetCount(); i++) {
Image m = GetImage(i);
Point p = m.Get2ndSpot();
if(m.GetKind() == IMAGE_ALPHA || p.x || p.y) {
if(PromptYesNo("Legacy file format does not support images "
"with full alpha channel or 2nd hotspot - "
"the information would be lost.&"
"Do you wish to convert the file to the new format?")) {
format = 0;
}
break;
}
}
iconshow.image.Clear();
if(IsCurrent()) {
Slot& c = Current();
iconshow.image = c.image;
iconshow.flags = c.flags;
iconshow.show_downscaled = show_downscaled;
iconshow.show_synthetics = show_synthetics;
ilist.Set(2, RawToValue(MakeTuple(c.image, c.flags)));
}
StoreToGlobal(*this, "icondes-ctrl");
Array<ImlImage> m;
VectorMap<Size, Image> exp;
String folder = GetFileFolder(filename);
for(int i = 0; i < GetCount(); i++) {
ImlImage& c = m.Add();
c.name = GetName(i);
c.image = GetImage(i);
c.exp = GetExport(i);
c.flags = GetFlags(i);
if(c.exp) {
Size sz = c.image.GetSize();
exp.GetAdd(sz) = c.image;
PNGEncoder png;
SaveChangedFile(AppendFileName(folder, String().Cat() << "icon" << sz.cx << 'x' << sz.cy << ".png"),
png.SaveString(c.image));
}
iconshow.Refresh();
}
void IconDes::SetSb()
{
magnify = max(magnify, 1);
if(IsCurrent()) {
sb.SetTotal(GetImageSize());
sb.SetPage(GetSize() / magnify);
}
String d = SaveIml(m, format, EOL);
if(!SaveChangedFileFinish(filename, d))
}
void IconDes::Scroll()
{
magnify = max(magnify, 1);
Refresh();
}
void IconDes::Layout()
{
SetSb();
}
void IconDes::SetCurrentImage(ImageBuffer& ib)
{
CurrentImage() = ib;
Refresh();
SyncShow();
}
Point IconDes::GetPos(Point p)
{
return p / max(magnify, 1) + sb;
}
void IconDes::FinishPaste()
{
CloseText();
if(IsCurrent()) {
Current().pastepos = Null;
Current().base_image.Clear();
}
Refresh();
rgbactrl.Show();
}
void IconDes::MakePaste()
{
if(!IsCurrent() || !IsPasting())
return;
filetime = FileGetTime(filename);
if(exp.GetCount())
SaveChangedFile(AppendFileName(folder, "icon.ico"), WriteIcon(exp.GetValues()));
Slot& c = Current();
c.image = c.base_image;
if(paste_mode == PASTE_OPAQUE)
UPP::Copy(c.image, c.pastepos, c.paste_image, c.paste_image.GetSize());
else
if(paste_mode == PASTE_BACK) {
Image h = c.image;
UPP::Copy(c.image, c.pastepos, c.paste_image, c.paste_image.GetSize());
UPP::Over(c.image, Point(0, 0), h, c.image.GetSize());
}
else
UPP::Over(c.image, c.pastepos, Premultiply(c.paste_image), c.paste_image.GetSize());
MaskSelection();
}
void IdeIconDes::ToolEx(Bar& bar)
void IconDes::DoBuffer(Event<ImageBuffer&> tool)
{
bar.Separator();
if(!IsSingleMode()) {
bar.Add("Usage..", IdeCommonImg::Cpp(), [=] {
String name = GetCurrentName();
TheIde()->FindDesignerItemReferences(name + "()", name);
});
// bar.Add("File properties..", IconDesImg::FileProperties(), THISBACK(FileProperties));
Size isz = GetImageSize();
Image h = Current().base_image;
ImageBuffer ib(h);
tool(ib);
CurrentImage() = ib;
if(!doselection)
MaskSelection();
Refresh();
}
void IconDes::DoPainter(Event<Painter&> tool)
{
DoBuffer([&](ImageBuffer& ib) {
BufferPainter iw(ib);
iw.Co();
iw.Translate(0.5, 0.5);
tool(iw);
});
}
void IconDes::DoDraw(Event<IconDraw&> tool)
{
DoBuffer([&](ImageBuffer& ib) {
IconDraw iw(ib);
tool(iw);
});
}
void IconDes::DoTool(Event<IconDraw&> tool, Event<Painter&> aa_tool)
{
if(antialiased && !doselection)
DoPainter(aa_tool);
else
DoDraw(tool);
}
void IconDes::LineTool(Point p, dword flags)
{
RGBA c = CurrentColor();
DoTool(
[&](IconDraw& iw) {
iw.DrawLine(startpoint, p, pen, c);
if(pen == 1 && Rect(iw.image.GetSize()).Contains(p))
iw.image[p.y][p.x] = c;
},
[&](Painter& sw) {
sw.Move(startpoint).Line(p).Stroke(pen, c);
}
);
}
void IconDes::EllipseTool0(Point p, dword flags, bool fill_empty)
{
RGBA c = CurrentColor();
DoTool(
[&](IconDraw& iw) {
iw.DrawEllipse(Rect(startpoint, p), fill_empty,
doselection ? c : RGBAZero(), pen, c);
},
[&](Painter& sw) {
sw.DrawEllipse(Rect(startpoint, p).Normalized(),
fill_empty ? LtGray() : Null, pen, c);
}
);
}
void IconDes::EllipseTool(Point p, dword flags)
{
EllipseTool0(p, flags, Null);
}
void IconDes::EmptyEllipseTool(Point p, dword flags)
{
EllipseTool0(p, flags, GrayColor(128));
}
void IconDes::RadialTool(Point p, dword f)
{
DoPainter([&](Painter& iw) {
double r = Distance(startpoint, p);
iw.Circle(startpoint.x, startpoint.y, Distance(startpoint, p))
.Fill(startpoint.x, startpoint.y, startcolor, r, CurrentColor());
});
}
void IconDes::LinearTool(Point p, dword f)
{
DoPainter([&](Painter& iw) {
Pointf pf = p;
Pointf sf = startpoint;
Pointf vec = 10000 * Orthogonal(sf - pf);
iw.Move(sf - vec).Line(pf - vec).Line(pf + vec).Line(sf + vec)
.Fill(sf, startcolor, pf, CurrentColor());
});
}
void IconDes::RectTool0(Point p, dword flags, bool empty)
{
DoDraw([&](IconDraw& iw) {
rect = Rect(startpoint, p + 1).Normalized();
Size sz = rect.GetSize();
if(empty)
iw.DrawRect(rect.left, rect.top, sz.cx, sz.cy,
doselection ? CurrentColor() : RGBAZero());
iw.DrawFrame(rect.left, rect.top, sz.cx, sz.cy, CurrentColor(), pen);
});
}
void IconDes::RectTool(Point p, dword flags)
{
RectTool0(p, flags, false);
}
void IconDes::EmptyRectTool(Point p, dword flags)
{
RectTool0(p, flags, true);
}
void IconDes::Freehand(Point p, int pen)
{
DoDraw([&](IconDraw& iw) {
iw.DrawRect(p.x - pen / 2, p.y - pen / 2, pen, pen, CurrentColor());
iw.DrawLine(startpoint, p, pen, CurrentColor());
});
Current().base_image = CurrentImage();
startpoint = p;
}
void IconDes::FreehandTool(Point p, dword flags)
{
Freehand(p, pen);
}
void IconDes::DoFill(int tolerance)
{
Image src = Current().image;
ImageBuffer ib(CurrentImage());
if(!doselection) {
RGBA c = CurrentColor();
c.r += 127;
MaskFill(ib, c, 0);
}
FloodFill(src, ib, CurrentColor(), startpoint, tolerance);
SetCurrentImage(ib);
if(!doselection)
MaskSelection();
}
void IconDes::HotSpotTool(Point p, dword f)
{
if(p != Current().image.GetHotSpot()) {
ImageBuffer ib(Current().image);
ib.SetHotSpot(p);
Current().image = ib;
Refresh();
}
}
void IdeIconDes::FileProperties()
Image IconDes::MakeIconDesCursor(const Image& arrow, const Image& cmask)
{
WithFilePropertiesLayout<TopWindow> dlg;
CtrlLayoutOKCancel(dlg, "File properties");
dlg.format <<= format;
if(dlg.Run() == IDOK)
format = ~dlg.format;
RGBA c = CurrentColor();
c.a = 255;
Image ucmask = Unmultiply(cmask);
ImageBuffer ib(ucmask.GetSize());
const RGBA *m = ~ucmask;
RGBA *t = ~ib;
RGBA *e = ib.End();
while(t < e) {
*t = c;
t->a = m->a;
m++;
t++;
}
Image cm(ib);
Image r = arrow;
Over(r, Point(0, 0), Premultiply(cm), r.GetSize());
return r;
}
void IdeIconDes::Serialize(Stream& s)
void IconDes::ColorChanged()
{
SerializeSettings(s);
cursor_image = MakeIconDesCursor(IconDesImg::Arrow(), IconDesImg::ArrowColor());
cursor_image_free = MakeIconDesCursor(IconDesImg::Arrow(), IconDesImg::ArrowColorFree());
fill_cursor = MakeIconDesCursor(IconDesImg::Fill(), IconDesImg::FillColor());
fill_cursor2 = MakeIconDesCursor(IconDesImg::Fill2(), IconDesImg::FillColor());
fill_cursor3 = MakeIconDesCursor(IconDesImg::Fill3(), IconDesImg::FillColor());
antifill_cursor = MakeIconDesCursor(IconDesImg::Fill(), IconDesImg::AntiFill());
PasteText();
SetBar();
}
String IdeIconDes::GetFileName() const
void IconDes::SetTool(void (IconDes::*_tool)(Point p, dword flags))
{
return filename;
FinishPaste();
if(HasCapture())
ReleaseCapture();
tool = _tool;
SetBar();
}
void IdeIconDes::EditMenu(Bar& bar)
RGBA IconDes::CurrentColor()
{
EditBar(bar);
ToolEx(bar);
bar.Add(IsSingleMode() ? "PNG" : "List", THISBACK(ListMenu));
bar.Add("Selection", THISBACK(SelectBar));
bar.Add("Image", THISBACK(ImageBar));
bar.Add("Draw", THISBACK(DrawBar));
bar.Add("Settings", THISBACK(SettingBar));
return rgbactrl.Get();
}
void IconDes::Paste(const Image& img)
{
FinishPaste();
if(!IsCurrent())
return;
SaveUndo();
Slot& c = Current();
c.base_image = c.image;
c.paste_image = img;
c.pastepos = Point(0, 0);
MakePaste();
SetBar();
}
Rect IconDes::SelectionRect()
{
if(!IsCurrent())
return Null;
Size isz = GetImageSize();
int minx = isz.cx - 1;
int maxx = 0;
int miny = isz.cy - 1;
int maxy = 0;
for(int y = 0; y < isz.cy; y++) {
const RGBA *k = Current().selection[y];
for(int x = 0; x < isz.cx; x++)
if((k++)->r == 255) {
if(x < minx) minx = x;
if(x > maxx) maxx = x;
if(y < miny) miny = y;
if(y > maxy) maxy = y;
}
}
return Rect(minx, miny, maxx + 1, maxy + 1);
}
Image IconDes::Copy(const Rect& r)
{
if(!IsCurrent() || r.IsEmpty())
return Image();
Slot& c = Current();
if(Rect(GetImageSize()) == r) // return whole image with correct hotspots
return c.image;
ImageBuffer ib(r.GetSize());
for(int y = r.top; y < r.bottom; y++) {
const RGBA *s = c.image[y] + r.left;
const RGBA *e = c.image[y] + r.right;
const RGBA *k = c.selection[y] + r.left;
RGBA *t = ib[y - r.top];
while(s < e) {
*t = *s;
if(!k->r)
*t = RGBAZero();
t++;
k++;
s++;
}
}
return ib;
}
void IconDes::Delete()
{
SetColor0(RGBAZero());
}
void IconDes::SetSelect(int a)
{
if(!IsCurrent())
return;
ImageBuffer ib(GetImageSize());
memset(ib, a, ib.GetLength() * sizeof(RGBA));
Current().selection = ib;
Refresh();
}
void IconDes::Select()
{
if(!IsCurrent())
return;
ReleaseCapture();
FinishPaste();
doselection = !doselection;
rgbactrl.Mask(doselection);
if(doselection && SelectionRect() == GetImageSize()) {
SetSelect(0);
rgbactrl.MaskSet(255);
}
Refresh();
SetBar();
}
void IconDes::CancelSelect()
{
ReleaseCapture();
doselection = false;
rgbactrl.Mask(false);
FinishPaste();
SetSelect(255);
SetBar();
}
void IconDes::InvertSelect()
{
if(!IsCurrent())
return;
ImageBuffer ib(Current().selection);
RGBA *s = ib;
const RGBA *e = s + ib.GetLength();
while(s < e) {
s->r = s->g = s->b = s->a = ~s->r;
s++;
}
Current().selection = ib;
Refresh();
}
void IconDes::Move()
{
if(!IsCurrent())
return;
Slot& c = Current();
selectrect = false;
if(IsPasting())
FinishPaste();
else {
doselection = false;
rgbactrl.Mask(false);
rgbactrl.Hide();
Rect r = SelectionRect();
Image m = Copy(r);
Delete();
SetSelect(255);
c.base_image = c.image;
c.paste_image = m;
c.pastepos = r.TopLeft();
MakePaste();
}
SetBar();
}
void IconDes::SelectRect()
{
doselection = false;
Select();
selectrect = true;
rect = Null;
SetBar();
}
String PackUndo(const Vector<ImageIml>& img)
{
return FastCompress(PackImlDataUncompressed(img));
}
Vector<ImageIml> UnpackUndo(const String& data)
{
return UnpackImlDataUncompressed(FastDecompress(data));
}
void IconDes::SaveUndo()
{
if(!IsCurrent())
return;
Slot& c = Current();
Vector<ImageIml> undo = UnpackUndo(c.undo);
int maxn = minmax((single_mode ? 40000000 : 2000000) / max((int)c.image.GetLength(), 1), 4, 128);
while(undo.GetCount() > maxn)
undo.Remove(0);
if(undo.GetCount() && undo.Top().image == c.image)
return;
undo.Add().image = c.image;
c.undo = PackUndo(undo);
c.redo.Clear();
SetBar();
undo.Clear();
}
void IconDes::Undo()
{
if(!IsCurrent())
return;
Slot& c = Current();
Vector<ImageIml> undo = UnpackUndo(c.undo);
if(undo.GetCount() == 0)
return;
Vector<ImageIml> redo = UnpackUndo(c.redo);
redo.Add().image = c.image;
c.image = undo.Pop().image;
c.undo = PackUndo(undo);
c.redo = PackUndo(redo);
SyncImage();
SetBar();
}
void IconDes::Redo()
{
if(!IsCurrent())
return;
Slot& c = Current();
Vector<ImageIml> redo = UnpackUndo(c.redo);
if(redo.GetCount() == 0)
return;
Vector<ImageIml> undo = UnpackUndo(c.undo);
undo.Add().image = c.image;
c.image = redo.Pop().image;
c.undo = PackUndo(undo);
c.redo = PackUndo(redo);
SyncImage();
SetBar();
}
void IconDes::SyncImage()
{
ReleaseCapture();
SyncShow();
if(IsCurrent()) {
Slot& c = Current();
SyncShow();
c.pastepos = Null;
if(c.selection.GetSize() != c.image.GetSize())
SetSelect(255);
if(single_mode)
info.SetLabel(Format("%d x %d", c.image.GetWidth(), c.image.GetHeight()));
}
selectrect = false;
SyncList();
SetBar();
Refresh();
}
void IconDes::Reset()
{
SetSelect(255);
SyncImage();
}
void IconDes::MaskFill(ImageBuffer& ib, RGBA color, int mask)
{
if(!IsCurrent())
return;
if(doselection)
Fill(ib, color, ib.GetLength());
else {
RGBA *t = ib;
RGBA *e = ib + ib.GetLength();
const RGBA *s = Current().selection;
while(t < e) {
if((s++)->r == mask)
*t = color;
t++;
}
}
}
void IconDes::SetColor0(RGBA color)
{
FinishPaste();
doselection = false;
rgbactrl.Mask(false);
SaveUndo();
ImageBuffer ib(Current().image);
MaskFill(ib, color, 255);
Refresh();
SetCurrentImage(ib);
SyncShow();
SetBar();
}
void IconDes::SetColor()
{
SetColor0(CurrentColor());
}
void IconDes::DoDelete()
{
SetColor0(RGBAZero());
}
void IconDes::BeginResize()
{
CancelSelect();
FinishPaste();
SaveUndo();
Refresh();
SyncShow();
}
void IconDes::ResizeUp()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = Magnify(c.image, 3, 3);
Reset();
}
void IconDes::ResizeDown()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = (c.image.GetSize() / 3).IsEmpty() ? CreateImage(Size(1, 1), White)
: DownSample3x(c.image);
Reset();
}
void IconDes::ResizeUp2()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = Magnify(c.image, 2, 2);
Reset();
}
void IconDes::ResizeDown2()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = (c.image.GetSize() / 3).IsEmpty() ? CreateImage(Size(1, 1), White)
: DownSample2x(c.image);
Reset();
}
void IconDes::Upscale()
{
if(!IsCurrent())
return;
Slot& c = Current();
BeginResize();
c.image = Upscale2x(c.image);
Reset();
}
void IconDes::SingleMode()
{
single_mode = true;
ilist.Ctrl::Remove();
rgbactrl.SubCtrl(&single);
Size fsz = GetTextSize("Resize", StdFont());
single.Add(info.HSizePos().TopPos(0, fsz.cy));
resize.SetLabel("Resize");
single.Add(resize.LeftPos(0, fsz.cx + 2 * fsz.cy).TopPos(4 * fsz.cy / 3, 4 * fsz.cy / 3));
resize <<= THISBACK(EditImage);
}

View file

@ -1,10 +1,128 @@
#ifndef _ide_IconDes_IconDes_h_
#define _ide_IconDes_IconDes_h_
#ifndef _IconDes_IconDes_h_
#define _IconDes_IconDes_h_
#include <plugin/bmp/bmp.h>
#include <ide/Common/Common.h>
#include <IconDes/IconDes.h>
struct IdeIconDes : IdeDesigner, IconDes {
#define IMAGECLASS IconDesImg
#define IMAGEFILE <ide/IconDes/IconDes.iml>
#include <Draw/iml_header.h>
#define LAYOUTFILE <ide/IconDes/IconDes.lay>
#include <CtrlCore/lay.h>
#define KEYNAMESPACE IconDesKeys
#define KEYGROUPNAME "Icon designer"
#define KEYFILE <ide/IconDes/IconDes.key>
#include <CtrlLib/key_header.h>
class AlphaCtrl : public Ctrl {
public:
virtual void Layout();
virtual void Paint(Draw& w);
virtual void LeftDown(Point p, dword keyflags);
virtual void MouseMove(Point p, dword keyflags);
private:
Image img;
Color color;
int alpha;
bool mask;
int maskvalue;
void MakeImage();
void DoPoint(Point p);
public:
void SetColor(Color c);
void Set(int a);
int Get() const;
void Mask(bool m);
bool IsMask() const { return mask; }
AlphaCtrl();
};
class RGBACtrl : public Ctrl {
public:
virtual void Paint(Draw& w);
virtual void Layout();
virtual void LeftDown(Point p, dword keyflags);
virtual void MouseMove(Point p, dword keyflags);
private:
Size cbox;
Point cs;
enum { COLORCOUNT = 216 + 18 + 18 };
Color color;
ColorRampCtrl ramp;
AlphaCtrl alpha;
EditString text;
FrameRight<Button> setcolor;
Ptr<Ctrl> subctrl;
Color GetColor(int i) const;
void Ramp();
void Alpha();
void SyncText();
int DoLayout(Size sz, bool set);
public:
typedef RGBACtrl CLASSNAME;
void Set(RGBA c);
void MaskSet(int a);
RGBA Get() const;
Color GetColor() const;
int GetAlpha() const;
void Mask(bool b);
void SubCtrl(Ctrl *c);
int GetHeight(int cx);
RGBACtrl();
};
struct IconShow : public Ctrl {
Image image;
bool show_downscaled;
bool show_synthetics;
dword flags;
void Paint(Draw& w);
IconShow() { BackPaint(); }
};
void FloodFill(const Image& source, ImageBuffer& target, RGBA color, Point pt, int tolerance);
void InterpolateImage(Image& img, const Rect& _rc);
void MirrorHorz(Image& img, const Rect& rect);
void MirrorVert(Image& img, const Rect& rect);
String PackImlDataUncompressed(const Vector<ImageIml>& image);
String PackImlData(const Vector<ImageIml>& image);
struct IconDraw : DDARasterizer {
RGBA docolor;
ImageBuffer& image;
virtual void PutHorz(int x, int y, int cx);
virtual void PutVert(int x, int y, int cy);
void DrawRect(int x, int y, int cx, int cy, RGBA color);
void DrawFrame(int x, int y, int cx, int cy, RGBA color, int n);
void DrawLine(Point p1, Point p2, int width, RGBA color);
void DrawEllipse(const Rect& r, bool fill_empty, RGBA color, int pen, RGBA pencolor);
IconDraw(ImageBuffer& image) : image(image) { Cy(image.GetHeight()); }
};
struct IconDes : public IdeDesigner, public Ctrl {
public: // IdeDesigner
virtual String GetFileName() const;
virtual void Save();
virtual void SaveEditPos();
@ -14,7 +132,7 @@ struct IdeIconDes : IdeDesigner, IconDes {
virtual void Serialize(Stream& s);
int format;
int format = 0;
String filename;
Time filetime;
String EOL = "\r\n";
@ -27,11 +145,335 @@ struct IdeIconDes : IdeDesigner, IconDes {
void CopyId(const String& n);
void FindId(const String& id);
typedef IdeIconDes CLASSNAME;
public:
virtual void Layout();
virtual void Paint(Draw& w);
virtual void LeftDown(Point p, dword keyflags);
virtual void MouseMove(Point p, dword keyflags);
virtual void MouseEnter(Point, dword) { SyncStatus(); }
virtual void MouseLeave() { SyncStatus(); }
virtual void LeftUp(Point p, dword keyflags);
virtual void MouseWheel(Point p, int zdelta, dword keyflags);
virtual void HorzMouseWheel(Point pt, int zdelta, dword keyflags);
virtual void RightDown(Point p, dword keyflags);
virtual bool Key(dword key, int count);
virtual Image CursorImage(Point p, dword keyflags);
IdeIconDes() { format = 0; }
private:
struct Slot {
String name;
Image image;
Image base_image;
Image selection;
Point pastepos = Null;
Image paste_image;
String undo;
String redo;
bool exp = false;
dword flags = 0;
};
enum {
PASTE_TRANSPARENT, PASTE_OPAQUE, PASTE_BACK
};
Array<Slot> slot;
Slot dummy;
int magnify;
int pen;
Point startpoint;
Point scroll_start = Null;
Point scroll_base;
RGBA startcolor = RGBAZero();
Rect m1refresh;
void (IconDes::*tool)(Point p, dword flags);
bool doselection = false;
bool selectrect = false;
int paste_mode;
bool show_synthetics = false;
bool show_downscaled = false;
bool show_grid2 = false;
bool antialiased = false;
int fill_type = 0;
ScrollBars sb;
ToolBar toolbar;
SplitterFrame leftpane;
SplitterFrame bottompane;
ParentCtrl imgs;
ArrayCtrl ilist;
EditString search;
RGBACtrl rgbactrl;
IconShow iconshow;
Image cursor_image, cursor_image_free;
Image fill_cursor, fill_cursor2, fill_cursor3, antifill_cursor;
bool single_mode;
ParentCtrl single;
Label info;
Button resize;
Array<Slot> removed;
FrameRight<Label> status;
int syncinglist = 0;
Rect rect;
struct TextDlg : WithIconDesTextLayout<TopWindow> {
typedef TextDlg CLASSNAME;
Font GetFont();
TextDlg();
};
TextDlg textdlg;
void DoBuffer(Event<ImageBuffer&> tool);
void DoPainter(Event<Painter&> tool);
void DoDraw(Event<IconDraw&> tool);
void DoTool(Event<IconDraw&> tool, Event<Painter&> aa_tool);
void LineTool(Point p, dword f);
void Freehand(Point p, int pen);
void FreehandTool(Point p, dword f);
void EllipseTool0(Point p, dword flags, bool fill_empty);
void EllipseTool(Point p, dword f);
void EmptyEllipseTool(Point p, dword f);
void RadialTool(Point p, dword f);
void LinearTool(Point p, dword f);
void RectTool0(Point p, dword f, bool empty);
void RectTool(Point p, dword f);
void EmptyRectTool(Point p, dword f);
void HotSpotTool(Point p, dword f);
void DoFill(int tolerance);
void Text();
void PasteText();
void CloseText();
bool IsCurrent() { return !IsNull(ilist.GetKey()); }
Slot& Current();
Image& CurrentImage();
void SetCurrentImage(ImageBuffer& ib);
RGBA CurrentColor();
Size GetImageSize();
bool InImage(int x, int y);
bool InImage(Point p) { return InImage(p.x, p.y); }
bool IsHotSpot() const { return tool == &IconDes::HotSpotTool; }
Image MakeIconDesCursor(const Image& arrow, const Image& cmask);
void SyncShow();
Point GetPos(Point p);
void ApplyImage(Image m, dword flags, bool alpha = false);
void SyncImage();
void Reset();
bool IsPasting() { return IsCurrent() && !IsNull(Current().pastepos); }
void MakePaste();
void Paste(const Image& img);
void FinishPaste();
void SetSelect(int a);
Rect SelectionRect();
void Select();
void InvertSelect();
void CancelSelect();
void SelectRect();
Image Copy(const Rect& r);
void Delete();
void Move();
void MaskSelection();
void SetSb();
void Scroll();
void SetTool(void (IconDes::*tool)(Point p, dword flags));
void SetMagnify(int mag);
void ZoomIn();
void ZoomOut();
void SetPen(int pen);
void MainToolBar(Bar& bar);
void SetBar();
void SaveUndo();
void Undo();
void Redo();
void DoPaste();
void DoCopy();
void DoCut();
void ColorChanged();
void MaskFill(ImageBuffer& ib, RGBA color, int mask);
void SetColor0(RGBA color);
void SetColor();
void DoDelete();
void Interpolate();
bool BeginTransform();
void MirrorX();
void MirrorY();
void SymmX();
void SymmY();
void FreeRotate();
void Rotate();
void SmoothRescale();
void KeyMove(int dx, int dy);
void BeginResize();
void ResizeUp();
void ResizeDown();
void ResizeUp2();
void ResizeDown2();
void Upscale();
void PlaceDlg(TopWindow& dlg);
void Couple(TopWindow& dlg, EditDouble& level, SliderCtrl& slider, double max, double init = 0);
void Couple(TopWindow& dlg, EditInt& level, SliderCtrl& slider, int max, int init = 0);
Image ImageStart();
void ImageSet(const Image& m);
void BlurSharpen();
void Colorize();
void Chroma();
void Contrast();
void Alpha();
void Colors();
void Smoothen();
void RemoveAlpha();
void Search();
void GoTo(int q);
void SyncList();
void ListCursor();
void PrepareImageDlg(WithImageLayout<TopWindow>& dlg);
void PrepareImageSizeDlg(WithImageSizeLayout<TopWindow>& dlg);
void SyncDlg(WithImageLayout<TopWindow>& dlg);
dword GetFlags(WithImageLayout<TopWindow>& dlg);
Slot& ImageInsert(int ii, const String& name, const Image& m, bool exp = false);
Slot& ImageInsert(const String& name, const Image& m, bool exp = false);
void Slice();
void InsertImage();
void InsertRemoved(int ii);
void EditImageSize();
void EditImage();
void RemoveImage();
void Duplicate();
void InsertPaste();
void InsertFile();
void ExportPngs();
void MoveSlot(int d);
void ChangeSlot(int d);
void DnDInsert(int line, PasteClip& d);
void Drag();
static FileSel& ImgFile();
static String FormatImageName(const Slot& c);
public:
void ListMenu(Bar& bar);
void EditBar(Bar& bar);
void SettingBar(Bar& bar);
void SelectBar(Bar& bar);
void ImageBar(Bar& bar);
void DrawBar(Bar& bar);
struct EditPosSlot : Moveable<EditPosSlot> {
String undo;
String redo;
String selection;
bool supersampling;
};
struct EditPos {
Vector<EditPosSlot> slot;
int cursor, sc;
};
void Clear();
Slot& AddImage(const String& name, const Image& image, bool exp);
int GetCount() const;
Image GetImage(int ii) const;
String GetName(int ii) const;
bool GetExport(int ii) const;
dword GetFlags(int ii) const;
bool FindName(const String& name);
String GetCurrentName() const;
void SyncStatus();
EditPos GetEditPos();
void SetEditPos(const EditPos& o);
void SerializeSettings(Stream& s);
void SingleMode();
bool IsSingleMode() const { return single_mode; }
typedef IconDes CLASSNAME;
IconDes();
};
struct ImlImage : ImageIml {
String name;
bool exp;
};
bool LoadIml(const String& data, Array<ImlImage>& img, int& format);
String SaveIml(const Array<ImlImage>& iml, int format, const String& eol = "\r\n");
template <class T>
inline
Image ForEachPixel(const Image& src, T op, bool co = true)
{
Size sz = src.GetSize();
ImageBuffer m(sz);
CoFor(co, sz.cy, [&](int y) {
const RGBA *s = src[y];
const RGBA *e = s + sz.cx;
RGBA *t = m[y];
while(s < e) {
*t = *s;
op(*t);
s++;
t++;
}
});
m.SetHotSpots(src);
return m;
}
template <class T>
inline
Image ForEachPixelStraight(const Image& src, T op, bool co = true)
{
return ForEachPixel(src, [&](RGBA& t) {
t = Unmultiply(t);
op(t);
t = Premultiply(t);
}, co);
}
struct IdeIconEditPos : IconDes::EditPos, Moveable<IdeIconEditPos> {
Time filetime;

View file

@ -1,58 +1,58 @@
#ifdef DUPLICATE
#undef DUPLICATE
#endif
KEY(INSERT_IMAGE, "Insert image..", K_INSERT)
KEY(IMAGE, "Image..", 0)
KEY(REMOVE_IMAGE, "Remove image", 0)
KEY(DUPLICATE, "Duplicate", K_CTRL_D)
KEY(INSERT_CLIP, "Insert from clipboard", K_ALT_V)
KEY(INSERT_FILE, "Insert from file(s)..", K_ALT_O)
KEY(EXPORT_PNGS, "Export to PNGs..", 0)
KEY(INSERT_IML, "Insert another .iml..", 0)
KEY(MOVE_UP, "Move up", K_CTRL_UP)
KEY(MOVE_DOWN, "Move down", K_CTRL_DOWN)
KEY(ZOOM_OUT, "Zoom out", K_CTRL_SUBTRACT)
KEY(ZOOM_IN, "Zoom in", K_CTRL_ADD)
KEY(PASTE_MODE, "Paste opaque", 0)
KEY(PASTE_BACK, "Paste to background", 0)
KEY(SELECT, "Select", K_SPACE)
KEY(INVERT_SEL, "Invert selection", K_CTRL_I)
KEY(CANCEL_SEL, "Cancel selection", K_CTRL_E)
KEY(SELECT_MOVE, "Select and move rectangle", K_CTRL_R)
KEY(MOVE, "Move", K_CTRL_M)
KEY(UPSCALE, "Smart Upscale 2x", 0)
KEY(RESIZEDOWN2, "Supersample 2x", 0)
KEY(RESIZEUP2, "Rescale Up 2x", 0)
KEY(RESIZEDOWN3, "Supersample 3x", 0)
KEY(RESIZEUP3, "Rescale Up 3x", 0)
KEY(SETCOLOR, "Set color", 0)
KEY(EMPTY, "Empty", K_DELETE)
KEY(INTERPOLATE, "Interpolate", 0)
KEY(HMIRROR, "Horizontal mirror", 0)
KEY(VMIRROR, "Vertical mirror", 0)
KEY(HSYM, "Horizontal symmetry", 0)
KEY(VSYM, "Vertical symmetry", 0)
KEY(ROTATE, "Rotate", 0)
KEY(FREE_ROTATE, "Free Rotate", 0)
KEY(RESCALE, "Smooth Rescale", 0)
KEY(BLUR, "Blur/Sharpen", 0)
KEY(COLORIZE, "Colorize", 0)
KEY(CHROMA, "Chroma", 0)
KEY(CONTRAST, "Contrast", 0)
KEY(ALPHA, "Alpha", 0)
KEY(COLORS, "Colors", 0)
KEY(SMOOTHEN, "Smoothen", 0)
KEY(FREEHAND, "FreeHand", K_H)
KEY(LINES, "Lines", K_L)
KEY(ELLIPSES, "Ellipses", K_E)
KEY(RADIAL, "Radial gradient", 0)
KEY(LINEAR, "Linear gradient", 0)
KEY(EMPTY_ELLIPSES, "Empty ellipses", K_W)
KEY(RECTANGLES, "Rectangles", K_R)
KEY(EMPTY_RECTANGLES, "Empty rectangles", K_T)
KEY(HOTSPOTS, "Hotspots", K_H)
KEY(RESIZE_SINGLE, "Resize", 0)
KEY(TEXT, "Text", 0)
KEY(REFERENCES, "Find references..", K_ALT_U)
#ifdef DUPLICATE
#undef DUPLICATE
#endif
KEY(INSERT_IMAGE, "Insert image..", K_INSERT)
KEY(IMAGE, "Image..", 0)
KEY(REMOVE_IMAGE, "Remove image", 0)
KEY(DUPLICATE, "Duplicate", K_CTRL_D)
KEY(INSERT_CLIP, "Insert from clipboard", K_ALT_V)
KEY(INSERT_FILE, "Insert from file(s)..", K_ALT_O)
KEY(EXPORT_PNGS, "Export to PNGs..", 0)
KEY(INSERT_IML, "Insert another .iml..", 0)
KEY(MOVE_UP, "Move up", K_CTRL_UP)
KEY(MOVE_DOWN, "Move down", K_CTRL_DOWN)
KEY(ZOOM_OUT, "Zoom out", K_CTRL_SUBTRACT)
KEY(ZOOM_IN, "Zoom in", K_CTRL_ADD)
KEY(PASTE_MODE, "Paste opaque", 0)
KEY(PASTE_BACK, "Paste to background", 0)
KEY(SELECT, "Select", K_SPACE)
KEY(INVERT_SEL, "Invert selection", K_CTRL_I)
KEY(CANCEL_SEL, "Cancel selection", K_CTRL_E)
KEY(SELECT_MOVE, "Select and move rectangle", K_CTRL_R)
KEY(MOVE, "Move", K_CTRL_M)
KEY(UPSCALE, "Smart Upscale 2x", 0)
KEY(RESIZEDOWN2, "Supersample 2x", 0)
KEY(RESIZEUP2, "Rescale Up 2x", 0)
KEY(RESIZEDOWN3, "Supersample 3x", 0)
KEY(RESIZEUP3, "Rescale Up 3x", 0)
KEY(SETCOLOR, "Set color", 0)
KEY(EMPTY, "Empty", K_DELETE)
KEY(INTERPOLATE, "Interpolate", 0)
KEY(HMIRROR, "Horizontal mirror", 0)
KEY(VMIRROR, "Vertical mirror", 0)
KEY(HSYM, "Horizontal symmetry", 0)
KEY(VSYM, "Vertical symmetry", 0)
KEY(ROTATE, "Rotate", 0)
KEY(FREE_ROTATE, "Free Rotate", 0)
KEY(RESCALE, "Smooth Rescale", 0)
KEY(BLUR, "Blur/Sharpen", 0)
KEY(COLORIZE, "Colorize", 0)
KEY(CHROMA, "Chroma", 0)
KEY(CONTRAST, "Contrast", 0)
KEY(ALPHA, "Alpha", 0)
KEY(COLORS, "Colors", 0)
KEY(SMOOTHEN, "Smoothen", 0)
KEY(FREEHAND, "FreeHand", K_H)
KEY(LINES, "Lines", K_L)
KEY(ELLIPSES, "Ellipses", K_E)
KEY(RADIAL, "Radial gradient", 0)
KEY(LINEAR, "Linear gradient", 0)
KEY(EMPTY_ELLIPSES, "Empty ellipses", K_W)
KEY(RECTANGLES, "Rectangles", K_R)
KEY(EMPTY_RECTANGLES, "Empty rectangles", K_T)
KEY(HOTSPOTS, "Hotspots", K_H)
KEY(RESIZE_SINGLE, "Resize", 0)
KEY(TEXT, "Text", 0)
KEY(REFERENCES, "Find references..", K_ALT_U)
KEY(SLICE, "Slice..", 0)

View file

@ -1,13 +1,33 @@
description "TheIDE - .iml designer\377B";
description "Image designer\377B";
uses
IconDes,
ide/Common;
CtrlLib,
plugin\gif,
plugin\jpg,
Painter,
RichEdit;
file
IconDes.h,
IconDes.h options(BUILDER_OPTION) PCH,
IconDes.key,
IconDraw.cpp,
AlphaCtrl.cpp,
RGBACtrl.cpp,
ImageOp.cpp,
Paint.cpp,
Event.cpp,
IconDes.cpp,
List.cpp,
Image.cpp,
Smoothen.cpp,
Text.cpp,
Bar.cpp,
EditPos.cpp,
ImlFile.cpp,
IdeIconDes.cpp,
IdeDes.cpp,
IconDes.lay,
IconDes.iml,
Info readonly separator,
Copying;

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
void IconDraw::PutHorz(int x, int y, int cx)
{
if(y < 0 || y >= image.GetHeight())
@ -74,5 +72,3 @@ void IconDraw::DrawEllipse(const Rect& r_, bool fill_empty, RGBA color, int pen,
Ellipse(r, pen);
}
}
}

View file

@ -6,7 +6,7 @@ static VectorMap<String, IdeIconEditPos>& sEP()
return x;
}
void IdeIconDes::SaveEditPos()
void IconDes::SaveEditPos()
{
IdeIconEditPos& ep = sEP().GetAdd(filename);
ep.filetime = filetime;
@ -47,7 +47,7 @@ void SerializeIconDesPos(Stream& s)
}
}
void IdeIconDes::RestoreEditPos()
void IconDes::RestoreEditPos()
{
IdeIconEditPos& ep = sEP().GetAdd(filename);
if(ep.filetime == filetime)
@ -66,7 +66,7 @@ struct IconDesModule : public IdeModule {
}
virtual IdeDesigner *CreateDesigner(const char *path, byte) {
if(IsImlFile(path)) {
IdeIconDes *d = new IdeIconDes;
IconDes *d = new IconDes;
LoadFromGlobal(*d, "icondes-ctrl");
if(d->Load(path)) {
return d;
@ -88,18 +88,18 @@ void RegisterIconDes()
RegisterIdeModule(Single<IconDesModule>());
}
void IdeIconDes::CopyId(const String& n)
void IconDes::CopyId(const String& n)
{
ClearClipboard();
AppendClipboardText(n);
}
void IdeIconDes::FindId(const String& id)
void IconDes::FindId(const String& id)
{
FindName(id);
}
void IdeIconDes::ListMenuEx(Bar& bar)
void IconDes::ListMenuEx(Bar& bar)
{
if(IsSingleMode())
return;

View file

@ -0,0 +1,103 @@
#include <ide/ide.h>
bool IconDes::Load(const char *_filename)
{
Clear();
filename = _filename;
filetime = FileGetTime(filename);
Array<ImlImage> iml;
int f;
String s = LoadFile(filename);
EOL = GetLineEndings(s);
if(!LoadIml(s, iml, f))
return false;
format = f;
for(const ImlImage& m : iml)
AddImage(m.name, m.image, m.exp).flags = m.flags;
return true;
}
void IconDes::Save()
{
if(format == 1) {
for(int i = 0; i < GetCount(); i++) {
Image m = GetImage(i);
Point p = m.Get2ndSpot();
if(m.GetKind() == IMAGE_ALPHA || p.x || p.y) {
if(PromptYesNo("Legacy file format does not support images "
"with full alpha channel or 2nd hotspot - "
"the information would be lost.&"
"Do you wish to convert the file to the new format?")) {
format = 0;
}
break;
}
}
}
StoreToGlobal(*this, "icondes-ctrl");
Array<ImlImage> m;
VectorMap<Size, Image> exp;
String folder = GetFileFolder(filename);
for(int i = 0; i < GetCount(); i++) {
ImlImage& c = m.Add();
c.name = GetName(i);
c.image = GetImage(i);
c.exp = GetExport(i);
c.flags = GetFlags(i);
if(c.exp) {
Size sz = c.image.GetSize();
exp.GetAdd(sz) = c.image;
PNGEncoder png;
SaveChangedFile(AppendFileName(folder, String().Cat() << "icon" << sz.cx << 'x' << sz.cy << ".png"),
png.SaveString(c.image));
}
}
String d = SaveIml(m, format, EOL);
if(!SaveChangedFileFinish(filename, d))
return;
filetime = FileGetTime(filename);
if(exp.GetCount())
SaveChangedFile(AppendFileName(folder, "icon.ico"), WriteIcon(exp.GetValues()));
}
void IconDes::ToolEx(Bar& bar)
{
bar.Separator();
if(!IsSingleMode()) {
bar.Add("Usage..", IdeCommonImg::Cpp(), [=] {
String name = GetCurrentName();
TheIde()->FindDesignerItemReferences(name + "()", name);
});
// bar.Add("File properties..", IconDesImg::FileProperties(), THISBACK(FileProperties));
}
}
void IconDes::FileProperties()
{
WithFilePropertiesLayout<TopWindow> dlg;
CtrlLayoutOKCancel(dlg, "File properties");
dlg.format <<= format;
if(dlg.Run() == IDOK)
format = ~dlg.format;
}
void IconDes::Serialize(Stream& s)
{
SerializeSettings(s);
}
String IconDes::GetFileName() const
{
return filename;
}
void IconDes::EditMenu(Bar& bar)
{
EditBar(bar);
ToolEx(bar);
bar.Add(IsSingleMode() ? "PNG" : "List", THISBACK(ListMenu));
bar.Add("Selection", THISBACK(SelectBar));
bar.Add("Image", THISBACK(ImageBar));
bar.Add("Draw", THISBACK(DrawBar));
bar.Add("Settings", THISBACK(SettingBar));
}

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
void IconDes::Interpolate()
{
if(!IsCurrent())
@ -10,7 +8,7 @@ void IconDes::Interpolate()
SaveUndo();
Slot& c = Current();
c.base_image = c.image;
UPP::InterpolateImage(c.image, c.image.GetSize());
::InterpolateImage(c.image, c.image.GetSize());
MaskSelection();
}
@ -482,5 +480,3 @@ void IconDes::Colors()
}
}
}
}

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
struct sFloodFill {
Size sz;
Buffer<byte> flag;
@ -185,5 +183,3 @@ String PackImlData(const Vector<ImageIml>& image)
{
return ZCompress(PackImlDataUncompressed(image));
}
}

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
class AlphaImageInfo
{
public:
@ -347,5 +345,3 @@ String SaveIml(const Array<ImlImage>& iml, int format, const String& eol) {
}
return out.GetResult();
}
}

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
String IconDes::FormatImageName(const Slot& c)
{
Size sz = c.image.GetSize();
@ -542,9 +540,6 @@ void IconDes::ListMenu(Bar& bar)
ListMenuEx(bar);
}
void IconDes::ListMenuEx(Bar& bar) {}
void IconDes::Clear()
{
ilist.Clear();
@ -638,5 +633,3 @@ void IconDes::Drag()
{
ilist.DoDragAndDrop(InternalClip(ilist, "icondes-icon"), ilist.GetDragSample(), DND_MOVE);
}
}

View file

@ -1,9 +1,7 @@
#include "IconDes.h"
namespace Upp {
#define IMAGECLASS IconDesImg
#define IMAGEFILE <IconDes/IconDes.iml>
#define IMAGEFILE <ide/IconDes/IconDes.iml>
#include <Draw/iml_source.h>
void IconShow::Paint(Draw& w)
@ -270,5 +268,3 @@ void IconDes::Paint(Draw& w)
PaintHotSpot(image.Get2ndSpot(), LtBlue());
}
}
}

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
Color s_stdcolor[] = {
Black,
Red,
@ -234,5 +232,3 @@ RGBACtrl::RGBACtrl()
Add(text);
SyncText();
}
}

View file

@ -1,7 +1,5 @@
#include "IconDes.h"
namespace Upp {
RGBA GetPixel(const Image& img, int x, int y)
{
if(x < 0 || x >= img.GetWidth() || y < 0 || y >= img.GetHeight())
@ -80,7 +78,7 @@ void IconDes::Smoothen()
dlg.level <<= dlg.Breaker();
Image bk = ImageStart();
for(;;) {
ImageSet(Upp::Smoothen(bk, 0.4 * minmax((double)~dlg.level + 0.01, 0.01, 1.1)));
ImageSet(::Smoothen(bk, 0.4 * minmax((double)~dlg.level + 0.01, 0.01, 1.1)));
switch(dlg.Run()) {
case IDCANCEL:
ImageSet(bk);
@ -90,5 +88,3 @@ void IconDes::Smoothen()
}
}
}
}

View file

@ -1,94 +1,90 @@
#include "IconDes.h"
namespace Upp {
IconDes::TextDlg::TextDlg()
{
CtrlLayout(*this, "Text");
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
if(!dynamic_cast<Button *>(q))
q->WhenAction = Proxy(WhenAction);
face.Add(Font::ARIAL);
face.Add(Font::ROMAN);
face.Add(Font::COURIER);
for(int i = Font::COURIER + 1; i < Font::GetFaceCount(); i++)
if(Font::GetFaceInfo(i) & Font::SCALEABLE)
face.Add(i);
SetupFaceList(face);
face <<= Font::ARIAL;
height.MinMax(4, 600);
height <<= 12;
for(int i = 4; i < 300; i += i < 16 ? 1 : i < 32 ? 4 : i < 48 ? 8 : 16)
height.AddList(i);
}
Font IconDes::TextDlg::GetFont()
{
Font fnt(~face, ~height);
fnt.Bold(~bold);
fnt.Italic(~italic);
fnt.Underline(~underline);
fnt.Strikeout(~strikeout);
fnt.NonAntiAliased(~nonaa);
return fnt;
}
void IconDes::CloseText()
{
if(textdlg.IsOpen())
textdlg.Close();
SetBar();
}
void IconDes::PasteText()
{
if(!IsCurrent() || !IsPasting() || !textdlg.IsOpen())
return;
WString text = ~textdlg.text;
Font font = textdlg.GetFont();
Size tsz = GetTextSize(text, font);
tsz.cx += tsz.cy / 3;
ImageDraw iw(tsz);
iw.Alpha().DrawText(0, 0, text, font, GrayColor(CurrentColor().a));
iw.DrawRect(tsz, CurrentColor());
#ifdef PLATFORM_WIN32 // non-antialiased works
Current().paste_image = iw;
#else
if(!font.IsNonAntiAliased())
Current().paste_image = iw;
else {
Image h = iw;
ImageBuffer ib(h);
RGBA cc = CurrentColor();
for(RGBA& c : ib)
c = c.a < 128 ? RGBAZero() : cc;
Current().paste_image = ib;
}
#endif
MakePaste();
}
void IconDes::Text()
{
if(textdlg.IsOpen())
textdlg.Close();
else {
ONCELOCK {
Rect r = GetScreenView();
Size sz = textdlg.GetLayoutSize();
r.left = r.left + (r.GetWidth() - sz.cx) / 2;
r.right = r.left + sz.cx;
r.top = r.bottom - sz.cy;
textdlg.NoCenter().SetRect(r);
}
Paste(CreateImage(Size(1, 1), RGBAZero()));
textdlg.WhenClose = THISBACK(CloseText);
textdlg <<= THISBACK(PasteText);
textdlg.Open();
PasteText();
}
SetBar();
}
}
#include "IconDes.h"
IconDes::TextDlg::TextDlg()
{
CtrlLayout(*this, "Text");
for(Ctrl *q = GetFirstChild(); q; q = q->GetNext())
if(!dynamic_cast<Button *>(q))
q->WhenAction = Proxy(WhenAction);
face.Add(Font::ARIAL);
face.Add(Font::ROMAN);
face.Add(Font::COURIER);
for(int i = Font::COURIER + 1; i < Font::GetFaceCount(); i++)
if(Font::GetFaceInfo(i) & Font::SCALEABLE)
face.Add(i);
SetupFaceList(face);
face <<= Font::ARIAL;
height.MinMax(4, 600);
height <<= 12;
for(int i = 4; i < 300; i += i < 16 ? 1 : i < 32 ? 4 : i < 48 ? 8 : 16)
height.AddList(i);
}
Font IconDes::TextDlg::GetFont()
{
Font fnt(~face, ~height);
fnt.Bold(~bold);
fnt.Italic(~italic);
fnt.Underline(~underline);
fnt.Strikeout(~strikeout);
fnt.NonAntiAliased(~nonaa);
return fnt;
}
void IconDes::CloseText()
{
if(textdlg.IsOpen())
textdlg.Close();
SetBar();
}
void IconDes::PasteText()
{
if(!IsCurrent() || !IsPasting() || !textdlg.IsOpen())
return;
WString text = ~textdlg.text;
Font font = textdlg.GetFont();
Size tsz = GetTextSize(text, font);
tsz.cx += tsz.cy / 3;
ImageDraw iw(tsz);
iw.Alpha().DrawText(0, 0, text, font, GrayColor(CurrentColor().a));
iw.DrawRect(tsz, CurrentColor());
#ifdef PLATFORM_WIN32 // non-antialiased works
Current().paste_image = iw;
#else
if(!font.IsNonAntiAliased())
Current().paste_image = iw;
else {
Image h = iw;
ImageBuffer ib(h);
RGBA cc = CurrentColor();
for(RGBA& c : ib)
c = c.a < 128 ? RGBAZero() : cc;
Current().paste_image = ib;
}
#endif
MakePaste();
}
void IconDes::Text()
{
if(textdlg.IsOpen())
textdlg.Close();
else {
ONCELOCK {
Rect r = GetScreenView();
Size sz = textdlg.GetLayoutSize();
r.left = r.left + (r.GetWidth() - sz.cx) / 2;
r.right = r.left + sz.cx;
r.top = r.bottom - sz.cy;
textdlg.NoCenter().SetRect(r);
}
Paste(CreateImage(Size(1, 1), RGBAZero()));
textdlg.WhenClose = THISBACK(CloseText);
textdlg <<= THISBACK(PasteText);
textdlg.Open();
PasteText();
}
SetBar();
}

View file

@ -4,7 +4,7 @@
#include <ide/Common/Common.h>
#include <RichEdit/RichEdit.h>
#include <CodeEditor/CodeEditor.h>
#include <IconDes/IconDes.h>
#include <ide/IconDes/IconDes.h>
#include <ide/Browser/Browser.h>
#define LAYOUTFILE <ide/LayDes/LayDes.lay>

View file

@ -3,7 +3,6 @@ description "TheIDE - layout (.lay) designer \377B";
uses
RichEdit,
Esc,
IconDes,
CodeEditor,
ide/Common,
ide/Browser;

View file

@ -4,7 +4,6 @@ uses
ide\Common,
ide\Core,
ide\LayDes,
ide\IconDes,
ide\Builders,
ide\Debuggers,
ide\Browser,