diff --git a/uppsrc/IconDes/Bar.cpp b/uppsrc/IconDes/Bar.cpp index bd1232631..6eb2a47cf 100644 --- a/uppsrc/IconDes/Bar.cpp +++ b/uppsrc/IconDes/Bar.cpp @@ -286,6 +286,8 @@ IconDes::IconDes() magnify = 13; pen = 1; + + single_mode = false; } END_UPP_NAMESPACE diff --git a/uppsrc/IconDes/IconDes.cpp b/uppsrc/IconDes/IconDes.cpp index 2672c7c18..28dcf0a40 100644 --- a/uppsrc/IconDes/IconDes.cpp +++ b/uppsrc/IconDes/IconDes.cpp @@ -429,7 +429,7 @@ void IconDes::SaveUndo() return; Slot& c = Current(); Vector undo = UnpackImlData(c.undo); - int maxn = minmax(400000 / max(c.image.GetLength(), 1), 4, 128); + int maxn = minmax((single_mode ? 4000000 : 400000) / max(c.image.GetLength(), 1), 4, 128); while(undo.GetCount() > maxn) undo.Remove(0); if(undo.GetCount() && undo.Top() == c.image) @@ -490,6 +490,8 @@ void IconDes::SyncImage() 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; SetBar(); @@ -576,4 +578,16 @@ void IconDes::ResizeDown() Reset(); } +void IconDes::SingleMode() +{ + single_mode = true; + list.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); +} + END_UPP_NAMESPACE diff --git a/uppsrc/IconDes/IconDes.h b/uppsrc/IconDes/IconDes.h index b20038003..ad5b769b5 100644 --- a/uppsrc/IconDes/IconDes.h +++ b/uppsrc/IconDes/IconDes.h @@ -147,6 +147,10 @@ private: IconShow iconshow; Image cursor_image; Image fill_cursor; + bool single_mode; + ParentCtrl single; + Label info; + Button resize; Array removed; @@ -265,9 +269,11 @@ private: void SyncList(); void ListCursor(); void PrepareImageDlg(WithImageLayout& dlg); + void PrepareImageSizeDlg(WithImageSizeLayout& dlg); void ImageInsert(const String& name, const Image& m, bool exp = false); void InsertImage(); void InsertRemoved(int ii); + void EditImageSize(); void EditImage(); void RemoveImage(); void Duplicate(); @@ -318,7 +324,8 @@ public: void SerializeSettings(Stream& s); - void HideList() { list.Hide(); } + void SingleMode(); + bool IsSingleMode() const { return single_mode; } typedef IconDes CLASSNAME; diff --git a/uppsrc/IconDes/IconDes.key b/uppsrc/IconDes/IconDes.key index de41e7ebd..a677237cb 100644 --- a/uppsrc/IconDes/IconDes.key +++ b/uppsrc/IconDes/IconDes.key @@ -44,3 +44,4 @@ 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) \ No newline at end of file diff --git a/uppsrc/IconDes/IconDes.lay b/uppsrc/IconDes/IconDes.lay index b55bfea09..80fdb3a51 100644 --- a/uppsrc/IconDes/IconDes.lay +++ b/uppsrc/IconDes/IconDes.lay @@ -10,6 +10,15 @@ LAYOUT(ImageLayout, 168, 108) ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(96, 64).TopPosZ(80, 24)) END_LAYOUT +LAYOUT(ImageSizeLayout, 168, 68) + ITEM(Label, dv___0, SetLabel(t_("Size")).LeftPosZ(8, 40).TopPosZ(8, 19)) + ITEM(EditIntSpin, cx, Min(1).Max(8192).LeftPosZ(52, 44).TopPosZ(8, 19)) + ITEM(EditIntSpin, cy, Min(1).Max(8192).LeftPosZ(116, 44).TopPosZ(8, 19)) + ITEM(Label, dv___3, SetLabel(t_("x")).LeftPosZ(100, 12).TopPosZ(8, 16)) + ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(28, 64).TopPosZ(36, 24)) + ITEM(Button, cancel, SetLabel(t_("Cancel")).LeftPosZ(96, 64).TopPosZ(36, 24)) +END_LAYOUT + LAYOUT(FilePropertiesLayout, 176, 68) ITEM(Option, format, SetLabel(t_("Legacy .iml format")).LeftPosZ(8, 160).TopPosZ(8, 15)) ITEM(Button, ok, SetLabel(t_("OK")).LeftPosZ(36, 64).TopPosZ(36, 24)) diff --git a/uppsrc/IconDes/List.cpp b/uppsrc/IconDes/List.cpp index 149ea3093..ab3fdb61a 100644 --- a/uppsrc/IconDes/List.cpp +++ b/uppsrc/IconDes/List.cpp @@ -52,6 +52,18 @@ void IconDes::PrepareImageDlg(WithImageLayout& dlg) dlg.name.SetFilter(sCharFilterCid); } +void IconDes::PrepareImageSizeDlg(WithImageSizeLayout& dlg) +{ + CtrlLayoutOKCancel(dlg, "New image"); + dlg.cx <<= 16; + dlg.cy <<= 16; + if(IsCurrent()) { + Size sz = GetImageSize(); + dlg.cx <<= sz.cx; + dlg.cy <<= sz.cy; + } +} + bool CheckName(WithImageLayout& dlg) { String n = dlg.name; @@ -207,10 +219,40 @@ void IconDes::ListCursor() SyncImage(); } +void IconDes::EditImageSize() +{ + Slot& c = Current(); + WithImageSizeLayout dlg; + PrepareImageSizeDlg(dlg); + dlg.Breaker(dlg.cx); + dlg.Breaker(dlg.cy); + Image img = c.image; + dlg.cx <<= img.GetWidth(); + dlg.cy <<= img.GetHeight(); + for(;;) { + switch(dlg.Run()) { + case IDCANCEL: + c.image = img; + Reset(); + return; + case IDOK: + Reset(); + return; + } + c.image = CreateImage(Size(minmax((int)~dlg.cx, 1, 8192), minmax((int)~dlg.cy, 1, 8192)), Null); + UPP::Copy(c.image, Point(0, 0), img, img.GetSize()); + Reset(); + } +} + void IconDes::EditImage() { if(!IsCurrent()) return; + if(single_mode) { + EditImageSize(); + return; + } Slot& c = Current(); WithImageLayout dlg; PrepareImageDlg(dlg); @@ -289,25 +331,29 @@ void IconDes::ChangeSlot(int d) void IconDes::ListMenu(Bar& bar) { using namespace IconDesKeys; - bar.Add(AK_INSERT_IMAGE, IconDesImg::Insert(), THISBACK(InsertImage)); - bar.Add(IsCurrent(), AK_IMAGE, IconDesImg::Edit(), THISBACK(EditImage)); - bar.Add(IsCurrent(), AK_REMOVE_IMAGE, IconDesImg::Remove(), THISBACK(RemoveImage)); - bar.Add(IsCurrent(), AK_DUPLICATE, IconDesImg::Duplicate(), THISBACK(Duplicate)); - bar.Add(AK_INSERT_CLIP, IconDesImg::InsertPaste(), THISBACK(InsertPaste)); - bar.Add(AK_INSERT_FILE, IconDesImg::InsertFile(), THISBACK(InsertFile)); - bar.Add(AK_INSERT_IML, IconDesImg::InsertIml(), THISBACK(InsertIml)); - bar.Add(AK_EXPORT_PNGS, IconDesImg::ExportPngs(), THISBACK(ExportPngs)); - bar.Separator(); - bar.Add(IsCurrent() && list.GetCursor() > 0, AK_MOVE_UP, IconDesImg::MoveUp(), - THISBACK1(MoveSlot, -1)); - bar.Add(IsCurrent() && list.GetCursor() < slot.GetCount() - 1, AK_MOVE_DOWN, IconDesImg::MoveDown(), - THISBACK1(MoveSlot, 1)); - if(removed.GetCount()) { + if(single_mode) + bar.Add(IsCurrent(), AK_RESIZE_SINGLE, IconDesImg::Edit(), THISBACK(EditImage)); + else { + bar.Add(AK_INSERT_IMAGE, IconDesImg::Insert(), THISBACK(InsertImage)); + bar.Add(IsCurrent(), AK_IMAGE, IconDesImg::Edit(), THISBACK(EditImage)); + bar.Add(IsCurrent(), AK_REMOVE_IMAGE, IconDesImg::Remove(), THISBACK(RemoveImage)); + bar.Add(IsCurrent(), AK_DUPLICATE, IconDesImg::Duplicate(), THISBACK(Duplicate)); + bar.Add(AK_INSERT_CLIP, IconDesImg::InsertPaste(), THISBACK(InsertPaste)); + bar.Add(AK_INSERT_FILE, IconDesImg::InsertFile(), THISBACK(InsertFile)); + bar.Add(AK_INSERT_IML, IconDesImg::InsertIml(), THISBACK(InsertIml)); + bar.Add(AK_EXPORT_PNGS, IconDesImg::ExportPngs(), THISBACK(ExportPngs)); bar.Separator(); - for(int i = removed.GetCount() - 1; i >= 0; i--) { - Slot& r = removed[i]; - bar.Add("Insert " + sFormatImageName(r.name, r.image, r.exp), r.base_image, - THISBACK1(InsertRemoved, i)); + bar.Add(IsCurrent() && list.GetCursor() > 0, AK_MOVE_UP, IconDesImg::MoveUp(), + THISBACK1(MoveSlot, -1)); + bar.Add(IsCurrent() && list.GetCursor() < slot.GetCount() - 1, AK_MOVE_DOWN, IconDesImg::MoveDown(), + THISBACK1(MoveSlot, 1)); + if(removed.GetCount()) { + bar.Separator(); + for(int i = removed.GetCount() - 1; i >= 0; i--) { + Slot& r = removed[i]; + bar.Add("Insert " + sFormatImageName(r.name, r.image, r.exp), r.base_image, + THISBACK1(InsertRemoved, i)); + } } } bar.Separator(); diff --git a/uppsrc/ide/IconDes/IconDes.cpp b/uppsrc/ide/IconDes/IconDes.cpp index 2547fd1e6..d5770be8b 100644 --- a/uppsrc/ide/IconDes/IconDes.cpp +++ b/uppsrc/ide/IconDes/IconDes.cpp @@ -63,7 +63,8 @@ void IdeIconDes::Save() void IdeIconDes::ToolEx(Bar& bar) { bar.Separator(); - bar.Add("File properties..", IconDesImg::FileProperties(), THISBACK(FileProperties)); + if(!IsSingleMode()) + bar.Add("File properties..", IconDesImg::FileProperties(), THISBACK(FileProperties)); } void IdeIconDes::FileProperties() @@ -88,7 +89,7 @@ void IdeIconDes::EditMenu(Bar& bar) { EditBar(bar); ToolEx(bar); - bar.Add("List", THISBACK(ListMenu)); + bar.Add(IsSingleMode() ? "PNG" : "List", THISBACK(ListMenu)); bar.Add("Selection", THISBACK(SelectBar)); bar.Add("Image", THISBACK(ImageBar)); bar.Add("Draw", THISBACK(DrawBar)); diff --git a/uppsrc/ide/IconDes/IconDes.h b/uppsrc/ide/IconDes/IconDes.h index 182dcd54a..d0ae7be79 100644 --- a/uppsrc/ide/IconDes/IconDes.h +++ b/uppsrc/ide/IconDes/IconDes.h @@ -23,6 +23,7 @@ struct IdeIconDes : IdeDesigner, IconDes { bool Load(const char *filename); void FileProperties(); void CopyId(const String& n); + void RestoreEditPos(); typedef IdeIconDes CLASSNAME; diff --git a/uppsrc/ide/IconDes/IdeDes.icpp b/uppsrc/ide/IconDes/IdeDes.icpp index 5c1d55522..10483f085 100644 --- a/uppsrc/ide/IconDes/IdeDes.icpp +++ b/uppsrc/ide/IconDes/IdeDes.icpp @@ -47,6 +47,13 @@ void SerializeIconDesPos(Stream& s) } } +void IdeIconDes::RestoreEditPos() +{ + IdeIconEditPos& ep = sEP().GetAdd(filename); + if(ep.filetime == filetime) + SetEditPos(ep); +} + bool IsImlFile(const char *path) { return ToLower(GetFileExt(path)) == ".iml"; @@ -63,9 +70,7 @@ struct IconDesModule : public IdeModule { IdeIconDes *d = new IdeIconDes; LoadFromGlobal(*d, "icondes-ctrl"); if(d->Load(path)) { - IdeIconEditPos& ep = sEP().GetAdd(path); - if(ep.filetime == d->filetime) - d->SetEditPos(ep); + d->RestoreEditPos(); return d; } delete d; @@ -93,6 +98,8 @@ void IdeIconDes::CopyId(const String& n) void IdeIconDes::ListMenuEx(Bar& bar) { + if(IsSingleMode()) + return; String n = GetCurrentName(); String c = GetFileTitle(filename); c.Set(0, ToUpper(c[0])); diff --git a/uppsrc/ide/Img/Img.h b/uppsrc/ide/Img/Img.h index ed1413268..3b8ed4b1a 100644 --- a/uppsrc/ide/Img/Img.h +++ b/uppsrc/ide/Img/Img.h @@ -23,6 +23,7 @@ struct IdePngDes : IdeIconDes { virtual void Save(); void Load(const char *filename); + void Create(const char *filename); }; #endif \ No newline at end of file diff --git a/uppsrc/ide/Img/Img.icpp b/uppsrc/ide/Img/Img.icpp index f6df76d82..9a0601d83 100644 --- a/uppsrc/ide/Img/Img.icpp +++ b/uppsrc/ide/Img/Img.icpp @@ -44,6 +44,7 @@ struct ImageViewModule : public IdeModule { if(ToLower(GetFileExt(path)) == ".png" && sz.cx <= 768 && sz.cy <= 512) { IdePngDes *d = new IdePngDes; d->Load(path); + d->RestoreEditPos(); return d; } else { @@ -60,6 +61,13 @@ struct ImageViewModule : public IdeModule { return d; } } + else + if(ToLower(GetFileExt(path)) == ".png" && GetFileLength(path) == 0) { + IdePngDes *d = new IdePngDes; + d->Create(path); + d->RestoreEditPos(); + return d; + } } return NULL; } diff --git a/uppsrc/ide/Img/Png.cpp b/uppsrc/ide/Img/Png.cpp index 444ea8498..9eb36d0a5 100644 --- a/uppsrc/ide/Img/Png.cpp +++ b/uppsrc/ide/Img/Png.cpp @@ -3,7 +3,8 @@ void IdePngDes::Save() { if(GetCount()) - SaveChangedFile(filename, PNGEncoder().SaveString(GetImage(0)), true); + SaveChangedFileFinish(filename, PNGEncoder().SaveString(GetImage(0))); + filetime = FileGetTime(filename); } void IdePngDes::Load(const char *_filename) @@ -13,5 +14,15 @@ void IdePngDes::Load(const char *_filename) filetime = FileGetTime(filename); Image m = StreamRaster::LoadFileAny(filename); AddImage(filename, m, false); - HideList(); + SingleMode(); +} + +void IdePngDes::Create(const char *_filename) +{ + Clear(); + filename = _filename; + filetime = GetSysTime(); + Image m = CreateImage(Size(16, 16), Null); + AddImage(filename, m, false); + SingleMode(); }