mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-15 14:16:07 -06:00
ide: IconDes code moved to ide/IconDes
This commit is contained in:
parent
5a2e47a495
commit
e1c1b82a11
31 changed files with 1395 additions and 1519 deletions
|
|
@ -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.
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
@ -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() {}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -1,7 +1,5 @@
|
|||
#include "IconDes.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
void AlphaCtrl::Layout()
|
||||
{
|
||||
MakeImage();
|
||||
|
|
@ -121,5 +119,3 @@ AlphaCtrl::AlphaCtrl()
|
|||
mask = false;
|
||||
maskvalue = 255;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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;
|
||||
|
|
|
|||
103
uppsrc/ide/IconDes/IdeIconDes.cpp
Normal file
103
uppsrc/ide/IconDes/IdeIconDes.cpp
Normal 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));
|
||||
}
|
||||
|
|
@ -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()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,5 @@
|
|||
#include "IconDes.h"
|
||||
|
||||
namespace Upp {
|
||||
|
||||
Color s_stdcolor[] = {
|
||||
Black,
|
||||
Red,
|
||||
|
|
@ -234,5 +232,3 @@ RGBACtrl::RGBACtrl()
|
|||
Add(text);
|
||||
SyncText();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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()
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -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();
|
||||
}
|
||||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -3,7 +3,6 @@ description "TheIDE - layout (.lay) designer \377B";
|
|||
uses
|
||||
RichEdit,
|
||||
Esc,
|
||||
IconDes,
|
||||
CodeEditor,
|
||||
ide/Common,
|
||||
ide/Browser;
|
||||
|
|
|
|||
|
|
@ -4,7 +4,6 @@ uses
|
|||
ide\Common,
|
||||
ide\Core,
|
||||
ide\LayDes,
|
||||
ide\IconDes,
|
||||
ide\Builders,
|
||||
ide\Debuggers,
|
||||
ide\Browser,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue