コード例 #1
0
void PropertiesEditorDialog::valueChanged(QtProperty *property, const QVariant &value)
{
    if (!m_property_to_id.contains(property))
    {
        return;
    }

    if (!m_canvas)
    {
        return;
    }
    QList<CanvasItem *> list = m_canvas->selectedItems();

    m_canvas->beginUndoMacro(tr("Change Property"));
    if (list.empty())
    {
        // Set the property directly on the canvas:
        m_canvas->setProperty(m_property_to_id[property].toLatin1().constData(), value);
    }
    else
    {
        // Otherwise, set it on the first item in the selection:
        CanvasItem *item = list.front();
        item->setProperty(m_property_to_id[property].toLatin1().constData(), value);
    }
}
コード例 #2
0
ファイル: node_2d.cpp プロジェクト: 93i/godot
void Node2D::set_global_transform(const Transform2D &p_transform) {

	CanvasItem *pi = get_parent_item();
	if (pi)
		set_transform(pi->get_global_transform().affine_inverse() * p_transform);
	else
		set_transform(p_transform);
}
コード例 #3
0
ファイル: canvas_item.cpp プロジェクト: brakhane/godot
CanvasItem *CanvasItem::get_toplevel() const {

	CanvasItem *ci = const_cast<CanvasItem *>(this);
	while (!ci->toplevel && Object::cast_to<CanvasItem>(ci->get_parent())) {
		ci = Object::cast_to<CanvasItem>(ci->get_parent());
	}

	return ci;
}
コード例 #4
0
ファイル: node_2d.cpp プロジェクト: 93i/godot
void Node2D::set_global_rotation(float p_radians) {

	CanvasItem *pi = get_parent_item();
	if (pi) {
		const float parent_global_rot = pi->get_global_transform().get_rotation();
		set_rotation(p_radians - parent_global_rot);
	} else {
		set_rotation(p_radians);
	}
}
コード例 #5
0
ファイル: node_2d.cpp プロジェクト: 93i/godot
void Node2D::set_global_scale(const Size2 &p_scale) {

	CanvasItem *pi = get_parent_item();
	if (pi) {
		const Size2 parent_global_scale = pi->get_global_transform().get_scale();
		set_scale(p_scale / parent_global_scale);
	} else {
		set_scale(p_scale);
	}
}
コード例 #6
0
ファイル: canvas_item.cpp プロジェクト: Scrik/godot
void CanvasItem::_notification(int p_what) {


	switch(p_what) {
		case NOTIFICATION_ENTER_TREE: {

			first_draw=true;
			pending_children_sort=false;
			if (get_parent()) {
				CanvasItem *ci = get_parent()->cast_to<CanvasItem>();
				if (ci)
					C=ci->children_items.push_back(this);
			}
			_enter_canvas();
			if (!block_transform_notify && !xform_change.in_list()) {
				get_tree()->xform_change_list.add(&xform_change);
			}
		} break;
		case NOTIFICATION_MOVED_IN_PARENT: {


			if (group!="") {
				get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_raise_self");
			} else {
				CanvasItem *p = get_parent_item();
				ERR_FAIL_COND(!p);
				p->_queue_sort_children();
			}


		} break;
		case NOTIFICATION_EXIT_TREE: {
			if (xform_change.in_list())
				get_tree()->xform_change_list.remove(&xform_change);
			_exit_canvas();
			if (C) {
				get_parent()->cast_to<CanvasItem>()->children_items.erase(C);
				C=NULL;
			}
			global_invalid=true;
		} break;
		case NOTIFICATION_DRAW: {

		} break;
		case NOTIFICATION_TRANSFORM_CHANGED: {


		} break;
		case NOTIFICATION_VISIBILITY_CHANGED: {

			emit_signal(SceneStringNames::get_singleton()->visibility_changed);
		} break;

	}
}
コード例 #7
0
ファイル: node_2d.cpp プロジェクト: Ragar0ck/godot
void Node2D::set_global_pos(const Point2& p_pos) {

	Matrix32 inv;
	CanvasItem *pi = get_parent_item();
	if (pi) {
		inv = pi->get_global_transform().affine_inverse();
		set_pos(inv.xform(p_pos));
	} else {
		set_pos(p_pos);
	}
}
コード例 #8
0
ファイル: canvas_item.cpp プロジェクト: brakhane/godot
Rect2 CanvasItem::_edit_get_item_and_children_rect() const {

	Rect2 rect = _edit_get_rect();

	for (int i = 0; i < get_child_count(); i++) {
		CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));
		if (c) {
			Rect2 sir = c->get_transform().xform(c->_edit_get_item_and_children_rect());
			rect = rect.merge(sir);
		}
	}

	return rect;
}
コード例 #9
0
ファイル: canvas_item.cpp プロジェクト: brakhane/godot
Ref<World2D> CanvasItem::get_world_2d() const {

	ERR_FAIL_COND_V(!is_inside_tree(), Ref<World2D>());

	CanvasItem *tl = get_toplevel();

	if (tl->canvas_layer) {
		return tl->canvas_layer->get_world_2d();
	} else if (tl->get_viewport()) {
		return tl->get_viewport()->find_world_2d();
	} else {
		return Ref<World2D>();
	}
}
コード例 #10
0
ファイル: statefactory.cpp プロジェクト: fant12/geditor
bool StateFactory::connectToSprite(AbstractSpriteState *state, QString name){

    CanvasItem *item = Drawer::instance()->getItems()->value(name, NULL);

    if(item){
        Sprite *sprite = new Sprite(name, item->getX(), item->getY(), item->getWidth(), item->getHeight());
        sprite->getStateMachine()->addState(state);
        Drawer::instance()->getItems()->insert(name, sprite);
        delete item;

        return true;
    }
    return false;
}
コード例 #11
0
ファイル: guideline.cpp プロジェクト: skieffer/ortho
void Guideline::move_to(int x, int y, bool store_undo, bool human)
{
    Q_UNUSED (x)
    Q_UNUSED (y)
    Q_UNUSED (store_undo)
    Q_UNUSED (human)
#if 0
    CanvasItem *cobj = this;
    int newval = 0;
    bool is_leader = false;
    int newx = 4 - cxoff, newy = 4 - cyoff;

    if (type == GUIDE_TYPE_VERT)
    {
        newval = x;
        newx = x;
    }
    else if (type == GUIDE_TYPE_HORI)
    {
        newval = y;
        newy = y;
    }
    fPos = newval;

    if ((newx == xpos) && (newy == ypos))
    {
        // Not moving, so do nothing.
        return;
    }

    bool freeshift = canvas()->isLayoutSuspended();
    if (freeshift)
    {
        d_printf("FREESHIFT\n");
    }
    
    if (human && (!is_leader || freeshift))
    {
        removeFromDistributions(freeshift);
        // Since the previous call will have suggested new values for
        // the guidelines involved in the distribution we need to resolve
        // here to avoid what looks like an unsovable state.
        
    }

    cobj->move_to(newx, newy, store_undo);
#endif
}
コード例 #12
0
ファイル: canvas_item.cpp プロジェクト: brakhane/godot
void CanvasItem::_enter_canvas() {

	if ((!Object::cast_to<CanvasItem>(get_parent())) || toplevel) {

		Node *n = this;

		canvas_layer = NULL;

		while (n) {

			canvas_layer = Object::cast_to<CanvasLayer>(n);
			if (canvas_layer) {
				break;
			}
			n = n->get_parent();
		}

		RID canvas;
		if (canvas_layer)
			canvas = canvas_layer->get_world_2d()->get_canvas();
		else
			canvas = get_viewport()->find_world_2d()->get_canvas();

		VisualServer::get_singleton()->canvas_item_set_parent(canvas_item, canvas);

		group = "root_canvas" + itos(canvas.get_id());

		add_to_group(group);
		if (canvas_layer)
			canvas_layer->reset_sort_index();
		else
			get_viewport()->gui_reset_canvas_sort_index();

		get_tree()->call_group_flags(SceneTree::GROUP_CALL_UNIQUE, group, "_toplevel_raise_self");

	} else {

		CanvasItem *parent = get_parent_item();
		canvas_layer = parent->canvas_layer;
		VisualServer::get_singleton()->canvas_item_set_parent(canvas_item, parent->get_canvas_item());
		VisualServer::get_singleton()->canvas_item_set_draw_index(canvas_item, get_index());
	}

	pending_update = false;
	update();

	notification(NOTIFICATION_ENTER_CANVAS);
}
コード例 #13
0
ファイル: canvas_item.cpp プロジェクト: AMG194/godot
void CanvasItem::_enter_canvas() {

	if ((!get_parent() || !get_parent()->cast_to<CanvasItem>()) || toplevel) {

		Node *n = this;
		Viewport *viewport=NULL;
		canvas_layer=NULL;

		while(n) {

			if (n->cast_to<Viewport>()) {

				viewport = n->cast_to<Viewport>();
				break;
			}
			if (!canvas_layer && n->cast_to<CanvasLayer>()) {

				canvas_layer = n->cast_to<CanvasLayer>();
			}
			n=n->get_parent();
		}

		RID canvas;
		if (canvas_layer)
			canvas=canvas_layer->get_world_2d()->get_canvas();
		else
			canvas=viewport->find_world_2d()->get_canvas();

		VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,canvas);

		group = "root_canvas"+itos(canvas.get_id());

		add_to_group(group);
		get_tree()->call_group(SceneTree::GROUP_CALL_UNIQUE,group,"_raise_self");

	} else {

		CanvasItem *parent = get_parent_item();
		VisualServer::get_singleton()->canvas_item_set_parent(canvas_item,parent->get_canvas_item());
		parent->_queue_sort_children();
	}

	pending_update=false;
	update();

	notification(NOTIFICATION_ENTER_CANVAS);

}
コード例 #14
0
QColor Core::pickColor(const QPointF& point, const QVariantList& canvasItems) {
    QPixmap pixmap;
    for (int i = canvasItems.count() - 1; i >= 0; i--) {
        QObject* obj = qvariant_cast<QObject*>(canvasItems.at(i));
        CanvasItem* canvasItem = qobject_cast<CanvasItem*>(obj);
        QPixmap* canvasPixmap = canvasItem->pixmap();
        if (pixmap.isNull()) {
            pixmap = QPixmap(canvasPixmap->width(), canvasPixmap->height());
            pixmap.fill(Qt::white);
        }
        QPainter painter(&pixmap);
        painter.drawPixmap(0, 0, *canvasPixmap);
    }

    return QColor(pixmap.toImage().pixel(qRound(point.x()), qRound(point.y())));
}
コード例 #15
0
void Core::writePng(const QString& pngPath, const QVariantList& canvasItems) {
    QPixmap pixmap;
    for (int i = canvasItems.count() - 1; i >= 0; i--)
    {
        QObject* obj = qvariant_cast<QObject*>(canvasItems.at(i));
        CanvasItem* canvasItem = qobject_cast<CanvasItem*>(obj);
        QPixmap* canvasPixmap = canvasItem->pixmap();
        if (pixmap.isNull()) {
            pixmap = QPixmap(canvasPixmap->width(), canvasPixmap->height());
            pixmap.fill(Qt::white);
        }
        QPainter painter(&pixmap);
        painter.drawPixmap(0, 0, *canvasPixmap);
    }
    pixmap.save(pngPath);
}
コード例 #16
0
void Floater::moveBy(double dx, double dy)
{
	if (!isEnabled())
		return;

	QCanvasItemList l = collisions(false);
	for (QCanvasItemList::Iterator it = l.begin(); it != l.end(); ++it)
	{
		CanvasItem *item = dynamic_cast<CanvasItem *>(*it);

		if (!noUpdateZ && item && item->canBeMovedByOthers())
			item->updateZ(this);

		if ((*it)->z() >= z())
		{
			if (item && item->canBeMovedByOthers() && collidesWith(*it))
			{
				if ((*it)->rtti() == Rtti_Ball)
				{
					//((Ball *)(*it))->setState(Rolling);
					(*it)->moveBy(dx, dy);
					if (game && game->hasFocus() && !game->isEditing() && game->curBall() == (Ball *)(*it))
							game->ballMoved();
				}
				else if ((*it)->rtti() != Rtti_Putter)
					(*it)->moveBy(dx, dy);
			}
		}
	}

	point->dontMove();
	point->move(x() + width(), y() + height());

	// this call must come after we have tested for collisions, otherwise we skip them when saving!
	// that's a bad thing
	QCanvasRectangle::moveBy(dx, dy);

	// because we don't do Bridge::moveBy();
	topWall->move(x(), y());
	botWall->move(x(), y() - 1);
	leftWall->move(x(), y());
	rightWall->move(x(), y());

	if (game && game->isEditing())
		game->updateHighlighter();
}
コード例 #17
0
ファイル: project_manager.cpp プロジェクト: SPTelur/godot
void ProjectManager::_update_project_buttons()
{
	for(int i=0;i<scroll_childs->get_child_count();i++) {

		CanvasItem *item = scroll_childs->get_child(i)->cast_to<CanvasItem>();
		item->update();
	}

	bool has_runnable_scene = false;
	for (Map<String,String>::Element *E=selected_list.front(); E; E=E->next()) {
		const String &selected_main = E->get();
		if (selected_main == "") continue;
		has_runnable_scene = true;
		break;
	}

	erase_btn->set_disabled(selected_list.size()<1);
	open_btn->set_disabled(selected_list.size()<1);
	run_btn->set_disabled(!has_runnable_scene);
}
コード例 #18
0
ファイル: canvas_item.cpp プロジェクト: brakhane/godot
void CanvasItem::_propagate_visibility_changed(bool p_visible) {

	notification(NOTIFICATION_VISIBILITY_CHANGED);

	if (p_visible)
		update(); //todo optimize
	else
		emit_signal(SceneStringNames::get_singleton()->hide);
	_block();

	for (int i = 0; i < get_child_count(); i++) {

		CanvasItem *c = Object::cast_to<CanvasItem>(get_child(i));

		if (c && c->visible) //should the toplevels stop propagation? i think so but..
			c->_propagate_visibility_changed(p_visible);
	}

	_unblock();
}
コード例 #19
0
void SceneTreeEditor::_cell_button_pressed(Object *p_item,int p_column,int p_id) {

	TreeItem *item=p_item->cast_to<TreeItem>();
	ERR_FAIL_COND(!item);

	NodePath np = item->get_metadata(0);

	Node *n=get_node(np);
	ERR_FAIL_COND(!n);

	if (p_id==BUTTON_SUBSCENE) {
		//open scene request
		Rect2 item_rect = tree->get_item_rect(item,0);
		item_rect.pos.y-=tree->get_scroll().y;
		item_rect.pos+=tree->get_global_pos();

		if (n==get_scene_node()) {
			inheritance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
			inheritance_menu->set_size(Vector2(item_rect.size.x,0));
			inheritance_menu->popup();
			instance_node=n->get_instance_ID();

		} else {
			instance_menu->set_pos(item_rect.pos+Vector2(0,item_rect.size.y));
			instance_menu->set_size(Vector2(item_rect.size.x,0));
			if (EditorNode::get_singleton()->get_edited_scene()->is_editable_instance(n))
				instance_menu->set_item_checked(0,true);
			else
				instance_menu->set_item_checked(0,false);

			if (n->get_owner()==get_scene_node()) {
				instance_menu->set_item_checked(1,n->get_scene_instance_load_placeholder());
				instance_menu->set_item_disabled(1,false);
			} else {

				instance_menu->set_item_checked(1,false);
				instance_menu->set_item_disabled(1,true);
			}

			instance_menu->popup();
			instance_node=n->get_instance_ID();
		}
		//emit_signal("open",n->get_filename());
	} else if (p_id==BUTTON_SCRIPT) {
		RefPtr script=n->get_script();
		if (!script.is_null())
			emit_signal("open_script",script);

	} else if (p_id==BUTTON_VISIBILITY) {


		if (n->is_type("Spatial")) {

			Spatial *ci = n->cast_to<Spatial>();
			if (!ci->is_visible() && ci->get_parent_spatial() && !ci->get_parent_spatial()->is_visible()) {
				error->set_text(TTR("This item cannot be made visible because the parent is hidden. Unhide the parent first."));
				error->popup_centered_minsize();
				return;
			}

			bool v = !bool(n->call("is_hidden"));
			undo_redo->create_action(TTR("Toggle Spatial Visible"));
			undo_redo->add_do_method(n,"_set_visible_",!v);
			undo_redo->add_undo_method(n,"_set_visible_",v);
			undo_redo->commit_action();
		} else if (n->is_type("CanvasItem")) {

			CanvasItem *ci = n->cast_to<CanvasItem>();
			if (!ci->is_visible() && ci->get_parent_item() && !ci->get_parent_item()->is_visible()) {
				error->set_text(TTR("This item cannot be made visible because the parent is hidden. Unhide the parent first."));
				error->popup_centered_minsize();
				return;
			}
			bool v = !bool(n->call("is_hidden"));
			undo_redo->create_action(TTR("Toggle CanvasItem Visible"));
			undo_redo->add_do_method(n,v?"hide":"show");
			undo_redo->add_undo_method(n,v?"show":"hide");
			undo_redo->commit_action();
		}

	} else if (p_id==BUTTON_LOCK) {

		if (n->is_type("CanvasItem")) {
			n->set_meta("_edit_lock_", Variant());
			_update_tree();
			emit_signal("node_changed");
		}

	} else if (p_id==BUTTON_GROUP) {
		if (n->is_type("CanvasItem")) {
			n->set_meta("_edit_group_", Variant());
			_update_tree();
			emit_signal("node_changed");
		}
	} else if (p_id==BUTTON_WARNING) {

		String config_err = n->get_configuration_warning();
		if (config_err==String())
			return;
		config_err=config_err.word_wrap(80);
		warning->set_text(config_err);
		warning->popup_centered_minsize();

	} else if (p_id==BUTTON_SIGNALS) {

		editor_selection->clear();
		editor_selection->add_node(n);

		set_selected(n);

		NodeDock::singleton->get_parent()->call("set_current_tab",NodeDock::singleton->get_index());
		NodeDock::singleton->show_connections();

	} else if (p_id==BUTTON_GROUPS) {

		editor_selection->clear();
		editor_selection->add_node(n);

		set_selected(n);

		NodeDock::singleton->get_parent()->call("set_current_tab",NodeDock::singleton->get_index());
		NodeDock::singleton->show_groups();
	}
}
コード例 #20
0
ファイル: project_manager.cpp プロジェクト: 9cat/godot
void ProjectManager::_panel_input(const InputEvent& p_ev,Node *p_hb) {

	if (p_ev.type==InputEvent::MOUSE_BUTTON && p_ev.mouse_button.pressed && p_ev.mouse_button.button_index==BUTTON_LEFT) {

		String clicked = p_hb->get_meta("name");
		String clicked_main_scene = p_hb->get_meta("main_scene");

		if (p_ev.key.mod.shift && selected_list.size()>0 && last_clicked!="" && clicked != last_clicked) {

			int clicked_id = -1;
			int last_clicked_id = -1;
			for(int i=0;i<scroll_childs->get_child_count();i++) {
				HBoxContainer *hb = scroll_childs->get_child(i)->cast_to<HBoxContainer>();
				if (!hb) continue;
				if (hb->get_meta("name") == clicked) clicked_id = i;
				if (hb->get_meta("name") == last_clicked) last_clicked_id = i;
			}

			if (last_clicked_id!=-1 && clicked_id!=-1) {
				int min = clicked_id < last_clicked_id? clicked_id : last_clicked_id;
				int max = clicked_id > last_clicked_id? clicked_id : last_clicked_id;
				for(int i=0; i<scroll_childs->get_child_count(); ++i) {
					HBoxContainer *hb = scroll_childs->get_child(i)->cast_to<HBoxContainer>();
					if (!hb) continue;
					if (i!=clicked_id && (i<min || i>max) && !p_ev.key.mod.control) {
						selected_list.erase(hb->get_meta("name"));
					} else if (i>=min && i<=max) {
						selected_list.insert(hb->get_meta("name"), hb->get_meta("main_scene"));
					}
				}
			}

		} else if (selected_list.has(clicked) && p_ev.key.mod.control) {

			selected_list.erase(clicked);

		} else {

			last_clicked = clicked;
			if (p_ev.key.mod.control || selected_list.size()==0) {
				selected_list.insert(clicked, clicked_main_scene);
			} else {
				selected_list.clear();
				selected_list.insert(clicked, clicked_main_scene);
			}
		}

		String single_selected = "";
		if (selected_list.size() == 1) {
			single_selected = selected_list.front()->key();
		}

		single_selected_main = "";
		for(int i=0;i<scroll_childs->get_child_count();i++) {
			CanvasItem *item = scroll_childs->get_child(i)->cast_to<CanvasItem>();
			item->update();

			if (single_selected!="" && single_selected == item->get_meta("name"))
				single_selected_main = item->get_meta("main_scene");
		}

		erase_btn->set_disabled(selected_list.size()<1);
		open_btn->set_disabled(selected_list.size()<1);
		run_btn->set_disabled(selected_list.size()<1 || (selected_list.size()==1 && single_selected_main==""));

		if (p_ev.mouse_button.doubleclick)
			_open_project(); //open if doubleclicked

	}
}
コード例 #21
0
ファイル: handle.cpp プロジェクト: SiteView/NNMQT
void Handle::reposition(void)
{
    double sw = 0, sh = 0;

    double nxpos, nypos;

    CanvasItem *parent = dynamic_cast<CanvasItem *> (parentItem());
    if (parent == NULL)
    {
        return;
    }

    int hflags = handleFlags();
    if (hflags & HAN_POINT)
    {
#if 0
        int index = get_identn(3);
        Polygon *poly = dynamic_cast<Polygon *> (parentItem());
        assert(poly != NULL);
        poly->getPointPos(index, &nxpos, &nypos);
#endif
    }
    else if (hflags & HAN_SEPARA)
    {
        Separation *separation = dynamic_cast<Separation *> (parentItem());

        nxpos = separation->handle_x;
        nypos = separation->handle_y;
    }
    else
    {
        sw = parent->width();
        sh = parent->height();

        if (xrel == HPLACE_MIN)
        {
            nxpos = - (sw / 2) + xoff;
        }
        else if (xrel == HPLACE_ZERO)
        {
            nxpos = 0 + xoff;
        }
        else // if (xrel == HPLACE_MAX)
        {
            nxpos = + (sw / 2) + xoff;
        }

        if (yrel == HPLACE_MIN)
        {
            nypos = - (sh / 2) + yoff;
        }
        else if (yrel == HPLACE_ZERO)
        {
            nypos = 0 + yoff;
        }
        else // if (yrel == HPLACE_MAX)
        {
            nypos = + (sh / 2) + yoff;
        }
    }

    if ((nxpos != x()) || (nypos != y()))
    {
        // If the handle has been moved.
        QGraphicsItem::setPos(nxpos, nypos);
    }
}
コード例 #22
0
void Core::writeOra(const QString& oraPath, const QSize& canvasSize, const QVariantList layerList) {
    QZipWriter zipWriter(oraPath);
    zipWriter.setCompressionPolicy(QZipWriter::AutoCompress);

    QByteArray xmlByteArray;

    // mimetype file
    xmlByteArray.append("image/openraster");
    zipWriter.addFile("mimetype", xmlByteArray);

    // stack.xml file
    QXmlStreamWriter stream(&xmlByteArray);
    stream.setAutoFormatting(true);

    stream.writeStartDocument();

    stream.writeStartElement("image");
    stream.writeAttribute("w", QString::number(canvasSize.width()));
    stream.writeAttribute("h",QString::number(canvasSize.height()));
    stream.writeStartElement("stack");

    QByteArray ba;
    QBuffer buffer(&ba);

    for (int i = 0; i < layerList.count(); i++) {
        QMap<QString, QVariant> map = layerList.at(i).toMap();
        QString name = map.value("name").toString();
        QString isVisible = map.value("isVisible").toString();
        QString isLock = map.value("isLock").toString();
        QString isSelected = map.value("isSelected").toString();

        buffer.open(QIODevice::WriteOnly);
        QObject* obj = qvariant_cast<QObject*>(map.value("canvasItem"));
        CanvasItem* canvasItem = qobject_cast<CanvasItem*>(obj);
        QPixmap* pixmap = canvasItem->pixmap();
        pixmap->save(&buffer, "PNG");
        buffer.close();

        QString src = "data/" + name + ".png";
        zipWriter.addFile(src, ba);

        // layer
        stream.writeStartElement("layer");
        stream.writeAttribute("name", name);
        stream.writeAttribute("composite-op", "svg:src-over");
        stream.writeAttribute("visibility", isVisible == "true" ? "visible" : "hidden");
        stream.writeAttribute("edit-locked", isLock);
        stream.writeAttribute("selected", isSelected);
        stream.writeAttribute("src", src);
        stream.writeAttribute("x", "0");
        stream.writeAttribute("y", "0");
        stream.writeAttribute("opacity", "1.0");
        stream.writeEndElement(); // layer
    }

    stream.writeEndElement(); // stack
    stream.writeEndElement(); // image
    stream.writeEndDocument(); // document
    zipWriter.addFile("stack.xml", xmlByteArray);

    zipWriter.close();
}