added all files
[ffqwlibrary] / libffqw-n810-1.0 / sources / ffscrollarea.cpp
diff --git a/libffqw-n810-1.0/sources/ffscrollarea.cpp b/libffqw-n810-1.0/sources/ffscrollarea.cpp
new file mode 100644 (file)
index 0000000..9bcfdd4
--- /dev/null
@@ -0,0 +1,422 @@
+/*\r
+         GNU GENERAL PUBLIC LICENSE\r
+                       Version 3, 29 June 2007\r
+\r
+ Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>\r
+ Everyone is permitted to copy and distribute verbatim copies\r
+ of this license document, but changing it is not allowed.\r
+\r
+                            Preamble\r
+\r
+  The GNU General Public License is a free, copyleft license for\r
+software and other kinds of works.\r
+\r
+  The licenses for most software and other practical works are designed\r
+to take away your freedom to share and change the works.  By contrast,\r
+the GNU General Public License is intended to guarantee your freedom to\r
+share and change all versions of a program--to make sure it remains free\r
+software for all its users.  We, the Free Software Foundation, use the\r
+GNU General Public License for most of our software; it applies also to\r
+any other work released this way by its authors.  You can apply it to\r
+your programs, too.\r
+\r
+  When we speak of free software, we are referring to freedom, not\r
+price.  Our General Public Licenses are designed to make sure that you\r
+have the freedom to distribute copies of free software (and charge for\r
+them if you wish), that you receive source code or can get it if you\r
+want it, that you can change the software or use pieces of it in new\r
+free programs, and that you know you can do these things.\r
+\r
+  To protect your rights, we need to prevent others from denying you\r
+these rights or asking you to surrender the rights.  Therefore, you have\r
+certain responsibilities if you distribute copies of the software, or if\r
+you modify it: responsibilities to respect the freedom of others.\r
+\r
+  For example, if you distribute copies of such a program, whether\r
+gratis or for a fee, you must pass on to the recipients the same\r
+freedoms that you received.  You must make sure that they, too, receive\r
+or can get the source code.  And you must show them these terms so they\r
+know their rights.\r
+\r
+  Developers that use the GNU GPL protect your rights with two steps:\r
+(1) assert copyright on the software, and (2) offer you this License\r
+giving you legal permission to copy, distribute and/or modify it.\r
+\r
+  For the developers' and authors' protection, the GPL clearly explains\r
+that there is no warranty for this free software.  For both users' and\r
+authors' sake, the GPL requires that modified versions be marked as\r
+changed, so that their problems will not be attributed erroneously to\r
+authors of previous versions.\r
+\r
+  Some devices are designed to deny users access to install or run\r
+modified versions of the software inside them, although the manufacturer\r
+can do so.  This is fundamentally incompatible with the aim of\r
+protecting users' freedom to change the software.  The systematic\r
+pattern of such abuse occurs in the area of products for individuals to\r
+use, which is precisely where it is most unacceptable.  Therefore, we\r
+have designed this version of the GPL to prohibit the practice for those\r
+products.  If such problems arise substantially in other domains, we\r
+stand ready to extend this provision to those domains in future versions\r
+of the GPL, as needed to protect the freedom of users.\r
+\r
+  Finally, every program is threatened constantly by software patents.\r
+States should not allow patents to restrict development and use of\r
+software on general-purpose computers, but in those that do, we wish to\r
+avoid the special danger that patents applied to a free program could\r
+make it effectively proprietary.  To prevent this, the GPL assures that\r
+patents cannot be used to render the program non-free.\r
+\r
+  The precise terms and conditions for copying, distribution and\r
+modification follow.\r
+\r
+http://www.gnu.org/licenses/gpl-3.0.txt\r
+*/\r
+/**\r
+ * @file ffscrollarea.cpp\r
+ * @brief Implementation of the FFScrollArea class\r
+ *\r
+ * @author ComArch S.A.\r
+ * @date 2009.09.20\r
+ * @version 1.0\r
+ */\r
+\r
+#include "ffscrollarea.h"\r
+#include <QDebug>\r
+#include <QPen>\r
+#include <QScrollBar>\r
+#include <QPainter>\r
+\r
+//defines view of scrollbars\r
+#define SCROLLBAR_STYLE " \\r
+       QScrollBar:vertical, QScrollBar:horizontal { \\r
+               border: 0px solid transparent; \\r
+               background: transparent; \\r
+               width: 5px; \\r
+               height: 5px; /* change this to 5px or more to see horizontal scrollbar */\\r
+               margin: 2px 2px 2px 2px; \\r
+       } \\r
+       QScrollBar::sub-page, QScrollBar::add-page { \\r
+               background: rgb(45,45,45); \\r
+       } \\r
+       QScrollBar::handle:vertical { \\r
+               background: qlineargradient(x1:0, y1:0, x2:0, y2:1, \\r
+                                           stop:0 rgba(30,30,30,0), stop: 0.1 #1d1, stop:0.9 #2e2, stop: 1 rgba(30,30,30,0)); \\r
+               min-height: 25px; \\r
+       } \\r
+       QScrollBar::handle:horizontal { \\r
+               background: qlineargradient(x1:0, y1:0, x2:1, y2:0, \\r
+                                           stop:0 rgba(30,30,30,0), stop: 0.1 #1d1, stop:0.9 #2e2, stop: 1 rgba(30,30,30,0)); \\r
+               min-width: 25px; \\r
+       } \\r
+       QScrollBar::add-line, QScrollBar::sub-line { \\r
+               border: 0px solid transparent; \\r
+       } \\r
+       QScrollArea { \\r
+               background-color: #222; color: #ddd; \\r
+       } \\r
+"\r
+\r
+/**\r
+ * Constructs FFScrollArea with parent\r
+ */\r
+FFScrollArea::FFScrollArea(QWidget* parent) :\r
+       QScrollArea(parent)\r
+{\r
+       init();\r
+}\r
+/**\r
+ * A virtual destructor\r
+ */\r
+FFScrollArea::~FFScrollArea()\r
+{\r
+\r
+}\r
+/**\r
+ * Initiates FFScrollArea class. Sets all needed fields, connections and calls.\r
+ * It is called by the constructor.\r
+ */\r
+void FFScrollArea::init()\r
+{\r
+       //sets FFScrollArea view properties\r
+       setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);\r
+       setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);\r
+       this->setFrameStyle(0);\r
+       setStyleSheet(SCROLLBAR_STYLE);\r
+       setStyleSheet("background-color: transparent");\r
+       //initiates all fields with default values\r
+       moved = false;\r
+       animate = false;\r
+\r
+       oldPos = QPointF(0, 0);\r
+       prevPos = QPointF(0, 0);\r
+       pos = QPointF(0, 0);\r
+       speed = QPointF(0, 0);\r
+       movement = QPointF(0, 0);\r
+\r
+       x = 0;\r
+       y = 0;\r
+\r
+       slowingDownRate_ = DEFAULT_SLOWING_DOWN_RATE;\r
+       postionSumplingTime_ = DEFAULT_POSIOTION_SUMPLING_TIME;\r
+       kineticAnimationTime_ = DEFAULT_KINETIC_ANIMATION_TIME;\r
+       minMotionLength_ = DEFAULT_MIN_MOTION_LENGTH;\r
+\r
+       timerPos.stop();\r
+       timerAnim.stop();\r
+\r
+       //connects signals and slots\r
+       connect(&timerPos, SIGNAL(timeout()), this, SLOT(updatePos()));\r
+       connect(&timerAnim, SIGNAL(timeout()), this, SLOT(animation()));\r
+}\r
+\r
+/**\r
+ * Method using to serve events. Overrides the virtual method from parent.\r
+ *\r
+ * @param object is a pointer handled object\r
+ * @param ev is a pointer to handled event\r
+ */\r
+\r
+bool FFScrollArea::eventFilter(QObject* object, QEvent* ev)\r
+{\r
+       //Does nothing when QEvent type is Paint\r
+       if(ev->type() == QEvent::Paint)\r
+               return false;\r
+\r
+       if(QMouseEvent* event = dynamic_cast<QMouseEvent*>(ev))\r
+       {\r
+               //Serves MouseButtonPressEvent\r
+               if(event->type() == QEvent::MouseButtonPress)\r
+               {\r
+\r
+                       moved = false;\r
+                       movement = QPointF(0, 0);\r
+                       timerAnim.stop();\r
+                       if(event)\r
+                       {\r
+                               //sets started values after each press event\r
+                               x = event->globalX();\r
+                               y = event->globalY();\r
+                               prevPos = event->globalPos();\r
+                               oldPos = event->globalPos();\r
+                               speed = QPointF(0.0, 0.0);\r
+                               pos = QPointF(0.0, 0.0);\r
+\r
+                               //starts position sampling timer\r
+                               timerPos.start(postionSumplingTime_);\r
+                       }\r
+                       else\r
+                       {\r
+                               return 0;\r
+                       }\r
+\r
+               }\r
+               //Serves MouseMoveEvent\r
+               if(event->type() == QEvent::MouseMove)\r
+               {\r
+\r
+                       //sets and calculates motion parameters\r
+                       int offsetY = event->globalY() - y;\r
+                       int offsetX = event->globalX() - x;\r
+\r
+                       int valY = this->verticalScrollBar()->value() - offsetY;\r
+                       int valX = this->horizontalScrollBar()->value()\r
+                                       - offsetX;\r
+\r
+                       y = event->globalY();\r
+                       x = event->globalX();\r
+\r
+                       //If motion length is shorter then minMotionLength_\r
+                       //scrollbars postion will be not set.\r
+                       if(minMotionLength_ < qAbs(movement.y())\r
+                                       || minMotionLength_\r
+                                                       < qAbs(movement.x()))\r
+                       {\r
+                               //sets new scrollBars' values\r
+                               this->verticalScrollBar()->setValue(valY);\r
+                               this->horizontalScrollBar()->setValue(valX);\r
+                               moved = true;\r
+\r
+                       }\r
+\r
+                       //Updates parameters\r
+                       movement.setY(movement.y() + qAbs(prevPos.y()\r
+                                       - event->globalY()));\r
+                       movement.setX(movement.x() + qAbs(prevPos.x()\r
+                                       - event->globalX()));\r
+\r
+                       prevPos = event->globalPos();\r
+               }\r
+               //Serves MouseButtonReleaseEvent\r
+               if(event->type() == QEvent::MouseButtonRelease)\r
+               {\r
+                       //Stops position's sampling\r
+                       timerPos.stop();\r
+\r
+                       if(moved)\r
+                       {\r
+                               //blocks signals\r
+                               object->blockSignals(true);\r
+                               object->event(event);\r
+                               object->blockSignals(false);\r
+\r
+                               //sets cursor position after\r
+                               //MouseButtonReleaseEvent\r
+                               pos.setY((float)(this->verticalScrollBar()->value()));\r
+                               pos.setX((float)(this->horizontalScrollBar()->value()));\r
+\r
+                               //starts animation\r
+                               timerAnim.start(kineticAnimationTime_);\r
+                               return true;\r
+                       }\r
+                       else\r
+                       {\r
+                               //do nothing\r
+                               return false;\r
+                       }\r
+               }\r
+       }\r
+       //calls parent's event filter\r
+       return QScrollArea::eventFilter(object, ev);\r
+}\r
+\r
+/**\r
+ * Sets widget on FFScrollArea\r
+ * Overrides the virtual method from parent.\r
+ *\r
+ * @param widget pointer to setting widget\r
+ */\r
+\r
+void FFScrollArea::setWidget(QWidget* widget)\r
+{\r
+       //calls parent method\r
+       ((QScrollArea*)this)->setWidget(widget);\r
+       //calls method to install EventFilter\r
+       installFilterRecursive(widget);\r
+}\r
+/**\r
+ * Installs eventFilter to each widget on FFScrollArea\r
+ *\r
+ * @param wdg pointer to widget to which eventFilter is installing.\r
+ */\r
+void FFScrollArea::installFilterRecursive(QWidget* wdg)\r
+{\r
+       if(!wdg)\r
+               return;\r
+       //Installs eventFilter to current widget\r
+       wdg->installEventFilter(this);\r
+\r
+       //Calls installFilterRecursive to all children\r
+       const QList<QObject*> widgets = wdg->children();\r
+       for(int i = 0; i < widgets.length(); ++i)\r
+       {\r
+               QWidget* wdg = dynamic_cast<QWidget*> (widgets.at(i));\r
+               if(wdg)\r
+                       installFilterRecursive(wdg);\r
+       }\r
+}\r
+/**\r
+ * Updates motion's speed and cursor's position\r
+ */\r
+void FFScrollArea::updatePos()\r
+{\r
+       //sets motion's speed\r
+       speed.setY(oldPos.y() - this->cursor().pos().y());\r
+       speed.setX(oldPos.x() - this->cursor().pos().x());\r
+       //sets current cursor's position\r
+       oldPos = this->cursor().pos();\r
+\r
+}\r
+\r
+/**\r
+ * Method responsible for kinetic's animation.\r
+ */\r
+\r
+void FFScrollArea::animation()\r
+{\r
+       //If speed is less then 1 animations is stopped\r
+       if(1 < qAbs(speed.x()) || 1 < qAbs(speed.y()))\r
+       {\r
+               //updates position\r
+               pos.setY(pos.y() + speed.y());\r
+               pos.setX(pos.x() + speed.x());\r
+\r
+               //sets new position on scrollbars\r
+               this->verticalScrollBar()->setValue((int)pos.y());\r
+               this->horizontalScrollBar()->setValue((int)pos.x());\r
+\r
+               //updates speed\r
+               speed.setY(speed.y() * slowingDownRate_);\r
+               speed.setX(speed.x() * slowingDownRate_);\r
+       }\r
+       else\r
+       {\r
+               //Stops animation\r
+               timerAnim.stop();\r
+       }\r
+}\r
+\r
+/**\r
+ * Returns rate responsible for kinetic speed slowing\r
+ */\r
+float FFScrollArea::getSlowingDownRate() const\r
+{\r
+       return slowingDownRate_;\r
+}\r
+/**\r
+ * Sets rate responsible for kinetic speed slowing\r
+ */\r
+void FFScrollArea::setSlowingDownRate(float slowingDownRate_)\r
+{\r
+       this->slowingDownRate_ = slowingDownRate_;\r
+}\r
+\r
+/**\r
+ *  Returns kinetic animation frame time in ms.\r
+ */\r
+int FFScrollArea::getKineticAnimationTime() const\r
+{\r
+       return kineticAnimationTime_;\r
+}\r
+\r
+/**\r
+ * Sets kinetic animation frame time in ms.\r
+ */\r
+void FFScrollArea::setKineticAnimationTime(int kineticAnimationTime_)\r
+{\r
+       this->kineticAnimationTime_ = kineticAnimationTime_;\r
+}\r
+\r
+/**\r
+ * Returns cursor position sampling time in ms.\r
+ */\r
+int FFScrollArea::getPostionSumplingTime() const\r
+{\r
+       return postionSumplingTime_;\r
+}\r
+\r
+/**\r
+ * Sets cursor position sampling time in ms.\r
+ */\r
+void FFScrollArea::setPostionSumplingTime(int postionSumplingTime_)\r
+{\r
+       this->postionSumplingTime_ = postionSumplingTime_;\r
+}\r
+\r
+/**\r
+ * Sets value needed to blocking signals\r
+ *\r
+ */\r
+void FFScrollArea::setMinMotionLength(int minMotionLength_)\r
+{\r
+       this->minMotionLength_ = minMotionLength_;\r
+}\r
+\r
+/**\r
+ * Returns value needed to blocking signals\r
+ */\r
+int FFScrollArea::getMinMotionLength() const\r
+{\r
+       return minMotionLength_;\r
+}\r
+\r
+\r