Skip to content

Instantly share code, notes, and snippets.

@aoloe aoloe/CMakeLists.txt
Last active Mar 21, 2018

Embed
What would you like to do?
cycle and reverse for scribus

Cycle and reverse

Proof of concept for improving the swap function in the Align & Distribute tool in Scribus

  • Much shorter code
  • Probably more correct
  • CycleLeft does not exactly the same as the current SwapLeft, but should be close enough and much simpler.
  • Reverse is a "real" swap.

Warning: the initial list is on purpose out of order (in Scribus AObjects is on the order of selection!).
The items are inserted as c a b, and when ordered they are indeed a b c.
The order (of selection) is kept in AObjects and you have to keep an eye on the coordinates to figure out the current order.

Links:

Trying QMultiMap

QMaps are "automatically" sorted.

I tried to use a QPoint as the key and a reference to the list's item as the value, but I could not find a way to set the value of the item in a way, that the one in the list also gets changed.

Finally, I've switched to the QList based solution in the main.cpp file.

#include <QMultiMap>
#include <QPoint>

bool operator <(QPoint a, QPoint b)
{
    return a.x() < b.x() || (a.x() == b.x() && a.y() < b.y());
}

int main()
{
    // [...]
    QMultiMap<QPoint, AObject*> def{};
    for (auto &a: aObjects) {
        def.insert({a.x, a.y}, &a);
    }
    QMutableMapIterator<QPoint, AObject*> it(def);
    it.toFront();
    it.next();
	auto swapX = it.value()->x;
    auto prevIt = it;
    it.next();
	while (it.hasNext()) {
        auto& temp = prevIt.value();
        temp->y = 20; // it does not change the items in the original list
        auto prevIt = it;
        it.next();
	}
    // [...]
}
int main()
{
    // [...]
	auto it = def.begin();
	auto swapX = it.value()->x;
	auto swapY = it.value()->y;
    auto prevIt = it;
	++it;
	while (it != def.end()) {
        prevIt.value()->y = 20; // it does not change the items in the original list

        qDebug() << prevIt.key();
        qDebug() << prevIt.value()->x;
        auto prevIt = it;
        ++it;
	}
    // [...]
}

Presentation

  • the current state
  • the new implementation
    • issues with map
      • we need qmultimap
      • how to write to the reference in the qmultimap?
    • simpler with qlist
  • algorithms?
    • iter_swap
      • std::iter_swap(it1, it2) is equivalent to std::swap(*it1, *it2)
    • reverse
CMAKE_MINIMUM_REQUIRED(VERSION 3.4)
PROJECT(cycle-and-reverse)
SET(CMAKE_CXX_STANDARD 14)
set(CMAKE_INCLUDE_CURRENT_DIR ON)
set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTORCC ON)
find_package(Qt5Core)
ADD_EXECUTABLE(cycle-and-reverse
main.cpp
)
target_link_libraries(cycle-and-reverse
Qt5::Core
)
#include <QDebug>
#include <QList>
class AObject
{
public:
char t{' '};
int x{0};
int y{0};
};
class ScribusDoc
{
public:
void reverse()
{
QList<AObject*> items{};
for (auto &a: AObjects) {
items.append(&a);
}
qSort(items.begin(), items.end(), compareAObject);
auto itBegin = items.begin();
auto itEnd = --items.end();
while (itBegin < itEnd) {
auto swapX = (*itBegin)->x;
auto swapY = (*itBegin)->y;
(*itBegin)->x = (*itEnd)->x;
(*itBegin)->y = (*itEnd)->y;
(*itEnd)->x = swapX;
(*itEnd)->y = swapY;
++itBegin;
--itEnd;
}
}
void cycleRight()
{
QList<AObject*> items{};
for (auto &a: AObjects) {
items.append(&a);
}
qSort(items.begin(), items.end(), compareAObject);
auto it = items.begin();
auto swapX = (*it)->x;
auto swapY = (*it)->y;
auto prevIt = it;
++it;
while (it != items.end()) {
(*prevIt)->x = (*it)->x;
(*prevIt)->y = (*it)->y;
prevIt = it;
++it;
}
it = --items.end();
(*it)->x = swapX;
(*it)->y = swapY;
}
void render()
{
qDebug() << "-----";
for (auto a: AObjects) {
qDebug() << a.t << a.x << a.y;
}
}
private:
QList<AObject> AObjects{{'c',3,4},{'a',2,1},{'b',2,2}};
static bool compareAObject(const AObject* a, const AObject* b)
{
return a->x < b->x || (a->x == b->x && a->y < b->y);
}
};
int main()
{
ScribusDoc doc;
doc.render();
qDebug() << "a b c > c a b > b c a > a b c";
doc.cycleRight();
doc.render();
doc.cycleRight();
doc.render();
doc.cycleRight();
doc.render();
qDebug() << "a b c > c a b > a b c";
doc.reverse();
doc.render();
doc.reverse();
doc.render();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.