DeepCover Embedded Security in IoT: Public-key Secured Data Paths

Dependencies:   MaximInterface

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Graphic.cpp Source File

Graphic.cpp

00001 /*******************************************************************************
00002 * Copyright (C) Maxim Integrated Products, Inc., All Rights Reserved.
00003 *
00004 * Permission is hereby granted, free of charge, to any person obtaining a
00005 * copy of this software and associated documentation files (the "Software"),
00006 * to deal in the Software without restriction, including without limitation
00007 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
00008 * and/or sell copies of the Software, and to permit persons to whom the
00009 * Software is furnished to do so, subject to the following conditions:
00010 *
00011 * The above copyright notice and this permission notice shall be included
00012 * in all copies or substantial portions of the Software.
00013 *
00014 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
00015 * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
00016 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
00017 * IN NO EVENT SHALL MAXIM INTEGRATED BE LIABLE FOR ANY CLAIM, DAMAGES
00018 * OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
00019 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
00020 * OTHER DEALINGS IN THE SOFTWARE.
00021 *
00022 * Except as contained in this notice, the name of Maxim Integrated
00023 * Products, Inc. shall not be used except as stated in the Maxim Integrated
00024 * Products, Inc. Branding Policy.
00025 *
00026 * The mere transfer of this software does not imply any licenses
00027 * of trade secrets, proprietary technology, copyrights, patents,
00028 * trademarks, maskwork rights, or any other form of intellectual
00029 * property whatsoever. Maxim Integrated Products, Inc. retains all
00030 * ownership rights.
00031 *******************************************************************************/
00032 
00033 #include <algorithm>
00034 #include <functional>
00035 #include "Bitmap.hpp"
00036 #include "Graphic.hpp"
00037 
00038 static const int minWidthHeight = 1;
00039 
00040 Graphic::Graphic()
00041     : parent_(NULL), children_(), focusedChild_(NULL), x_(0), y_(0),
00042       width_(minWidthHeight), height_(minWidthHeight), valid_(false) {}
00043 
00044 static void setParentNull(Graphic * node) { node->setParent (NULL); }
00045 
00046 Graphic::~Graphic() {
00047   // Set children's parent to NULL.
00048   std::for_each(children_.begin(), children_.end(), setParentNull);
00049   // Remove from parent.
00050   setParent (NULL);
00051 }
00052 
00053 void Graphic::setParent (Graphic * parent) {
00054   if ((parent_ == parent) || (parent == this)) {
00055     return;
00056   }
00057 
00058   if (parent_) {
00059     // Remove this from the old parent's list of children.
00060     parent_->children_.erase(std::remove(parent_->children_.begin(),
00061                                          parent_->children_.end(), this));
00062     // Ensure that the old parent's focused child is not this.
00063     if (parent_->focusedChild_ == this) {
00064       parent_->focusedChild_ = NULL;
00065     }
00066     // Signal children changed event on old parent.
00067     parent_->childrenChanged();
00068   }
00069   if (parent) {
00070     // Add this to new parent's list of children.
00071     parent->children_.push_back(this);
00072     // Signal children changed event on new parent.
00073     parent->childrenChanged();
00074   }
00075   parent_ = parent;
00076 }
00077 
00078 bool Graphic::focused() const {
00079   // First check if a focused child has not been set on this graphic.
00080   bool focused = !focusedChild_;
00081   // Then check if each parent has the correct focused child set.
00082   for (const Graphic * node = this; focused && node->parent_;
00083        node = node->parent_) {
00084     focused = (node->parent_->focusedChild_ == node);
00085   }
00086   return focused;
00087 }
00088 
00089 void Graphic::setFocused() {
00090   // Locate top-level parent.
00091   Graphic * node = this;
00092   while (node->parent_) {
00093     node = node->parent_;
00094   }
00095   // Locate currently focused item.
00096   while (node->focusedChild_) {
00097     node = node->focusedChild_;
00098   }
00099   // Do nothing if this is already focused.
00100   if (node == this) {
00101     return;
00102   }
00103 
00104   // Create new focus chain by setting the focused child of each parent.
00105   focusedChild_ = NULL;
00106   for (Graphic * node = this; node->parent_; node = node->parent_) {
00107     node->parent_->focusedChild_ = node;
00108   }
00109   // Raise focus changed events on both nodes.
00110   node->focusChanged(false);
00111   focusChanged(true);
00112 }
00113 
00114 void Graphic::move(int x, int y) {
00115   if (x_ != x || y_ != y) {
00116     x_ = x;
00117     y_ = y;
00118     invalidate();
00119     moved();
00120   }
00121 }
00122 
00123 void Graphic::resize(int width, int height) {
00124   if (width_ != width || height_ != height) {
00125     width_ = std::max(width, minWidthHeight);
00126     height_ = std::max(height, minWidthHeight);
00127     invalidate();
00128     resized();
00129   }
00130 }
00131 
00132 // Functor overlays rendered graphics onto a bitmap.
00133 class RenderOverlay {
00134 public:
00135   RenderOverlay(Bitmap & bitmap, int xOffset, int yOffset)
00136       : bitmap(bitmap), xOffset(xOffset), yOffset(yOffset) {}
00137 
00138   void operator()(const Graphic * graphic) {
00139     if (graphic) {
00140       graphic->render(bitmap, xOffset, yOffset);
00141     }
00142   }
00143 
00144 private:
00145   Bitmap & bitmap;
00146   const int xOffset;
00147   const int yOffset;
00148 };
00149 
00150 void Graphic::doRender(Bitmap & bitmap, int xOffset, int yOffset) const {
00151   std::for_each(children_.begin(), children_.end(),
00152                 RenderOverlay(bitmap, xOffset + x(), yOffset + y()));
00153 }
00154 
00155 void Graphic::render(Bitmap & bitmap, int xOffset, int yOffset) const {
00156   // Clear region.
00157   bitmap.clear(xOffset + x(), yOffset + y(), width(), height());
00158   // Do actual rendering.
00159   doRender(bitmap, xOffset, yOffset);
00160 }
00161 
00162 void Graphic::render(Bitmap & bitmap) const {
00163   int xOffset = 0;
00164   int yOffset = 0;
00165   for (const Graphic * graphic = parent(); graphic;
00166        graphic = graphic->parent()) {
00167     xOffset += graphic->x();
00168     yOffset += graphic->y();
00169   }
00170   render(bitmap, xOffset, yOffset);
00171 }
00172 
00173 void Graphic::updateAll() {
00174   // Perform updated event on this graphic.
00175   updated();
00176   // Call recursively on each child.
00177   std::for_each(children_.begin(), children_.end(),
00178                 std::mem_fun(&Graphic::updateAll));
00179 }
00180 
00181 bool Graphic::redrawInvalid(Bitmap & canvas) {
00182   bool redraw = !valid_;
00183   if (redraw) {
00184     // Redraw if invalid.
00185     render(canvas);
00186     // Set all children to valid since they were incorporated in the redraw.
00187     setAllValid();
00188   } else {
00189     // Call recursively on each child.
00190     for (ChildContainer::iterator it = children_.begin(); it != children_.end();
00191          ++it) {
00192       if ((*it)->redrawInvalid(canvas)) {
00193         redraw = true;
00194       }
00195     }
00196   }
00197   return redraw;
00198 }
00199 
00200 void Graphic::setAllValid() {
00201   valid_ = true;
00202   // Call recursively on each child.
00203   std::for_each(children_.begin(), children_.end(),
00204                 std::mem_fun(&Graphic::setAllValid));
00205 }
00206 
00207 bool Graphic::update(Bitmap * canvas) {
00208   bool redraw = false;
00209   updateAll();
00210   if (canvas) {
00211     redraw = redrawInvalid(*canvas);
00212   }
00213   return redraw;
00214 }
00215 
00216 bool Graphic::processKey(Key key) {
00217   // Find focused child.
00218   Graphic * receiver = this;
00219   while (receiver->focusedChild_) {
00220     receiver = receiver->focusedChild_;
00221   }
00222   // Pass event to focused child and then to each parent until handled.
00223   bool handled = false;
00224   do {
00225     handled = receiver->doProcessKey(key);
00226     receiver = receiver->parent_;
00227   } while (!handled && receiver);
00228   return handled;
00229 }
00230 
00231 void Graphic::childrenChanged() { invalidate(); }
00232 
00233 void Graphic::focusChanged(bool) {}
00234 
00235 void Graphic::moved() {}
00236 
00237 void Graphic::resized() {}
00238 
00239 void Graphic::updated() {}
00240 
00241 bool Graphic::doProcessKey(Key) { return false; }