[aseprite] 159/196: Add possibility to recover raw images from a session (as a sequence of frames or layers)

Tobias Hansen thansen at moszumanska.debian.org
Wed Apr 20 18:50:15 UTC 2016


This is an automated email from the git hooks/post-receive script.

thansen pushed a commit to branch master
in repository aseprite.

commit 495a645917678fe9af93af0b3ada9b6fb1a89fda
Author: David Capello <davidcapello at gmail.com>
Date:   Thu Apr 7 16:12:03 2016 -0300

    Add possibility to recover raw images from a session (as a sequence of frames or layers)
    
    This might be useful in extreme cases where the normal restoration
    procedure doesn't work/restore the whole sprite structure correctly.
---
 src/app/crash/raw_images_as.h     | 23 ++++++++++++++++
 src/app/crash/read_document.cpp   | 58 +++++++++++++++++++++++++++++++++++++++
 src/app/crash/read_document.h     |  5 +++-
 src/app/crash/session.cpp         | 44 +++++++++++++++++++++--------
 src/app/crash/session.h           |  5 +++-
 src/app/ui/data_recovery_view.cpp | 50 +++++++++++++++++++++++++--------
 src/app/ui/skin/skin_theme.cpp    |  4 ++-
 7 files changed, 162 insertions(+), 27 deletions(-)

diff --git a/src/app/crash/raw_images_as.h b/src/app/crash/raw_images_as.h
new file mode 100644
index 0000000..1558bfb
--- /dev/null
+++ b/src/app/crash/raw_images_as.h
@@ -0,0 +1,23 @@
+// Aseprite
+// Copyright (C) 2001-2016  David Capello
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as
+// published by the Free Software Foundation.
+
+#ifndef APP_CRASH_RAW_IMAGES_H_INCLUDED
+#define APP_CRASH_RAW_IMAGES_H_INCLUDED
+#pragma once
+
+namespace app {
+namespace crash {
+
+  enum class RawImagesAs {
+    kFrames,
+    kLayers,
+  };
+
+} // namespace crash
+} // namespace app
+
+#endif
diff --git a/src/app/crash/read_document.cpp b/src/app/crash/read_document.cpp
index 2afcb10..5e4c096 100644
--- a/src/app/crash/read_document.cpp
+++ b/src/app/crash/read_document.cpp
@@ -378,5 +378,63 @@ app::Document* read_document(const std::string& dir)
   return Reader(dir).loadDocument();
 }
 
+app::Document* read_document_with_raw_images(const std::string& dir,
+                                             RawImagesAs as)
+{
+  Reader reader(dir);
+
+  DocumentInfo info;
+  if (!reader.loadDocumentInfo(info)) {
+    info.format = IMAGE_RGB;
+    info.width = 256;
+    info.height = 256;
+    info.filename = "Unknown";
+  }
+  info.width = MID(1, info.width, 99999);
+  info.height = MID(1, info.height, 99999);
+  Sprite* spr = new Sprite(info.format, info.width, info.height, 256);
+
+  // Load each image as a new frame
+  auto lay = new LayerImage(spr);
+  spr->folder()->addLayer(lay);
+
+  frame_t frame = 0;
+  for (const auto& fn : base::list_files(dir)) {
+    if (fn.compare(0, 3, "img") != 0)
+      continue;
+
+    std::ifstream s(FSTREAM_PATH(base::join_path(dir, fn)), std::ifstream::binary);
+    if (!s)
+      continue;
+
+    ImageRef img;
+    if (read32(s) == MAGIC_NUMBER)
+      img.reset(read_image(s, false));
+
+    if (img) {
+      lay->addCel(new Cel(frame, img));
+    }
+
+    switch (as) {
+      case RawImagesAs::kFrames:
+        ++frame;
+        break;
+      case RawImagesAs::kLayers:
+        lay = new LayerImage(spr);
+        spr->folder()->addLayer(lay);
+        break;
+    }
+  }
+  if (as == RawImagesAs::kFrames) {
+    if (frame > 1)
+      spr->setTotalFrames(frame);
+  }
+
+  app::Document* doc = new app::Document(spr);
+  doc->setFilename(info.filename);
+  doc->impossibleToBackToSavedState();
+  return doc;
+}
+
 } // namespace crash
 } // namespace app
diff --git a/src/app/crash/read_document.h b/src/app/crash/read_document.h
index 41122cd..dc75309 100644
--- a/src/app/crash/read_document.h
+++ b/src/app/crash/read_document.h
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -9,6 +9,7 @@
 #define APP_CRASH_READ_DOCUMENT_H_INCLUDED
 #pragma once
 
+#include "app/crash/raw_images_as.h"
 #include "doc/frame.h"
 #include "doc/pixel_format.h"
 
@@ -35,6 +36,8 @@ namespace crash {
 
   bool read_document_info(const std::string& dir, DocumentInfo& info);
   app::Document* read_document(const std::string& dir);
+  app::Document* read_document_with_raw_images(const std::string& dir,
+                                               RawImagesAs as);
 
 } // namespace crash
 } // namespace app
diff --git a/src/app/crash/session.cpp b/src/app/crash/session.cpp
index c262c2b..eb377e3 100644
--- a/src/app/crash/session.cpp
+++ b/src/app/crash/session.cpp
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -166,18 +166,22 @@ void Session::restoreBackup(Backup* backup)
   try {
     app::Document* doc = read_document(backup->dir());
     if (doc) {
-      std::string fn = doc->filename();
-      if (!fn.empty()) {
-        std::string ext = base::get_file_extension(fn);
-        if (!ext.empty())
-          ext = "." + ext;
-
-        doc->setFilename(
-          base::join_path(
-            base::get_file_path(fn),
-            base::get_file_title(fn) + "-Recovered" + ext));
-      }
+      fixFilename(doc);
+      UIContext::instance()->documents().add(doc);
+    }
+  }
+  catch (const std::exception& ex) {
+    Console::showException(ex);
+  }
+}
 
+void Session::restoreRawImages(Backup* backup, RawImagesAs as)
+{
+  Console console;
+  try {
+    app::Document* doc = read_document_with_raw_images(backup->dir(), as);
+    if (doc) {
+      fixFilename(doc);
       UIContext::instance()->documents().add(doc);
     }
   }
@@ -241,5 +245,21 @@ void Session::deleteDirectory(const std::string& dir)
   base::remove_directory(dir);
 }
 
+void Session::fixFilename(app::Document* doc)
+{
+  std::string fn = doc->filename();
+  if (fn.empty())
+    return;
+
+  std::string ext = base::get_file_extension(fn);
+  if (!ext.empty())
+    ext = "." + ext;
+
+  doc->setFilename(
+    base::join_path(
+      base::get_file_path(fn),
+      base::get_file_title(fn) + "-Recovered" + ext));
+}
+
 } // namespace crash
 } // namespace app
diff --git a/src/app/crash/session.h b/src/app/crash/session.h
index dbded8f..ec97529 100644
--- a/src/app/crash/session.h
+++ b/src/app/crash/session.h
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -9,6 +9,7 @@
 #define APP_CRASH_SESSION_H_INCLUDED
 #pragma once
 
+#include "app/crash/raw_images_as.h"
 #include "base/disable_copying.h"
 #include "base/process.h"
 #include "base/shared_ptr.h"
@@ -52,6 +53,7 @@ namespace crash {
     void removeDocument(app::Document* doc);
 
     void restoreBackup(Backup* backup);
+    void restoreRawImages(Backup* backup, RawImagesAs as);
     void deleteBackup(Backup* backup);
 
   private:
@@ -59,6 +61,7 @@ namespace crash {
     std::string pidFilename() const;
     std::string verFilename() const;
     void deleteDirectory(const std::string& dir);
+    void fixFilename(app::Document* doc);
 
     base::pid m_pid;
     std::string m_path;
diff --git a/src/app/ui/data_recovery_view.cpp b/src/app/ui/data_recovery_view.cpp
index 4c4e2f2..4bfa092 100644
--- a/src/app/ui/data_recovery_view.cpp
+++ b/src/app/ui/data_recovery_view.cpp
@@ -1,5 +1,5 @@
 // Aseprite
-// Copyright (C) 2001-2015  David Capello
+// Copyright (C) 2001-2016  David Capello
 //
 // This program is free software; you can redistribute it and/or modify
 // it under the terms of the GNU General Public License version 2 as
@@ -15,6 +15,7 @@
 #include "app/crash/data_recovery.h"
 #include "app/crash/session.h"
 #include "app/modules/gui.h"
+#include "app/ui/drop_down_button.h"
 #include "app/ui/skin/skin_style_property.h"
 #include "app/ui/skin/skin_theme.h"
 #include "app/ui/workspace.h"
@@ -24,8 +25,8 @@
 #include "ui/entry.h"
 #include "ui/listitem.h"
 #include "ui/message.h"
-#include "ui/size_hint_event.h"
 #include "ui/resize_event.h"
+#include "ui/size_hint_event.h"
 #include "ui/system.h"
 #include "ui/view.h"
 
@@ -45,10 +46,14 @@ public:
     , m_openButton(backup ? "Open": "Open All")
     , m_deleteButton(backup ? "Delete": "Delete All")
   {
-    addChild(&m_openButton);
-    addChild(&m_deleteButton);
+    m_hbox.setBgColor(gfx::ColorNone);
+    m_hbox.setTransparent(true);
+    m_hbox.addChild(&m_openButton);
+    m_hbox.addChild(&m_deleteButton);
+    addChild(&m_hbox);
 
     m_openButton.Click.connect(base::Bind(&Item::onOpen, this));
+    m_openButton.DropDownClick.connect(base::Bind<void>(&Item::onOpenMenu, this));
     m_deleteButton.Click.connect(base::Bind(&Item::onDelete, this));
 
     setup_mini_look(&m_openButton);
@@ -68,13 +73,10 @@ protected:
     ListItem::onResize(ev);
 
     gfx::Rect rc = ev.bounds();
-    gfx::Size sz1 = m_openButton.sizeHint();
-    sz1.w *= 2*guiscale();
-    gfx::Size sz2 = m_deleteButton.sizeHint();
-    int h = rc.h*3/4;
-    int sep = 8*guiscale();
-    m_openButton.setBounds(gfx::Rect(rc.x+rc.w-sz2.w-sz1.w-2*sep, rc.y+rc.h/2-h/2, sz1.w, h));
-    m_deleteButton.setBounds(gfx::Rect(rc.x+rc.w-sz2.w-sep, rc.y+rc.h/2-h/2, sz2.w, h));
+    gfx::Size sz = m_hbox.sizeHint();
+    m_hbox.setBounds(
+      gfx::Rect(
+        rc.x+rc.w-sz.w-2*guiscale(), rc.y+rc.h/2-sz.h/2, sz.w, sz.h));
   }
 
   void onOpen() {
@@ -85,6 +87,29 @@ protected:
         m_session->restoreBackup(backup);
   }
 
+  void onOpenRaw(crash::RawImagesAs as) {
+    if (m_backup)
+      m_session->restoreRawImages(m_backup, as);
+    else
+      for (auto backup : m_session->backups())
+        m_session->restoreRawImages(backup, as);
+  }
+
+  void onOpenMenu() {
+    gfx::Rect bounds = m_openButton.bounds();
+
+    Menu menu;
+    MenuItem rawFrames("Raw Images as Frames");
+    MenuItem rawLayers("Raw Images as Layers");
+    menu.addChild(&rawFrames);
+    menu.addChild(&rawLayers);
+
+    rawFrames.Click.connect(base::Bind(&Item::onOpenRaw, this, crash::RawImagesAs::kFrames));
+    rawLayers.Click.connect(base::Bind(&Item::onOpenRaw, this, crash::RawImagesAs::kLayers));
+
+    menu.showPopup(gfx::Point(bounds.x, bounds.y+bounds.h));
+  }
+
   void onDelete() {
     Widget* parent = this->parent();
 
@@ -126,7 +151,8 @@ protected:
 private:
   crash::Session* m_session;
   crash::Session::Backup* m_backup;
-  ui::Button m_openButton;
+  ui::HBox m_hbox;
+  DropDownButton m_openButton;
   ui::Button m_deleteButton;
 };
 
diff --git a/src/app/ui/skin/skin_theme.cpp b/src/app/ui/skin/skin_theme.cpp
index 52e3295..3e18549 100644
--- a/src/app/ui/skin/skin_theme.cpp
+++ b/src/app/ui/skin/skin_theme.cpp
@@ -765,8 +765,10 @@ void SkinTheme::paintBox(PaintEvent& ev)
   Widget* widget = static_cast<Widget*>(ev.getSource());
   Graphics* g = ev.graphics();
 
-  if (!is_transparent(BGCOLOR))
+  if (!widget->isTransparent() &&
+      !is_transparent(BGCOLOR)) {
     g->fillRect(BGCOLOR, g->getClipBounds());
+  }
 }
 
 void SkinTheme::paintButton(PaintEvent& ev)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-games/aseprite.git



More information about the Pkg-games-commits mailing list