<commit_before>#include "outlinefactory.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <QVBoxLayout>
#include <QDebug>
#include <QToolButton>
#include <QLabel>
#include <QStackedWidget>

namespace TextEditor {
namespace Internal {

OutlineWidgetStack::OutlineWidgetStack(OutlineFactory *factory) :
    QStackedWidget(),
    m_factory(factory),
    m_syncWithEditor(true)
{
    QLabel *label = new QLabel(tr("No outline available"), this);
    label->setAlignment(Qt::AlignCenter);
    addWidget(label);

    m_toggleSync = new QToolButton;
    m_toggleSync->setIcon(QIcon(":/core/images/linkicon.png"));
    m_toggleSync->setCheckable(true);
    m_toggleSync->setChecked(true);
    m_toggleSync->setToolTip(tr("Synchronize with Editor"));
    connect(m_toggleSync, SIGNAL(clicked(bool)), this, SLOT(toggleCursorSynchronization()));

    Core::EditorManager *editorManager = Core::EditorManager::instance();
    connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)),
            this, SLOT(updateCurrentEditor(Core::IEditor*)));
    updateCurrentEditor(editorManager->currentEditor());
}

OutlineWidgetStack::~OutlineWidgetStack()
{
}

QToolButton *OutlineWidgetStack::toggleSyncButton()
{
    return m_toggleSync;
}

bool OutlineWidgetStack::isCursorSynchronized() const
{
    return m_syncWithEditor;
}

void OutlineWidgetStack::toggleCursorSynchronization()
{
    m_syncWithEditor = !m_syncWithEditor;
    if (IOutlineWidget *outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget()))
        outlineWidget->setCursorSynchronization(m_syncWithEditor);
}

void OutlineWidgetStack::updateCurrentEditor(Core::IEditor *editor)
{
    IOutlineWidget *newWidget = 0;

    if (editor) {
        foreach (IOutlineWidgetFactory *widgetFactory, m_factory->widgetFactories()) {
            if (widgetFactory->supportsEditor(editor)) {
                newWidget = widgetFactory->createWidget(editor);
                break;
            }
        }
    }

    if (newWidget != currentWidget()) {
        // delete old widget
        if (IOutlineWidget *outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget())) {
            removeWidget(outlineWidget);
            delete outlineWidget;
        }
        if (newWidget) {
            newWidget->setCursorSynchronization(m_syncWithEditor);
            addWidget(newWidget);
            setCurrentWidget(newWidget);
        }
    }
}

OutlineFactory::OutlineFactory() :
    Core::INavigationWidgetFactory()
{
}

QList<IOutlineWidgetFactory*> OutlineFactory::widgetFactories() const
{
    return m_factories;
}

void OutlineFactory::setWidgetFactories(QList<IOutlineWidgetFactory*> factories)
{
    m_factories = factories;
}

QString OutlineFactory::displayName() const
{
    return tr("Outline");
}

QString OutlineFactory::id() const
{
    return QLatin1String("Outline");
}

QKeySequence OutlineFactory::activationSequence() const
{
    return QKeySequence();
}

Core::NavigationView OutlineFactory::createWidget()
{
    Core::NavigationView n;
    OutlineWidgetStack *placeHolder = new OutlineWidgetStack(this);
    n.widget = placeHolder;
    n.dockToolBarWidgets.append(placeHolder->toggleSyncButton());
    return n;
}

} // namespace Internal
} // namespace TextEditor
<commit_msg>Make default background of outline white.<commit_after>#include "outlinefactory.h"
#include <coreplugin/editormanager/editormanager.h>
#include <coreplugin/editormanager/ieditor.h>
#include <QVBoxLayout>
#include <QDebug>
#include <QToolButton>
#include <QLabel>
#include <QStackedWidget>

namespace TextEditor {
namespace Internal {

OutlineWidgetStack::OutlineWidgetStack(OutlineFactory *factory) :
    QStackedWidget(),
    m_factory(factory),
    m_syncWithEditor(true)
{
    QLabel *label = new QLabel(tr("No outline available"), this);
    label->setAlignment(Qt::AlignCenter);

    // set background to be white
    label->setAutoFillBackground(true);
    label->setBackgroundRole(QPalette::Base);

    addWidget(label);

    m_toggleSync = new QToolButton;
    m_toggleSync->setIcon(QIcon(":/core/images/linkicon.png"));
    m_toggleSync->setCheckable(true);
    m_toggleSync->setChecked(true);
    m_toggleSync->setToolTip(tr("Synchronize with Editor"));
    connect(m_toggleSync, SIGNAL(clicked(bool)), this, SLOT(toggleCursorSynchronization()));

    Core::EditorManager *editorManager = Core::EditorManager::instance();
    connect(editorManager, SIGNAL(currentEditorChanged(Core::IEditor*)),
            this, SLOT(updateCurrentEditor(Core::IEditor*)));
    updateCurrentEditor(editorManager->currentEditor());
}

OutlineWidgetStack::~OutlineWidgetStack()
{
}

QToolButton *OutlineWidgetStack::toggleSyncButton()
{
    return m_toggleSync;
}

bool OutlineWidgetStack::isCursorSynchronized() const
{
    return m_syncWithEditor;
}

void OutlineWidgetStack::toggleCursorSynchronization()
{
    m_syncWithEditor = !m_syncWithEditor;
    if (IOutlineWidget *outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget()))
        outlineWidget->setCursorSynchronization(m_syncWithEditor);
}

void OutlineWidgetStack::updateCurrentEditor(Core::IEditor *editor)
{
    IOutlineWidget *newWidget = 0;

    if (editor) {
        foreach (IOutlineWidgetFactory *widgetFactory, m_factory->widgetFactories()) {
            if (widgetFactory->supportsEditor(editor)) {
                newWidget = widgetFactory->createWidget(editor);
                break;
            }
        }
    }

    if (newWidget != currentWidget()) {
        // delete old widget
        if (IOutlineWidget *outlineWidget = qobject_cast<IOutlineWidget*>(currentWidget())) {
            removeWidget(outlineWidget);
            delete outlineWidget;
        }
        if (newWidget) {
            newWidget->setCursorSynchronization(m_syncWithEditor);
            addWidget(newWidget);
            setCurrentWidget(newWidget);
        }
    }
}

OutlineFactory::OutlineFactory() :
    Core::INavigationWidgetFactory()
{
}

QList<IOutlineWidgetFactory*> OutlineFactory::widgetFactories() const
{
    return m_factories;
}

void OutlineFactory::setWidgetFactories(QList<IOutlineWidgetFactory*> factories)
{
    m_factories = factories;
}

QString OutlineFactory::displayName() const
{
    return tr("Outline");
}

QString OutlineFactory::id() const
{
    return QLatin1String("Outline");
}

QKeySequence OutlineFactory::activationSequence() const
{
    return QKeySequence();
}

Core::NavigationView OutlineFactory::createWidget()
{
    Core::NavigationView n;
    OutlineWidgetStack *placeHolder = new OutlineWidgetStack(this);
    n.widget = placeHolder;
    n.dockToolBarWidgets.append(placeHolder->toggleSyncButton());
    return n;
}

} // namespace Internal
} // namespace TextEditor
<|endoftext|>


<commit_before>#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/* local */
#include "EdjeView.h"
#include "EdjeContext.h"

/* Eflxx */
#include <elementaryxx/Elementaryxx.h>

/* stateval */
#include "stateval/stateval.h"
#include "stateval/private/stateval_private.h"

/* STD */
#include <iostream>

using namespace std;

EdjeView::EdjeView(EdjeContext *context, const std::map <std::string, std::string> &params) :
  mLogger("stateval.plugins.viewmanager.edje.EdjeView"),
  mEdjeContext(context),
  groupState(Unrealized),
  mEvent (-1)
{
  assert(context);

  std::map <std::string, std::string>::const_iterator param_it;

  param_it = params.find ("filename");
  if (param_it != params.end ())
  {
    mFilename = param_it->second;
  }
  else
  {
    // TODO: needed error handling
    assert (false);
  }

  param_it = params.find ("groupname");
  if (param_it != params.end ())
  {
    mGroupname = param_it->second;
  }
  else
  {
    // TODO: needed error handling
    assert (false);
  }

  LOG4CXX_TRACE(mLogger, "constructor: " << mFilename << "," << mGroupname);

  mRealizeDispatcher.signalDispatch.connect(sigc::mem_fun(this, &EdjeView::realizeDispatched));
  mUnrealizeDispatcher.signalDispatch.connect(sigc::mem_fun(this, &EdjeView::unrealizeDispatched));

  mPushEventDispatcher.signalDispatch.connect(sigc::mem_fun(this, &EdjeView::pushEventDispatched));
}

void EdjeView::realize()
{
  LOG4CXX_DEBUG(mLogger, "+wait for realize");
  mRealizeDispatcher.emit();

  mutexRealize.lock();
  condRealize.wait(mutexRealize);
  mutexRealize.unlock();
  LOG4CXX_DEBUG(mLogger, "-wait for realize");
}

void EdjeView::unrealize()
{
  LOG4CXX_TRACE(mLogger, "+unrealize ()");

  mUnrealizeDispatcher.emit();

  // wait for animation finished on statemachine thread
  mutexUnrealize.lock();
  condUnrealize.wait(mutexUnrealize);
  mutexUnrealize.unlock();

  groupState = Unrealized;

  LOG4CXX_TRACE(mLogger, "-unrealize ()");
}

void EdjeView::realizeDispatched(int missedEvents)
{
  LOG4CXX_TRACE(mLogger, "+realizeDispatched()");

  LOG4CXX_INFO(mLogger, "Filename: '" << mFilename << "', Groupname: " << mGroupname);

  mWindow = mEdjeContext->window;
  mLayout = Elmxx::Layout::factory(*mWindow);
  mLayout->setSizeHintWeight(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  mWindow->addResizeObject(*mLayout);
  mLayout->show();

  mLayout->setFile(mFilename, mGroupname);

  LOG4CXX_INFO(mLogger, "Layer: " << getLayer());
  mLayout->setLayer(getLayer());

  Eflxx::CountedPtr <Edjexx::Object> edjeObj(mLayout->getEdje());

  // connect visible/invisible handler
  // --> TODO: while changing names connect both -> remove later deprecated names!
  edjeObj->connect("invisible_signal", "edje", sigc::mem_fun(this, &EdjeView::invisibleFunc));
  edjeObj->connect("visible_signal", "edje", sigc::mem_fun(this, &EdjeView::visibleFunc));
  //// <--

  // this is the new name of the spec!
  edjeObj->connect("animation,end", "invisible", sigc::mem_fun(this, &EdjeView::invisibleFunc));
  edjeObj->connect("animation,end", "visible", sigc::mem_fun(this, &EdjeView::visibleFunc));

  edjeObj->connect("*", "edje", sigc::mem_fun(this, &EdjeView::edjeFunc));
  edjeObj->connect("*", "stateval", sigc::mem_fun(this, &EdjeView::statevalFunc));

  edjeObj->connect("*", "*", sigc::mem_fun(this, &EdjeView::allFunc));

  mLayout->resize(mEdjeContext->resolution);

  updateContent(true);

  groupState = Realizing;
  edjeObj->emit("visible", "stateval");
  mEdjeContext->background->hide (); // make background "transparent"

  condRealize.signal();

  LOG4CXX_TRACE(mLogger, "-realizeDispatched()");
}

void EdjeView::unrealizeDispatched(int missedEvents)
{
  if (mLayout)
  {
    groupState = Unrealizing;
    Eflxx::CountedPtr <Edjexx::Object> edjeObj = mLayout->getEdje();

    // show background while view switch to prevent flickering of
    // below composite layer
    mEdjeContext->background->show ();

    edjeObj->emit("invisible", "stateval");
  }
}

void EdjeView::updateContent(bool initalDrawing)
{

  // FIXME: seems first screen could not do a updateContent ()!!
  if (!mLayout)
    return;

  StateMachineAccessor &stateMachineAccessor = StateMachineAccessor::getInstance();
  Eflxx::CountedPtr <Edjexx::Object> edjeObj(mLayout->getEdje());

  /* FIXME: this logic below is not correct because if a variable is connected to two different widgets it
            may not be updated correct. TODO: check this!
   */
  for (WidgetIterator wl_it = beginOfWidgets();
       wl_it != endOfWidgets();
       ++wl_it)
  {
    const Widget &w = *wl_it;

    AbstractVariable *val = stateMachineAccessor.getVariable(w.getVariable());
    assert(val);

    // update widget data only if update is needed
    // always draw a widget for initial screen display
    if (val->needsUpdate () || initalDrawing)
    {
      try
      {
        Edjexx::Part &part = edjeObj->getPart(w.getName());

        if (val->getType() == AbstractVariable::TYPE_STRUCT)
        {
          Struct *st = static_cast <Struct *>(val);
          bool specialHandled = false;

          // TODO: is there a special handling for struct types needed?
          try
          {
            Evasxx::Object &ext_eo3 = part.getExternalObject();
            Evasxx::Object &eo3 = part.getSwallow();
            LOG4CXX_DEBUG(mLogger, "Edje External Widget type: " << ext_eo3.getType());
            LOG4CXX_DEBUG(mLogger, "Edje Part Widget type: " << eo3.getType());

            if (ext_eo3.getType() == "elm_widget")
            {
              Elmxx::Object &elm_object = *(static_cast <Elmxx::Object *>(&ext_eo3));

              LOG4CXX_DEBUG(mLogger, "Elm Widget type: " << elm_object.getWidgetType());
              // TODO: slider is now generic supported. But ElmList needs to be implemented...
              /*if (elm_object.getWidgetType () == "slider")
              {
                Elmxx::Slider &slider = *(static_cast <Elmxx::Slider*> (&elm_object));
                AbstractVariable *av1 = st->getData ("label");
                if (av1->getType () == AbstractVariable::TYPE_STRING)
                {
                  String *s1 = static_cast <String*> (av1);
                  slider.setLabel (s1->getData ());
                }

                AbstractVariable *av2 = st->getData ("value");
                if (av2->getType () == AbstractVariable::TYPE_FLOAT)
                {
                  Float *f1 = static_cast <Float*> (av2);
                  slider.setValue (f1->getData ());
                }
                specialHandled = true;
              }*/
            }
          }
          catch (Edjexx::ExternalNotExistingException ene)
          {
            cerr << ene.what() << endl;
          }

          // generic widget type handling
          if (!specialHandled)
          {
            for (Struct::Iterator s_it = st->begin();
                 s_it != st->end();
                 ++s_it)
            {
              const string &name = s_it->first;
              AbstractVariable *av = s_it->second;

              if (av)
              {
                if (av->getType() == AbstractVariable::TYPE_STRING)
                {
                  String *str = static_cast <String *>(av);
                  Edjexx::ExternalParam param(name, str->getData());
                  part.setParam(&param);
                }
                else if (av->getType() == AbstractVariable::TYPE_FLOAT)
                {
                  Float *f = static_cast <Float *>(av);
                  Edjexx::ExternalParam param(name, f->getData());
                  part.setParam(&param);
                }
                else if (av->getType() == AbstractVariable::TYPE_BOOL)
                {
                  Bool *b = static_cast <Bool *>(av);
                  Edjexx::ExternalParam param(name, b->getData());
                  part.setParam(&param);
                }
              }
            }
          }
        }
        else if (val->getType() == AbstractVariable::TYPE_LIST)
        {
          try
          {
            List *ls = static_cast <List *>(val);

            Evasxx::Object &ext_eo3 = part.getExternalObject();
            Evasxx::Object &eo3 = part.getSwallow();
            LOG4CXX_DEBUG(mLogger, "Edje External Widget type: " << ext_eo3.getType());
            LOG4CXX_DEBUG(mLogger, "Edje Part Widget type: " << eo3.getType());

            if (ext_eo3.getType() == "elm_widget")
            {
              Elmxx::Object &elm_object = *(static_cast <Elmxx::Object *>(&ext_eo3));

              LOG4CXX_DEBUG(mLogger, "Elm Widget type: " << elm_object.getWidgetType());

              if (elm_object.getWidgetType() == "list")
              {
                Elmxx::List &list = *(static_cast <Elmxx::List *>(&elm_object));

                // TODO: I think until the edited/merge feature is implemented it's the
                // best to clear the list before adding new elements...
                list.clear();
                for (List::Iterator ls_it = ls->begin();
                     ls_it != ls->end();
                     ++ls_it)
                {
                  AbstractVariable *av = *ls_it;

                  if (av->getType() == AbstractVariable::TYPE_STRING)
                  {
                    String *str = static_cast <String *>(av);
                    list.append(str->getData(), NULL, NULL);
                  }
                  list.go();
                }
              }
            }
          }
          catch (Edjexx::ExternalNotExistingException ene)
          {
            cerr << ene.what() << endl;
          }
        }
        else if (val->getType() == AbstractVariable::TYPE_STRING)
        {
          String *str = static_cast <String *>(val);

          part.setText(str->getData());
        }
        else
        {
          LOG4CXX_WARN(mLogger, "Currently not supported AbstractVariable Type!");
        }
      }
      catch (Edjexx::PartNotExistingException pne)
      {
        cerr << pne.what() << endl;
      }

      // widget is updated, so reset need for update
      val->setUpdateFlag (false);

      LOG4CXX_INFO(mLogger, "Widget name: " << w.getName());
      LOG4CXX_INFO(mLogger, "Widget variable: " << w.getVariable());
    }

  }
}

void EdjeView::invisibleFunc(const std::string emmision, const std::string source)
{
  LOG4CXX_TRACE(mLogger, "invisibleFunc");

  groupState = Unrealized;
  mWindow->delResizeObject(*mLayout);
  mLayout->destroy();
  mLayout = NULL;

  // signal the edje statemachine thread that the animation is finished
  condUnrealize.signal();
}

void EdjeView::visibleFunc(const std::string emmision, const std::string source)
{
  LOG4CXX_TRACE(mLogger, "visibleFunc");

  groupState = Realized;
}

void EdjeView::statevalFunc(const std::string emmision, const std::string source)
{
  LOG4CXX_TRACE(mLogger, "statevalFunc: " << emmision << ", " << source);
}

void EdjeView::edjeFunc(const std::string emmision, const std::string source)
{
  LOG4CXX_TRACE(mLogger, "edjeFunc: " << emmision << ", " << source);
}

void EdjeView::allFunc(const std::string emmision, const std::string source)
{
  if (source != "stateval")
  {
    StateMachineAccessor &StateMachineAccessor(StateMachineAccessor::getInstance());

    string event("edje," + source + "," + emmision);
    LOG4CXX_DEBUG(mLogger, "allFunc: " << event << " (" << mGroupname << ")");

    // only push new events for realized screens
    // FIXME: when I do this it leads into freezes as the invisible signal doesn't come
    //if (groupState != Realized) return;

    if (StateMachineAccessor.findMapingEvent(event) != -1)
    {
      LOG4CXX_DEBUG(mLogger, "mStateMachineAccessor->pushEvent");
      StateMachineAccessor.pushEvent(event);
    }
  }
}

void EdjeView::pushEventDispatched(int missedEvents)
{
  if (groupState == Realized)
  {
    StateMachineAccessor &stateMachineAccessor(StateMachineAccessor::getInstance());

    // TODO: think about defining some common events (update/exit,...) in stateval lib
    static const int VIEW_UPDATE_EVENT = stateMachineAccessor.findMapingEvent("VIEW_UPDATE");

    string eventString = stateMachineAccessor.findMapingEvent(mEvent);

    LOG4CXX_DEBUG(mLogger, "EdjeView::smEvents: " << mEvent << " / " << eventString);

    if ((eventString.length() >= 4) && (eventString.substr(4) != "edje"))
    {
      Eflxx::CountedPtr <Edjexx::Object> edjeObj = mLayout->getEdje();
      edjeObj->emit(eventString, "stateval");
    }

    if (mEvent == VIEW_UPDATE_EVENT)
    {
      updateContent(false);
    }
  }

  mCondPushEvent.signal ();
}

void EdjeView::pushEvent(int event)
{
  mEvent = event;

  mPushEventDispatcher.emit ();

  mMutexPushEvent.lock();
  mCondPushEvent.wait(mMutexPushEvent);
  mMutexPushEvent.unlock();
}
<commit_msg>repair Elm_list feature<commit_after>#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

/* local */
#include "EdjeView.h"
#include "EdjeContext.h"

/* Eflxx */
#include <elementaryxx/Elementaryxx.h>

/* stateval */
#include "stateval/stateval.h"
#include "stateval/private/stateval_private.h"

/* STD */
#include <iostream>

using namespace std;

EdjeView::EdjeView(EdjeContext *context, const std::map <std::string, std::string> &params) :
  mLogger("stateval.plugins.viewmanager.edje.EdjeView"),
  mEdjeContext(context),
  groupState(Unrealized),
  mEvent (-1)
{
  assert(context);

  std::map <std::string, std::string>::const_iterator param_it;

  param_it = params.find ("filename");
  if (param_it != params.end ())
  {
    mFilename = param_it->second;
  }
  else
  {
    // TODO: needed error handling
    assert (false);
  }

  param_it = params.find ("groupname");
  if (param_it != params.end ())
  {
    mGroupname = param_it->second;
  }
  else
  {
    // TODO: needed error handling
    assert (false);
  }

  LOG4CXX_TRACE(mLogger, "constructor: " << mFilename << "," << mGroupname);

  mRealizeDispatcher.signalDispatch.connect(sigc::mem_fun(this, &EdjeView::realizeDispatched));
  mUnrealizeDispatcher.signalDispatch.connect(sigc::mem_fun(this, &EdjeView::unrealizeDispatched));

  mPushEventDispatcher.signalDispatch.connect(sigc::mem_fun(this, &EdjeView::pushEventDispatched));
}

void EdjeView::realize()
{
  LOG4CXX_DEBUG(mLogger, "+wait for realize");
  mRealizeDispatcher.emit();

  mutexRealize.lock();
  condRealize.wait(mutexRealize);
  mutexRealize.unlock();
  LOG4CXX_DEBUG(mLogger, "-wait for realize");
}

void EdjeView::unrealize()
{
  LOG4CXX_TRACE(mLogger, "+unrealize ()");

  mUnrealizeDispatcher.emit();

  // wait for animation finished on statemachine thread
  mutexUnrealize.lock();
  condUnrealize.wait(mutexUnrealize);
  mutexUnrealize.unlock();

  groupState = Unrealized;

  LOG4CXX_TRACE(mLogger, "-unrealize ()");
}

void EdjeView::realizeDispatched(int missedEvents)
{
  LOG4CXX_TRACE(mLogger, "+realizeDispatched()");

  LOG4CXX_INFO(mLogger, "Filename: '" << mFilename << "', Groupname: " << mGroupname);

  mWindow = mEdjeContext->window;
  mLayout = Elmxx::Layout::factory(*mWindow);
  mLayout->setSizeHintWeight(EVAS_HINT_EXPAND, EVAS_HINT_EXPAND);
  mWindow->addResizeObject(*mLayout);
  mLayout->show();

  mLayout->setFile(mFilename, mGroupname);

  LOG4CXX_INFO(mLogger, "Layer: " << getLayer());
  mLayout->setLayer(getLayer());

  Eflxx::CountedPtr <Edjexx::Object> edjeObj(mLayout->getEdje());

  // connect visible/invisible handler
  // --> TODO: while changing names connect both -> remove later deprecated names!
  edjeObj->connect("invisible_signal", "edje", sigc::mem_fun(this, &EdjeView::invisibleFunc));
  edjeObj->connect("visible_signal", "edje", sigc::mem_fun(this, &EdjeView::visibleFunc));
  //// <--

  // this is the new name of the spec!
  edjeObj->connect("animation,end", "invisible", sigc::mem_fun(this, &EdjeView::invisibleFunc));
  edjeObj->connect("animation,end", "visible", sigc::mem_fun(this, &EdjeView::visibleFunc));

  edjeObj->connect("*", "edje", sigc::mem_fun(this, &EdjeView::edjeFunc));
  edjeObj->connect("*", "stateval", sigc::mem_fun(this, &EdjeView::statevalFunc));

  edjeObj->connect("*", "*", sigc::mem_fun(this, &EdjeView::allFunc));

  mLayout->resize(mEdjeContext->resolution);

  updateContent(true);

  groupState = Realizing;
  edjeObj->emit("visible", "stateval");
  mEdjeContext->background->hide (); // make background "transparent"

  condRealize.signal();

  LOG4CXX_TRACE(mLogger, "-realizeDispatched()");
}

void EdjeView::unrealizeDispatched(int missedEvents)
{
  if (mLayout)
  {
    groupState = Unrealizing;
    Eflxx::CountedPtr <Edjexx::Object> edjeObj = mLayout->getEdje();

    // show background while view switch to prevent flickering of
    // below composite layer
    mEdjeContext->background->show ();

    edjeObj->emit("invisible", "stateval");
  }
}

void EdjeView::updateContent(bool initalDrawing)
{

  // FIXME: seems first screen could not do a updateContent ()!!
  if (!mLayout)
    return;

  StateMachineAccessor &stateMachineAccessor = StateMachineAccessor::getInstance();
  Eflxx::CountedPtr <Edjexx::Object> edjeObj(mLayout->getEdje());

  /* FIXME: this logic below is not correct because if a variable is connected to two different widgets it
            may not be updated correct. TODO: check this!
   */
  for (WidgetIterator wl_it = beginOfWidgets();
       wl_it != endOfWidgets();
       ++wl_it)
  {
    const Widget &w = *wl_it;

    AbstractVariable *val = stateMachineAccessor.getVariable(w.getVariable());
    assert(val);

    // update widget data only if update is needed
    // always draw a widget for initial screen display
    if (val->needsUpdate () || initalDrawing)
    {
      try
      {
        Edjexx::Part &part = edjeObj->getPart(w.getName());

        if (val->getType() == AbstractVariable::TYPE_STRUCT)
        {
          Struct *st = static_cast <Struct *>(val);
          bool specialHandled = false;

          // TODO: is there a special handling for struct types needed?
          try
          {
            Evasxx::Object &ext_eo3 = part.getExternalObject();
            Evasxx::Object &eo3 = part.getSwallow();
            LOG4CXX_DEBUG(mLogger, "Edje External Widget type: " << ext_eo3.getType());
            LOG4CXX_DEBUG(mLogger, "Edje Part Widget type: " << eo3.getType());

            if (ext_eo3.getType() == "elm_widget")
            {
              Elmxx::Object &elm_object = *(static_cast <Elmxx::Object *>(&ext_eo3));

              LOG4CXX_DEBUG(mLogger, "Elm Widget type: " << elm_object.getWidgetType());
              // TODO: slider is now generic supported. But ElmList needs to be implemented...
              /*if (elm_object.getWidgetType () == "slider")
              {
                Elmxx::Slider &slider = *(static_cast <Elmxx::Slider*> (&elm_object));
                AbstractVariable *av1 = st->getData ("label");
                if (av1->getType () == AbstractVariable::TYPE_STRING)
                {
                  String *s1 = static_cast <String*> (av1);
                  slider.setLabel (s1->getData ());
                }

                AbstractVariable *av2 = st->getData ("value");
                if (av2->getType () == AbstractVariable::TYPE_FLOAT)
                {
                  Float *f1 = static_cast <Float*> (av2);
                  slider.setValue (f1->getData ());
                }
                specialHandled = true;
              }*/
            }
          }
          catch (Edjexx::ExternalNotExistingException ene)
          {
            cerr << ene.what() << endl;
          }

          // generic widget type handling
          if (!specialHandled)
          {
            for (Struct::Iterator s_it = st->begin();
                 s_it != st->end();
                 ++s_it)
            {
              const string &name = s_it->first;
              AbstractVariable *av = s_it->second;

              if (av)
              {
                if (av->getType() == AbstractVariable::TYPE_STRING)
                {
                  String *str = static_cast <String *>(av);
                  Edjexx::ExternalParam param(name, str->getData());
                  part.setParam(&param);
                }
                else if (av->getType() == AbstractVariable::TYPE_FLOAT)
                {
                  Float *f = static_cast <Float *>(av);
                  Edjexx::ExternalParam param(name, f->getData());
                  part.setParam(&param);
                }
                else if (av->getType() == AbstractVariable::TYPE_BOOL)
                {
                  Bool *b = static_cast <Bool *>(av);
                  Edjexx::ExternalParam param(name, b->getData());
                  part.setParam(&param);
                }
              }
            }
          }
        }
        else if (val->getType() == AbstractVariable::TYPE_LIST)
        {
          try
          {
            List *ls = static_cast <List *>(val);

            Evasxx::Object &ext_eo3 = part.getExternalObject();
            Evasxx::Object &eo3 = part.getSwallow();
            LOG4CXX_DEBUG(mLogger, "Edje External Widget type: " << ext_eo3.getType());
            LOG4CXX_DEBUG(mLogger, "Edje Part Widget type: " << eo3.getType());

            if (ext_eo3.getType() == "elm_list")
            {
              Elmxx::Object &elm_object = *(static_cast <Elmxx::Object *>(&ext_eo3));

              LOG4CXX_DEBUG(mLogger, "Elm Widget type: " << elm_object.getWidgetType());

              if (elm_object.getWidgetType() == "Elm_List")
              {
                Elmxx::List &list = *(static_cast <Elmxx::List *>(&elm_object));

                // TODO: I think until the edited/merge feature is implemented it's the
                // best to clear the list before adding new elements...
                list.clear();
                for (List::Iterator ls_it = ls->begin();
                     ls_it != ls->end();
                     ++ls_it)
                {
                  AbstractVariable *av = *ls_it;

                  if (av->getType() == AbstractVariable::TYPE_STRING)
                  {
                    String *str = static_cast <String *>(av);
                    list.append(str->getData(), NULL, NULL);
                  }
                  list.go();
                }
              }
            }
          }
          catch (Edjexx::ExternalNotExistingException ene)
          {
            cerr << ene.what() << endl;
          }
        }
        else if (val->getType() == AbstractVariable::TYPE_STRING)
        {
          String *str = static_cast <String *>(val);

          part.setText(str->getData());
        }
        else
        {
          LOG4CXX_WARN(mLogger, "Currently not supported AbstractVariable Type!");
        }
      }
      catch (Edjexx::PartNotExistingException pne)
      {
        cerr << pne.what() << endl;
      }

      // widget is updated, so reset need for update
      val->setUpdateFlag (false);

      LOG4CXX_INFO(mLogger, "Widget name: " << w.getName());
      LOG4CXX_INFO(mLogger, "Widget variable: " << w.getVariable());
    }

  }
}

void EdjeView::invisibleFunc(const std::string emmision, const std::string source)
{
  LOG4CXX_TRACE(mLogger, "invisibleFunc");

  groupState = Unrealized;
  mWindow->delResizeObject(*mLayout);
  mLayout->destroy();
  mLayout = NULL;

  // signal the edje statemachine thread that the animation is finished
  condUnrealize.signal();
}

void EdjeView::visibleFunc(const std::string emmision, const std::string source)
{
  LOG4CXX_TRACE(mLogger, "visibleFunc");

  groupState = Realized;
}

void EdjeView::statevalFunc(const std::string emmision, const std::string source)
{
  LOG4CXX_TRACE(mLogger, "statevalFunc: " << emmision << ", " << source);
}

void EdjeView::edjeFunc(const std::string emmision, const std::string source)
{
  LOG4CXX_TRACE(mLogger, "edjeFunc: " << emmision << ", " << source);
}

void EdjeView::allFunc(const std::string emmision, const std::string source)
{
  if (source != "stateval")
  {
    StateMachineAccessor &StateMachineAccessor(StateMachineAccessor::getInstance());

    string event("edje," + source + "," + emmision);
    LOG4CXX_DEBUG(mLogger, "allFunc: " << event << " (" << mGroupname << ")");

    // only push new events for realized screens
    // FIXME: when I do this it leads into freezes as the invisible signal doesn't come
    //if (groupState != Realized) return;

    if (StateMachineAccessor.findMapingEvent(event) != -1)
    {
      LOG4CXX_DEBUG(mLogger, "mStateMachineAccessor->pushEvent");
      StateMachineAccessor.pushEvent(event);
    }
  }
}

void EdjeView::pushEventDispatched(int missedEvents)
{
  if (groupState == Realized)
  {
    StateMachineAccessor &stateMachineAccessor(StateMachineAccessor::getInstance());

    // TODO: think about defining some common events (update/exit,...) in stateval lib
    static const int VIEW_UPDATE_EVENT = stateMachineAccessor.findMapingEvent("VIEW_UPDATE");

    string eventString = stateMachineAccessor.findMapingEvent(mEvent);

    LOG4CXX_DEBUG(mLogger, "EdjeView::smEvents: " << mEvent << " / " << eventString);

    if ((eventString.length() >= 4) && (eventString.substr(4) != "edje"))
    {
      Eflxx::CountedPtr <Edjexx::Object> edjeObj = mLayout->getEdje();
      edjeObj->emit(eventString, "stateval");
    }

    if (mEvent == VIEW_UPDATE_EVENT)
    {
      updateContent(false);
    }
  }

  mCondPushEvent.signal ();
}

void EdjeView::pushEvent(int event)
{
  mEvent = event;

  mPushEventDispatcher.emit ();

  mMutexPushEvent.lock();
  mCondPushEvent.wait(mMutexPushEvent);
  mMutexPushEvent.unlock();
}
<|endoftext|>


<commit_before>/*****************************
Copyright 2011 Rafael Muñoz Salinas. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

   1. Redistributions of source code must retain the above copyright notice, this list of
      conditions and the following disclaimer.

   2. Redistributions in binary form must reproduce the above copyright notice, this list
      of conditions and the following disclaimer in the documentation and/or other materials
      provided with the distribution.

THIS SOFTWARE IS PROVIDED BY Rafael Muñoz Salinas ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Rafael Muñoz Salinas OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of Rafael Muñoz Salinas.
********************************/
#include <aruco/boarddetector.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <fstream>
#include <opencv2/calib3d/calib3d.hpp>
using namespace std;
using namespace cv;
namespace aruco {
    /**
    */
    BoardDetector::BoardDetector ( bool  setYPerpendicular ) {
        _setYPerpendicular=setYPerpendicular;
        _areParamsSet=false;
        repj_err_thres=-1;
    }
    /**
       * Use if you plan to let this class to perform marker detection too
       */
    void BoardDetector::setParams ( const BoardConfiguration &bc,const CameraParameters &cp, float markerSizeMeters ) {
        _camParams=cp;
        _markerSize=markerSizeMeters;
        _bconf=bc;
        _areParamsSet=true;
    }
    /**
    *
    *
    */
    void BoardDetector::setParams ( const BoardConfiguration &bc ) {
        _bconf=bc;
        _areParamsSet=true;
    }

    /**
    *
    *
    */
    float  BoardDetector::detect ( const cv::Mat &im ) throw ( cv::Exception ) {
        _mdetector.detect ( im,_vmarkers );

        float res;

        if ( _camParams.isValid() )
            res=detect ( _vmarkers,_bconf,_boardDetected,_camParams.CameraMatrix,_camParams.Distorsion,_markerSize );
        else res=detect ( _vmarkers,_bconf,_boardDetected );
        return res;
    }
    /**
    *
    *
    */
    float BoardDetector::detect ( const vector<Marker> &detectedMarkers,const  BoardConfiguration &BConf, Board &Bdetected,const CameraParameters &cp, float markerSizeMeters ) throw ( cv::Exception ) {
        return detect ( detectedMarkers, BConf,Bdetected,cp.CameraMatrix,cp.Distorsion,markerSizeMeters );
    }
    /**
    *
    *
    */
    float BoardDetector::detect ( const vector<Marker> &detectedMarkers,const  BoardConfiguration &BConf, Board &Bdetected, Mat camMatrix,Mat distCoeff,float markerSizeMeters ) throw ( cv::Exception ) {
        if ( BConf.size() ==0 ) throw cv::Exception ( 8881,"BoardDetector::detect","Invalid BoardConfig that is empty",__FILE__,__LINE__ );
        if ( BConf[0].size() <2 ) throw cv::Exception ( 8881,"BoardDetector::detect","Invalid BoardConfig that is empty 2",__FILE__,__LINE__ );
        //compute the size of the markers in meters, which is used for some routines(mostly drawing)
        float ssize;
        if ( BConf.mInfoType==BoardConfiguration::PIX && markerSizeMeters>0 ) ssize=markerSizeMeters;
        else if ( BConf.mInfoType==BoardConfiguration::METERS ) {
            ssize=cv::norm ( BConf[0][0]-BConf[0][1] );
        }

        // cout<<"markerSizeMeters="<<markerSizeMeters<<endl;
        Bdetected.clear();
        ///find among detected markers these that belong to the board configuration
        for ( unsigned int i=0; i<detectedMarkers.size(); i++ ) {
            int idx=BConf.getIndexOfMarkerId ( detectedMarkers[i].id );
            if ( idx!=-1 ) {
                Bdetected.push_back ( detectedMarkers[i] );
                Bdetected.back().ssize=ssize;
            }
        }
        //copy configuration
        Bdetected.conf=BConf;
//

        bool hasEnoughInfoForRTvecCalculation=false;
        if ( Bdetected.size() >=1 ) {
            if ( camMatrix.rows!=0 ) {
                if ( markerSizeMeters>0 && BConf.mInfoType==BoardConfiguration::PIX ) hasEnoughInfoForRTvecCalculation=true;
                else if ( BConf.mInfoType==BoardConfiguration::METERS ) hasEnoughInfoForRTvecCalculation=true;
            }
        }

//calculate extrinsic if there is information for that
        if ( hasEnoughInfoForRTvecCalculation ) {

            //calculate the size of the markers in meters if expressed in pixels
            double marker_meter_per_pix=0;
            if ( BConf.mInfoType==BoardConfiguration::PIX ) marker_meter_per_pix=markerSizeMeters /  cv::norm ( BConf[0][0]-BConf[0][1] );
            else marker_meter_per_pix=1;//to avoind interferring the process below

            // now, create the matrices for finding the extrinsics
            vector<cv::Point3f> objPoints;
            vector<cv::Point2f> imagePoints;
            for ( size_t i=0; i<Bdetected.size(); i++ ) {
                int idx=Bdetected.conf.getIndexOfMarkerId ( Bdetected[i].id );
                assert ( idx!=-1 );
                for ( int p=0; p<4; p++ ) {
                    imagePoints.push_back ( Bdetected[i][p] );
                    const aruco::MarkerInfo &Minfo=Bdetected.conf.getMarkerInfo ( Bdetected[i].id );
                    objPoints.push_back ( Minfo[p]*marker_meter_per_pix );
//  		cout<<objPoints.back()<<endl;
                }
            }
            if ( distCoeff.total() ==0 ) distCoeff=cv::Mat::zeros ( 1,4,CV_32FC1 );

// 	    for(size_t i=0;i< imagePoints.size();i++){
// 		cout<<objPoints[i]<<" "<<imagePoints[i]<<endl;
// 	    }
// 	    cout<<"cam="<<camMatrix<<" "<<distCoeff<<endl;
            cv::Mat rvec,tvec;
            cv::solvePnP ( objPoints,imagePoints,camMatrix,distCoeff,rvec,tvec );
            rvec.convertTo ( Bdetected.Rvec,CV_32FC1 );
            tvec.convertTo ( Bdetected.Tvec,CV_32FC1 );
//             cout<<rvec<< " "<<tvec<<" _setYPerpendicular="<<_setYPerpendicular<<endl;

            {
                vector<cv::Point2f> reprojected;
                cv::projectPoints ( objPoints,rvec,tvec,camMatrix,distCoeff,reprojected );
                double errSum=0;
                //check now the reprojection error and
                for ( size_t i=0; i<reprojected.size(); i++ ) {
                    errSum+=cv::norm ( reprojected[i]-imagePoints[i] );
                }
//                  cout<<"AAA RE="<<errSum/double ( reprojected.size() ) <<endl;

            }
            //now, do a refinement and remove points whose reprojection error is above a threshold, then repeat calculation with the rest
            if ( repj_err_thres>0 ) {
                vector<cv::Point2f> reprojected;
                cv::projectPoints ( objPoints,rvec,tvec,camMatrix,distCoeff,reprojected );

                vector<int> pointsThatPassTest;//indices
                //check now the reprojection error and
                for ( size_t i=0; i<reprojected.size(); i++ ) {
                    float err=cv::norm ( reprojected[i]-imagePoints[i] );
                    if ( err<repj_err_thres ) pointsThatPassTest.push_back ( i );
                }
                cout<<"Number of points after reprjection test "<<pointsThatPassTest.size() <<"/"<<objPoints.size() <<endl;
                //copy these data to another vectors and repeat
                vector<cv::Point3f> objPoints_filtered;
                vector<cv::Point2f> imagePoints_filtered;
                for ( size_t i=0; i<pointsThatPassTest.size(); i++ ) {
                    objPoints_filtered.push_back ( objPoints[pointsThatPassTest[i] ] );
                    imagePoints_filtered.push_back ( imagePoints[pointsThatPassTest[i] ] );
                }

                cv::solvePnP ( objPoints,imagePoints,camMatrix,distCoeff,rvec,tvec );
                rvec.convertTo ( Bdetected.Rvec,CV_32FC1 );
                tvec.convertTo ( Bdetected.Tvec,CV_32FC1 );
            }

            //now, rotate 90 deg in X so that Y axis points up
            if ( _setYPerpendicular )
                rotateXAxis ( Bdetected.Rvec );
//         cout<<Bdetected.Rvec.at<float>(0,0)<<" "<<Bdetected.Rvec.at<float>(1,0)<<" "<<Bdetected.Rvec.at<float>(2,0)<<endl;
//         cout<<Bdetected.Tvec.at<float>(0,0)<<" "<<Bdetected.Tvec.at<float>(1,0)<<" "<<Bdetected.Tvec.at<float>(2,0)<<endl;
        }

        float prob=float ( Bdetected.size() ) /double ( Bdetected.conf.size() );
        return prob;
    }

    void BoardDetector::rotateXAxis ( Mat &rotation ) {
        cv::Mat R ( 3,3,CV_32FC1 );
        Rodrigues ( rotation, R );
        //create a rotation matrix for x axis
        cv::Mat RX=cv::Mat::eye ( 3,3,CV_32FC1 );
        float angleRad=-M_PI/2;
        RX.at<float> ( 1,1 ) =cos ( angleRad );
        RX.at<float> ( 1,2 ) =-sin ( angleRad );
        RX.at<float> ( 2,1 ) =sin ( angleRad );
        RX.at<float> ( 2,2 ) =cos ( angleRad );
        //now multiply
        R=R*RX;
        //finally, the the rodrigues back
        Rodrigues ( R,rotation );

    }

    /**Static version (all in one)
     */
    Board BoardDetector::detect ( const cv::Mat &Image, const BoardConfiguration &bc,const CameraParameters &cp, float markerSizeMeters ) {
        BoardDetector BD;
        BD.setParams ( bc,cp,markerSizeMeters );
        BD.detect ( Image );
        return BD.getDetectedBoard();
    }
};

<commit_msg>Update boarddetector.cpp<commit_after>/*****************************
Copyright 2011 Rafael Muñoz Salinas. All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

   1. Redistributions of source code must retain the above copyright notice, this list of
      conditions and the following disclaimer.

   2. Redistributions in binary form must reproduce the above copyright notice, this list
      of conditions and the following disclaimer in the documentation and/or other materials
      provided with the distribution.

THIS SOFTWARE IS PROVIDED BY Rafael Muñoz Salinas ''AS IS'' AND ANY EXPRESS OR IMPLIED
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL Rafael Muñoz Salinas OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

The views and conclusions contained in the software and documentation are those of the
authors and should not be interpreted as representing official policies, either expressed
or implied, of Rafael Muñoz Salinas.
********************************/
#include <aruco/boarddetector.h>
#define _USE_MATH_DEFINES
#include <math.h>
#include <cstdlib>
#include <ctime>
#include <cassert>
#include <fstream>
#include <opencv2/calib3d/calib3d.hpp>
using namespace std;
using namespace cv;
namespace aruco {
    /**
    */
    BoardDetector::BoardDetector ( bool  setYPerpendicular ) {
        _setYPerpendicular=setYPerpendicular;
        _areParamsSet=false;
        repj_err_thres=-1;
    }
    /**
       * Use if you plan to let this class to perform marker detection too
       */
    void BoardDetector::setParams ( const BoardConfiguration &bc,const CameraParameters &cp, float markerSizeMeters ) {
        _camParams=cp;
        _markerSize=markerSizeMeters;
        _bconf=bc;
        _areParamsSet=true;
    }
    /**
    *
    *
    */
    void BoardDetector::setParams ( const BoardConfiguration &bc ) {
        _bconf=bc;
        _areParamsSet=true;
    }

    /**
    *
    *
    */
    float  BoardDetector::detect ( const cv::Mat &im ) throw ( cv::Exception ) {
        _mdetector.detect ( im,_vmarkers );

        float res;

        if ( _camParams.isValid() )
            res=detect ( _vmarkers,_bconf,_boardDetected,_camParams.CameraMatrix,_camParams.Distorsion,_markerSize );
        else res=detect ( _vmarkers,_bconf,_boardDetected );
        return res;
    }
    /**
    *
    *
    */
    float BoardDetector::detect ( const vector<Marker> &detectedMarkers,const  BoardConfiguration &BConf, Board &Bdetected,const CameraParameters &cp, float markerSizeMeters ) throw ( cv::Exception ) {
        return detect ( detectedMarkers, BConf,Bdetected,cp.CameraMatrix,cp.Distorsion,markerSizeMeters );
    }
    /**
    *
    *
    */
    float BoardDetector::detect ( const vector<Marker> &detectedMarkers,const  BoardConfiguration &BConf, Board &Bdetected, Mat camMatrix,Mat distCoeff,float markerSizeMeters ) throw ( cv::Exception ) {
      //  if ( BConf.size() ==0 ) throw cv::Exception ( 8881,"BoardDetector::detect","Invalid BoardConfig that is empty",__FILE__,__LINE__ );
      //  if ( BConf[0].size() <2 ) throw cv::Exception ( 8881,"BoardDetector::detect","Invalid BoardConfig that is empty 2",__FILE__,__LINE__ );
        //compute the size of the markers in meters, which is used for some routines(mostly drawing)
        float ssize;
        if ( BConf.mInfoType==BoardConfiguration::PIX && markerSizeMeters>0 ) ssize=markerSizeMeters;
        else if ( BConf.mInfoType==BoardConfiguration::METERS ) {
            ssize=cv::norm ( BConf[0][0]-BConf[0][1] );

        }

        // cout<<"markerSizeMeters="<<markerSizeMeters<<endl;
        Bdetected.clear();
        ///find among detected markers these that belong to the board configuration
        for ( unsigned int i=0; i<detectedMarkers.size(); i++ ) {
            int idx=BConf.getIndexOfMarkerId ( detectedMarkers[i].id );
            if ( idx!=-1 ) {
                Bdetected.push_back ( detectedMarkers[i] );
                Bdetected.back().ssize=ssize;
            }
        }
        //copy configuration
        Bdetected.conf=BConf;
//

        bool hasEnoughInfoForRTvecCalculation=false;
        if ( Bdetected.size() >=1 ) {
            if ( camMatrix.rows!=0 ) {
                if ( markerSizeMeters>0 && BConf.mInfoType==BoardConfiguration::PIX ) hasEnoughInfoForRTvecCalculation=true;
                else if ( BConf.mInfoType==BoardConfiguration::METERS ) hasEnoughInfoForRTvecCalculation=true;
            }
        }

//calculate extrinsic if there is information for that
        if ( hasEnoughInfoForRTvecCalculation ) {

            //calculate the size of the markers in meters if expressed in pixels
            double marker_meter_per_pix=0;
            if ( BConf.mInfoType==BoardConfiguration::PIX ) marker_meter_per_pix=markerSizeMeters /  cv::norm ( BConf[0][0]-BConf[0][1] );
            else marker_meter_per_pix=1;//to avoind interferring the process below

            // now, create the matrices for finding the extrinsics
            vector<cv::Point3f> objPoints;
            vector<cv::Point2f> imagePoints;
            for ( size_t i=0; i<Bdetected.size(); i++ ) {
                int idx=Bdetected.conf.getIndexOfMarkerId ( Bdetected[i].id );
                assert ( idx!=-1 );
                for ( int p=0; p<4; p++ ) {
                    imagePoints.push_back ( Bdetected[i][p] );
                    const aruco::MarkerInfo &Minfo=Bdetected.conf.getMarkerInfo ( Bdetected[i].id );
                    objPoints.push_back ( Minfo[p]*marker_meter_per_pix );
//  		cout<<objPoints.back()<<endl;
                }
            }
            if ( distCoeff.total() ==0 ) distCoeff=cv::Mat::zeros ( 1,4,CV_32FC1 );

// 	    for(size_t i=0;i< imagePoints.size();i++){
// 		cout<<objPoints[i]<<" "<<imagePoints[i]<<endl;
// 	    }
// 	    cout<<"cam="<<camMatrix<<" "<<distCoeff<<endl;
            cv::Mat rvec,tvec;
            cv::solvePnP ( objPoints,imagePoints,camMatrix,distCoeff,rvec,tvec );
            rvec.convertTo ( Bdetected.Rvec,CV_32FC1 );
            tvec.convertTo ( Bdetected.Tvec,CV_32FC1 );
//             cout<<rvec<< " "<<tvec<<" _setYPerpendicular="<<_setYPerpendicular<<endl;

            {
                vector<cv::Point2f> reprojected;
                cv::projectPoints ( objPoints,rvec,tvec,camMatrix,distCoeff,reprojected );
                double errSum=0;
                //check now the reprojection error and
                for ( size_t i=0; i<reprojected.size(); i++ ) {
                    errSum+=cv::norm ( reprojected[i]-imagePoints[i] );
                }
//                  cout<<"AAA RE="<<errSum/double ( reprojected.size() ) <<endl;

            }
            //now, do a refinement and remove points whose reprojection error is above a threshold, then repeat calculation with the rest
            if ( repj_err_thres>0 ) {
                vector<cv::Point2f> reprojected;
                cv::projectPoints ( objPoints,rvec,tvec,camMatrix,distCoeff,reprojected );

                vector<int> pointsThatPassTest;//indices
                //check now the reprojection error and
                for ( size_t i=0; i<reprojected.size(); i++ ) {
                    float err=cv::norm ( reprojected[i]-imagePoints[i] );
                    if ( err<repj_err_thres ) pointsThatPassTest.push_back ( i );
                }
                cout<<"Number of points after reprjection test "<<pointsThatPassTest.size() <<"/"<<objPoints.size() <<endl;
                //copy these data to another vectors and repeat
                vector<cv::Point3f> objPoints_filtered;
                vector<cv::Point2f> imagePoints_filtered;
                for ( size_t i=0; i<pointsThatPassTest.size(); i++ ) {
                    objPoints_filtered.push_back ( objPoints[pointsThatPassTest[i] ] );
                    imagePoints_filtered.push_back ( imagePoints[pointsThatPassTest[i] ] );
                }

                cv::solvePnP ( objPoints,imagePoints,camMatrix,distCoeff,rvec,tvec );
                rvec.convertTo ( Bdetected.Rvec,CV_32FC1 );
                tvec.convertTo ( Bdetected.Tvec,CV_32FC1 );
            }

            //now, rotate 90 deg in X so that Y axis points up
            if ( _setYPerpendicular )
                rotateXAxis ( Bdetected.Rvec );
//         cout<<Bdetected.Rvec.at<float>(0,0)<<" "<<Bdetected.Rvec.at<float>(1,0)<<" "<<Bdetected.Rvec.at<float>(2,0)<<endl;
//         cout<<Bdetected.Tvec.at<float>(0,0)<<" "<<Bdetected.Tvec.at<float>(1,0)<<" "<<Bdetected.Tvec.at<float>(2,0)<<endl;
        }

        float prob=float ( Bdetected.size() ) /double ( Bdetected.conf.size() );
        return prob;
    }

    void BoardDetector::rotateXAxis ( Mat &rotation ) {
        cv::Mat R ( 3,3,CV_32FC1 );
        Rodrigues ( rotation, R );
        //create a rotation matrix for x axis
        cv::Mat RX=cv::Mat::eye ( 3,3,CV_32FC1 );
        float angleRad=-M_PI/2;
        RX.at<float> ( 1,1 ) =cos ( angleRad );
        RX.at<float> ( 1,2 ) =-sin ( angleRad );
        RX.at<float> ( 2,1 ) =sin ( angleRad );
        RX.at<float> ( 2,2 ) =cos ( angleRad );
        //now multiply
        R=R*RX;
        //finally, the the rodrigues back
        Rodrigues ( R,rotation );

    }

    /**Static version (all in one)
     */
    Board BoardDetector::detect ( const cv::Mat &Image, const BoardConfiguration &bc,const CameraParameters &cp, float markerSizeMeters ) {
        BoardDetector BD;
        BD.setParams ( bc,cp,markerSizeMeters );
        BD.detect ( Image );
        return BD.getDetectedBoard();
    }
};
<|endoftext|>


<commit_before>/* netmsg.cpp
   Copyright (C) 2003-2005 Tommi Maekitalo

This file is part of cxxtools.

Cxxtools is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

Cxxtools is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Cxxtools; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA  02111-1307  USA

************************************************************************

   usage: sender:   netmsg [-h host] [-p port] {message}
          receiver: netmsg -r [-l length] [-c]

*/

#include "cxxtools/udp.h"
#include "cxxtools/dynbuffer.h"
#include "cxxtools/arg.h"

void usage(const char* progname)
{
  std::cerr << "usage: " << progname << " [-h host] [-p port] {message}\n"
               "       " << progname << " -r [-h host] [-l length] [-c]" << std::endl;
}

int main(int argc, char* argv[])
{
  try
  {
    cxxtools::Arg<bool> help(argc, argv, '?');
    if (help)
    {
      usage(argv[0]);
      return 0;
    }

    cxxtools::Arg<bool> receive(argc, argv, 'l');
    cxxtools::Arg<unsigned short> port(argc, argv, 'p', 1234);

    if (receive)
    {
      cxxtools::Arg<unsigned> size(argc, argv, 's', 1024);
      cxxtools::Arg<const char*> host(argc, argv, 'h', "0.0.0.0");
      cxxtools::Arg<bool> continuous(argc, argv, 'c');
      cxxtools::Arg<bool> nonewline(argc, argv, 'n');

      if (argc > 1)
      {
        usage(argv[0]);
        return -1;
      }

      cxxtools::net::UdpReceiver receiver(host, port);
      cxxtools::Dynbuffer<char> buffer(size);

      std::cout << "waiting for messages on port " << port << std::endl;
      do
      {
        cxxtools::net::UdpReceiver::size_type s = receiver.recv(buffer.data(), size);
        std::cout << std::string(buffer.data(), s);
        if (!nonewline)
          std::cout << std::endl;
        else
          std::cout.flush();
      } while (continuous);
    }
    else
    {
      cxxtools::Arg<const char*> host(argc, argv, 'h', "127.0.0.1");

      if (argc == 1)
      {
        usage(argv[0]);
        return -1;
      }

      cxxtools::net::UdpSender sender(host, port);
      for (int a = 1; a < argc; ++a)
      {
        std::cout << "send message \"" << argv[a] << "\" to " << host << ':' << port << std::endl;
        sender.send(argv[a]);
      }
    }
  }
  catch (const std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }
}
<commit_msg>fixed usage-message<commit_after>/* netmsg.cpp
   Copyright (C) 2003-2005 Tommi Maekitalo

This file is part of cxxtools.

Cxxtools is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.

Cxxtools is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with Cxxtools; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA  02111-1307  USA

************************************************************************

   usage: sender:   netmsg [-h host] [-p port] {message}
          receiver: netmsg -r [-l length] [-c]

*/

#include "cxxtools/udp.h"
#include "cxxtools/dynbuffer.h"
#include "cxxtools/arg.h"

void usage(const char* progname)
{
  std::cerr << "usage: " << progname << " [-h host] [-p port] {message}\n"
               "       " << progname << " -l [-h host] [-p port] [-s size] [-c] [-n]" << std::endl;
}

int main(int argc, char* argv[])
{
  try
  {
    cxxtools::Arg<bool> help(argc, argv, '?');
    if (help)
    {
      usage(argv[0]);
      return 0;
    }

    cxxtools::Arg<bool> receive(argc, argv, 'l');
    cxxtools::Arg<unsigned short> port(argc, argv, 'p', 1234);

    if (receive)
    {
      cxxtools::Arg<unsigned> size(argc, argv, 's', 1024);
      cxxtools::Arg<const char*> host(argc, argv, 'h', "0.0.0.0");
      cxxtools::Arg<bool> continuous(argc, argv, 'c');
      cxxtools::Arg<bool> nonewline(argc, argv, 'n');

      if (argc > 1)
      {
        usage(argv[0]);
        return -1;
      }

      cxxtools::net::UdpReceiver receiver(host, port);
      cxxtools::Dynbuffer<char> buffer(size);

      std::cout << "waiting for messages on port " << port << std::endl;
      do
      {
        cxxtools::net::UdpReceiver::size_type s = receiver.recv(buffer.data(), size);
        std::cout << std::string(buffer.data(), s);
        if (!nonewline)
          std::cout << std::endl;
        else
          std::cout.flush();
      } while (continuous);
    }
    else
    {
      cxxtools::Arg<const char*> host(argc, argv, 'h', "127.0.0.1");

      if (argc == 1)
      {
        usage(argv[0]);
        return -1;
      }

      cxxtools::net::UdpSender sender(host, port);
      for (int a = 1; a < argc; ++a)
      {
        std::cout << "send message \"" << argv[a] << "\" to " << host << ':' << port << std::endl;
        sender.send(argv[a]);
      }
    }
  }
  catch (const std::exception& e)
  {
    std::cerr << e.what() << std::endl;
  }
}
<|endoftext|>


<commit_before>#include "kwm.h"

extern AXUIElementRef focused_window_ref;
extern window_info focused_window;
extern bool toggle_tap;
extern bool enable_auto_raise;

static const CGKeyCode kVK_SPECIAL_Å = 0x21;
static const CGKeyCode kVK_SPECIAL_Ø = 0x29;
static const CGKeyCode kVK_SPECIAL_Æ = 0x27;

bool kwm_hotkey_commands(bool cmd_key, bool ctrl_key, bool alt_key, CGKeyCode keycode)
{
    if(cmd_key && alt_key && ctrl_key)
    {
        if(keycode == kVK_ANSI_T)
        {
            toggle_tap = !toggle_tap;
            std::cout << (toggle_tap ? "tap enabled" : "tap disabled") << std::endl;
            return true;
        }

        if(keycode == kVK_ANSI_R)
        {
            enable_auto_raise = !enable_auto_raise;
            std::cout << (enable_auto_raise ? "autoraise enabled" : "autoraise disabled") << std::endl;
            return true;
        }
    }

    return false;
}

bool system_hotkey_passthrough(bool cmd_key, bool ctrl_key, bool alt_key, CGKeyCode keycode)
{
    // Spotlight fix
    if (cmd_key && !ctrl_key && !alt_key)
    {
        if (keycode == kVK_Space)
        {
            toggle_tap = false;
            std::cout << "tap disabled" << std::endl;
            return true;
        }
        else if(keycode == kVK_Tab)
            return true;
    }

    return false;
}

bool custom_hotkey_commands(bool cmd_key, bool ctrl_key, bool alt_key, CGKeyCode keycode)
{
    if(cmd_key && alt_key && ctrl_key)
    {
        // Start Applications
        std::string sys_command = "";
        // New iterm2 Window
        if(keycode == kVK_ANSI_1)
            sys_command = "/Applications/iTerm.app/Contents/MacOS/iTerm2 --new-window &";
        // YTD - Media Player Controls
        else if(keycode == kVK_ANSI_Z)
            sys_command = "ytc prev";
        else if(keycode == kVK_ANSI_X)
            sys_command = "ytc play";
        else if(keycode == kVK_ANSI_C)
            sys_command = "ytc next";
        else if(keycode == kVK_ANSI_V)
            sys_command = "ytc stop";

        if(sys_command != "")
        {
            system(sys_command.c_str());
            return true;
        }

        // Toggle Screen Layout
        if(keycode == kVK_Space)
        {
            apply_layout_for_display(get_display_of_window(&focused_window)->id);
            return true;
        }

        // Window Layout
        window_layout layout;
        layout.name = "invalid";
        if(keycode == kVK_ANSI_M)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "fullscreen");
        else if(keycode == kVK_LeftArrow)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "left vertical split");
        else if(keycode == kVK_RightArrow)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "right vertical split");
        else if(keycode == kVK_UpArrow)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "upper horizontal split");
        else if(keycode == kVK_DownArrow)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "lower horizontal split");
        else if(keycode == kVK_ANSI_P)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "upper left split");
        else if(keycode == kVK_SPECIAL_Ø)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "lower left split");
        else if(keycode == kVK_SPECIAL_Å)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "upper right split");
        else if(keycode == kVK_SPECIAL_Æ)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "lower right split");

        if(layout.name != "invalid")
        {
            set_window_dimensions(focused_window_ref, &focused_window, layout.x, layout.y, layout.width, layout.height);
            return true;
        }

        // Window Resize
        if(keycode == kVK_ANSI_H)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y,
                    focused_window.width - 10,
                    focused_window.height);
        else if(keycode == kVK_ANSI_J)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y,
                    focused_window.width,
                    focused_window.height + 10);
        else if(keycode == kVK_ANSI_K)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y,
                    focused_window.width,
                    focused_window.height - 10);
        else if(keycode == kVK_ANSI_L)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y,
                    focused_window.width + 10,
                    focused_window.height);
    }

    if(cmd_key && ctrl_key && !alt_key)
    {
        // Multiple Screens
        if(keycode == kVK_ANSI_P || keycode == kVK_ANSI_N)
        {
            if(keycode == kVK_ANSI_P)
                cycle_focused_window_display(-1);

            if(keycode == kVK_ANSI_N)
                cycle_focused_window_display(1);

            return true;
        }

        // Move Window
        if(keycode == kVK_ANSI_H)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x - 10,
                    focused_window.y,
                    focused_window.width,
                    focused_window.height);
        else if(keycode == kVK_ANSI_J)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y + 10,
                    focused_window.width,
                    focused_window.height);
        else if(keycode == kVK_ANSI_K)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y - 10,
                    focused_window.width,
                    focused_window.height);
        else if(keycode == kVK_ANSI_L)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x + 10,
                    focused_window.y,
                    focused_window.width,
                    focused_window.height);
    }

    if(cmd_key && alt_key && !ctrl_key)
    {
        // Cycle focused window layout
        if(keycode == kVK_ANSI_P || keycode == kVK_ANSI_N)
        {
            if(keycode == kVK_ANSI_P)
                cycle_focused_window_layout(get_display_of_window(&focused_window)->id, -1);

            if(keycode == kVK_ANSI_N)
                cycle_focused_window_layout(get_display_of_window(&focused_window)->id, 1);

            return true;
        }

        // Cycle window inside focused layout
        if(keycode == kVK_Tab)
        {
            cycle_window_inside_layout(get_display_of_window(&focused_window)->id);
            return true;
        }

        // Focus a window
        if(keycode == kVK_ANSI_H || keycode == kVK_ANSI_L)
        {
            if(keycode == kVK_ANSI_H)
                shift_window_focus("prev");
            else if(keycode == kVK_ANSI_L)
                shift_window_focus("next");

            return true;
        }
    }

    return false;
}
<commit_msg>disabled retarded system hotkeys<commit_after>#include "kwm.h"

extern AXUIElementRef focused_window_ref;
extern window_info focused_window;
extern bool toggle_tap;
extern bool enable_auto_raise;

static const CGKeyCode kVK_SPECIAL_Å = 0x21;
static const CGKeyCode kVK_SPECIAL_Ø = 0x29;
static const CGKeyCode kVK_SPECIAL_Æ = 0x27;

bool kwm_hotkey_commands(bool cmd_key, bool ctrl_key, bool alt_key, CGKeyCode keycode)
{
    if(cmd_key && alt_key && ctrl_key)
    {
        if(keycode == kVK_ANSI_T)
        {
            toggle_tap = !toggle_tap;
            std::cout << (toggle_tap ? "tap enabled" : "tap disabled") << std::endl;
            return true;
        }

        if(keycode == kVK_ANSI_R)
        {
            enable_auto_raise = !enable_auto_raise;
            std::cout << (enable_auto_raise ? "autoraise enabled" : "autoraise disabled") << std::endl;
            return true;
        }
    }

    return false;
}

bool system_hotkey_passthrough(bool cmd_key, bool ctrl_key, bool alt_key, CGKeyCode keycode)
{
    // Spotlight fix
    if (cmd_key && !ctrl_key && !alt_key)
    {
        if (keycode == kVK_Space)
        {
            toggle_tap = false;
            std::cout << "tap disabled" << std::endl;
            return true;
        }
        else if(keycode == kVK_Tab)
            return true;
    }

    return false;
}

bool custom_hotkey_commands(bool cmd_key, bool ctrl_key, bool alt_key, CGKeyCode keycode)
{
    if(cmd_key && alt_key && ctrl_key)
    {
        // Start Applications
        std::string sys_command = "";
        // New iterm2 Window
        if(keycode == kVK_ANSI_1)
            sys_command = "/Applications/iTerm.app/Contents/MacOS/iTerm2 --new-window &";
        // YTD - Media Player Controls
        else if(keycode == kVK_ANSI_Z)
            sys_command = "ytc prev";
        else if(keycode == kVK_ANSI_X)
            sys_command = "ytc play";
        else if(keycode == kVK_ANSI_C)
            sys_command = "ytc next";
        else if(keycode == kVK_ANSI_V)
            sys_command = "ytc stop";

        if(sys_command != "")
        {
            system(sys_command.c_str());
            return true;
        }

        // Toggle Screen Layout
        if(keycode == kVK_Space)
        {
            apply_layout_for_display(get_display_of_window(&focused_window)->id);
            return true;
        }

        // Window Layout
        window_layout layout;
        layout.name = "invalid";
        if(keycode == kVK_ANSI_M)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "fullscreen");
        else if(keycode == kVK_LeftArrow)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "left vertical split");
        else if(keycode == kVK_RightArrow)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "right vertical split");
        else if(keycode == kVK_UpArrow)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "upper horizontal split");
        else if(keycode == kVK_DownArrow)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "lower horizontal split");
        else if(keycode == kVK_ANSI_P)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "upper left split");
        else if(keycode == kVK_SPECIAL_Ø)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "lower left split");
        else if(keycode == kVK_SPECIAL_Å)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "upper right split");
        else if(keycode == kVK_SPECIAL_Æ)
            layout = get_window_layout_for_screen(get_display_of_window(&focused_window)->id, "lower right split");

        if(layout.name != "invalid")
        {
            set_window_dimensions(focused_window_ref, &focused_window, layout.x, layout.y, layout.width, layout.height);
            return true;
        }

        // Window Resize
        if(keycode == kVK_ANSI_H)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y,
                    focused_window.width - 10,
                    focused_window.height);
        else if(keycode == kVK_ANSI_J)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y,
                    focused_window.width,
                    focused_window.height + 10);
        else if(keycode == kVK_ANSI_K)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y,
                    focused_window.width,
                    focused_window.height - 10);
        else if(keycode == kVK_ANSI_L)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y,
                    focused_window.width + 10,
                    focused_window.height);
    }

    if(cmd_key && ctrl_key && !alt_key)
    {
        // Multiple Screens
        if(keycode == kVK_ANSI_P || keycode == kVK_ANSI_N)
        {
            if(keycode == kVK_ANSI_P)
                cycle_focused_window_display(-1);

            if(keycode == kVK_ANSI_N)
                cycle_focused_window_display(1);

            return true;
        }

        // Move Window
        if(keycode == kVK_ANSI_H)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x - 10,
                    focused_window.y,
                    focused_window.width,
                    focused_window.height);
        else if(keycode == kVK_ANSI_J)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y + 10,
                    focused_window.width,
                    focused_window.height);
        else if(keycode == kVK_ANSI_K)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x,
                    focused_window.y - 10,
                    focused_window.width,
                    focused_window.height);
        else if(keycode == kVK_ANSI_L)
            set_window_dimensions(focused_window_ref,
                    &focused_window,
                    focused_window.x + 10,
                    focused_window.y,
                    focused_window.width,
                    focused_window.height);
    }

    if(cmd_key && alt_key && !ctrl_key)
    {
        // Cycle focused window layout
        if(keycode == kVK_ANSI_P || keycode == kVK_ANSI_N)
        {
            if(keycode == kVK_ANSI_P)
                cycle_focused_window_layout(get_display_of_window(&focused_window)->id, -1);

            if(keycode == kVK_ANSI_N)
                cycle_focused_window_layout(get_display_of_window(&focused_window)->id, 1);

            return true;
        }

        // Cycle window inside focused layout
        if(keycode == kVK_Tab)
        {
            cycle_window_inside_layout(get_display_of_window(&focused_window)->id);
            return true;
        }

        // Focus a window
        if(keycode == kVK_ANSI_H || keycode == kVK_ANSI_L)
        {
            if(keycode == kVK_ANSI_H)
                shift_window_focus("prev");
            else if(keycode == kVK_ANSI_L)
                shift_window_focus("next");

            return true;
        }
    }

    if(cmd_key && !alt_key && !ctrl_key)
    {
        // disable retarded hotkey for minimizing an application
        if(keycode == kVK_ANSI_M)
            return true;
        // disable retarded hotkey for hiding an application
        else if(keycode == kVK_ANSI_H)
            return true;
    }

    return false;
}
<|endoftext|>


<commit_before>#include "kmeans.h"
#include <iostream>
#include <cassert>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <limits>
using namespace std;

namespace med {

Kmeans::Kmeans(const DistFunc &distFunc) :
		distFunc_(distFunc), debug_(false) {
}

std::map<int, Cluster> Kmeans::process(const std::vector<Vector>& points,
		int groups, float epsilon, int iterations) const {
	assert(groups > 0);

	vector<KmeansCluster> clusters;
	auto centroids = findRandomCentroids(points, groups);
	for (auto& point : centroids) {
		KmeansCluster cluster;
		cluster.centroid_ = point;
		clusters.push_back(cluster);
	}

	if (debug_) {
		cout << "Step 1: centroids" << endl;
		for (auto &cluster : clusters) {
			cout << vectorToString(cluster.centroid_) << endl;
		}
	}

	assignPoints(clusters, points);

	double error = numeric_limits<double>::max();
	for (int iteration = 0; iteration != iterations; ++iteration) {
		recalculateCentroids(clusters);
		if (!reassignPoints(clusters)) {
			if (debug_) {
				cout << "No reassign in " << iteration << " iteration so stop."
						<< endl;
			}
			break;
		}
		double qError = error;
		error = calculateQuantizationError(clusters);
		if (error < 0) {
			if (debug_) {
				cout << "Worse result, so don't calc new epsilon error."
						<< endl;
			}
		} else {
			qError = (qError - error) / error;
		}

		if (debug_) {
			cout << "qError (epsilon): " << qError << " in " << iteration
					<< " iteration." << endl;
		}

		if (qError < epsilon) {
			break;
		}
	}

	map<int, Cluster> result;
	int id = 1;
	for (auto& cluster : clusters) {
		result[id++] = cluster.cluster_;
	}

	return result;
}

vector<Vector> Kmeans::findRandomCentroids(const vector<Vector>& points,
		int groups) const {
	// TODO optimize it
	srand(unsigned(time(0)));
	vector<int> randomInc;
	for (int i = 0; i < points.size(); ++i) {
		randomInc.push_back(i);
	}

	random_shuffle(randomInc.begin(), randomInc.end());

	vector<Vector> centroids;
	for (int i = 0; i < groups; ++i) {
		centroids.push_back(points[randomInc[i]]);
	}

	return centroids;
}

void Kmeans::assignPoints(vector<KmeansCluster>& clusters,
		const vector<Vector>& points) const {
	for (auto& point : points) {
		double minDistance = numeric_limits<double>::max();
		int clu = -1;
		for (int c = 0; c < clusters.size(); ++c) {
			double distance = distFunc_(clusters[c].centroid_, point, true);
			if (distance < minDistance) {
				minDistance = distance;
				clu = c;
			}
		}
		assert(clu != -1);
		clusters[clu].cluster_.push_back(point);
	}
}

void Kmeans::recalculateCentroids(std::vector<KmeansCluster>& clusters) const {
	for (auto& cluster : clusters) {
		Vector newCentroid;
		for (auto& point : cluster.cluster_) {
			if (newCentroid.size() == 0) {
				for (auto& p : point) {
					newCentroid.push_back(0);
				}
			}
			for (int i = 0; i < point.size(); ++i) {
				newCentroid[i] += point[i];
			}
		}
		int clusterSize = cluster.cluster_.size();
		if (clusterSize > 0) {
			for (int i = 0; i < cluster.centroid_.size(); ++i) {
				cluster.centroid_[i] = newCentroid[i] / clusterSize;
			}
		}

		if (debug_) {
			cout << "Recalculated centroid: "
					<< vectorToString(cluster.centroid_) << endl;
		}
	}

	if (debug_) {
		cout << endl;
	}
}

bool Kmeans::reassignPoints(vector<KmeansCluster>& clusters) const {
	vector<Vector> points;
	for (auto& cluster : clusters) {
		points.insert(points.end(), cluster.cluster_.begin(),
				cluster.cluster_.end());
		cluster.cluster_.clear();
	}
	assignPoints(clusters, points);
	// TODO think about - different approach
	return true;
}

double Kmeans::calculateQuantizationError(
		const vector<KmeansCluster>& clusters) const {
	int points = 0;
	double result = 0;
	for (auto& cluster : clusters) {
		points += cluster.cluster_.size();
		for (auto& point : cluster.cluster_) {
			result += distFunc_(point, cluster.centroid_, true);
		}
	}
	result /= points;
	if (debug_) {
		cout << "Quantization error=" << result << endl;
	}

	return result;
}

}
<commit_msg>Info about kmeans algorithm ending.<commit_after>#include "kmeans.h"
#include <iostream>
#include <cassert>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <limits>
using namespace std;

namespace med {

Kmeans::Kmeans(const DistFunc &distFunc) :
		distFunc_(distFunc), debug_(false) {
}

std::map<int, Cluster> Kmeans::process(const std::vector<Vector>& points,
		int groups, float epsilon, int iterations) const {
	assert(groups > 0);

	vector<KmeansCluster> clusters;
	auto centroids = findRandomCentroids(points, groups);
	for (auto& point : centroids) {
		KmeansCluster cluster;
		cluster.centroid_ = point;
		clusters.push_back(cluster);
	}

	if (debug_) {
		cout << "Step 1: centroids" << endl;
		for (auto &cluster : clusters) {
			cout << vectorToString(cluster.centroid_) << endl;
		}
	}

	assignPoints(clusters, points);

	double error = numeric_limits<double>::max();
	int iteration;
	for (iteration = 0; iteration != iterations; ++iteration) {
		recalculateCentroids(clusters);
		if (!reassignPoints(clusters)) {
			if (debug_) {
				cout << "No reassign in " << iteration << " iteration so stop."
						<< endl;
			}
			break;
		}
		double qError = error;
		error = calculateQuantizationError(clusters);
		if (error < 0) {
			if (debug_) {
				cout << "Worse result, so don't calc new epsilon error."
						<< endl;
			}
		} else {
			qError = (qError - error) / error;
		}

		if (debug_) {
			cout << "qError (epsilon): " << qError << " in " << iteration
					<< " iteration." << endl;
		}

		if (qError < epsilon) {
			cout << "Finish by qError < epsilon (" << qError << " < " << epsilon
					<< ")" << endl;
			break;
		}
	}
	cout << "Finished after " << iteration << " of " << iterations
			<< " with epsilonError=" << error << endl;

	map<int, Cluster> result;
	int id = 1;
	for (auto& cluster : clusters) {
		result[id++] = cluster.cluster_;
	}

	return result;
}

vector<Vector> Kmeans::findRandomCentroids(const vector<Vector>& points,
		int groups) const {
	// TODO optimize it
	srand(unsigned(time(0)));
	vector<int> randomInc;
	for (int i = 0; i < points.size(); ++i) {
		randomInc.push_back(i);
	}

	random_shuffle(randomInc.begin(), randomInc.end());

	vector<Vector> centroids;
	for (int i = 0; i < groups; ++i) {
		centroids.push_back(points[randomInc[i]]);
	}

	return centroids;
}

void Kmeans::assignPoints(vector<KmeansCluster>& clusters,
		const vector<Vector>& points) const {
	for (auto& point : points) {
		double minDistance = numeric_limits<double>::max();
		int clu = -1;
		for (int c = 0; c < clusters.size(); ++c) {
			double distance = distFunc_(clusters[c].centroid_, point, true);
			if (distance < minDistance) {
				minDistance = distance;
				clu = c;
			}
		}
		assert(clu != -1);
		clusters[clu].cluster_.push_back(point);
	}
}

void Kmeans::recalculateCentroids(std::vector<KmeansCluster>& clusters) const {
	for (auto& cluster : clusters) {
		Vector newCentroid;
		for (auto& point : cluster.cluster_) {
			if (newCentroid.size() == 0) {
				for (auto& p : point) {
					newCentroid.push_back(0);
				}
			}
			for (int i = 0; i < point.size(); ++i) {
				newCentroid[i] += point[i];
			}
		}
		int clusterSize = cluster.cluster_.size();
		if (clusterSize > 0) {
			for (int i = 0; i < cluster.centroid_.size(); ++i) {
				cluster.centroid_[i] = newCentroid[i] / clusterSize;
			}
		}

		if (debug_) {
			cout << "Recalculated centroid: "
					<< vectorToString(cluster.centroid_) << endl;
		}
	}

	if (debug_) {
		cout << endl;
	}
}

bool Kmeans::reassignPoints(vector<KmeansCluster>& clusters) const {
	vector<Vector> points;
	for (auto& cluster : clusters) {
		points.insert(points.end(), cluster.cluster_.begin(),
				cluster.cluster_.end());
		cluster.cluster_.clear();
	}
	assignPoints(clusters, points);
	// TODO think about - different approach
	return true;
}

double Kmeans::calculateQuantizationError(
		const vector<KmeansCluster>& clusters) const {
	int points = 0;
	double result = 0;
	for (auto& cluster : clusters) {
		points += cluster.cluster_.size();
		for (auto& point : cluster.cluster_) {
			result += distFunc_(point, cluster.centroid_, true);
		}
	}
	result /= points;
	if (debug_) {
		cout << "Quantization error=" << result << endl;
	}

	return result;
}

}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2014, webvariants GmbH, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @author: Thomas Krause (thomas.krause@webvariants.de)
 */

#include "iocontroller/IOController.h"

//Constructor
Susi::IOController::IOController() {
	// use current as base path
	this->base_path = Poco::Path(Poco::Path::current());
}

Susi::IOController::IOController(std::string base_path) {
	// init with base path
	this->base_path = Poco::Path(base_path);
}

 //high level
std::size_t Susi::IOController::writeFile(std::string filename,char* ptr, std::size_t len) {

	Poco::Path dir = this->getAbsDirFromString(filename);

	if(this->checkDir(dir)) {
		// write File
		std::ofstream s((char*)filename.c_str());
		s<<ptr;
		s.close();

		return len;
	} else {
		throw std::runtime_error{"WriteFile: Dir don't exists!"+filename};
	}
}

std::size_t Susi::IOController::writeFile(std::string filename,std::string content) {
	return this->writeFile(filename, (char*)content.c_str(), content.size());
}

std::string Susi::IOController::readFile(std::string filename) {

	if(this->checkFile(this->getAbsPathFromString(filename))) {
		std::string result = "";
		char * buffer;
		int length = 0;
		std::ifstream s((char*)filename.c_str());

		if(s) {
			// get length of file:
	    	s.seekg (0, s.end);
			length = s.tellg();
		    s.seekg (0, s.beg);

	    	buffer = new char [length];
		}

		// read data as a block:
	    s.read(buffer,length);

	    if (!s) std::cout << "error: only " << s.gcount() << " could be read";

	    s.close();

	    result += std::string(buffer,length);

	    delete[] buffer;

	    return result;
	} else {
		throw std::runtime_error{"ReadFile: File don't exists!"};
	}
}

bool Susi::IOController::movePath(std::string source_path, std::string dest_path) {
	Poco::File sf(this->getAbsPathFromString(source_path));
	Poco::Path dp = this->getAbsPathFromString(dest_path);

	if(sf.exists()) {
		sf.moveTo(dp.toString());
		return true;
	} else {
		throw std::runtime_error{"movePath: SOURCE_PATH don't exist!"};
	}
}

bool Susi::IOController::copyPath(std::string source_path, std::string dest_path) {
	Poco::File sf(this->getAbsPathFromString(source_path));
	Poco::Path dp = this->getAbsPathFromString(dest_path);

	if(sf.exists()) {
		sf.copyTo(dp.toString());
		return true;
	} else {
		throw std::runtime_error{"copyPath: SOURCE_PATH don't exist!"};
	}
}

bool Susi::IOController::deletePath(std::string path) {

	Poco::File f(this->getAbsPathFromString(path));

	if(f.exists()) {
		if(f.isFile() || f.isDirectory()) {
			if(f.isFile()) {
				f.remove(false);
				return true;
			} else {
				f.remove(true); // deletes recursive
				return true;
			}
		} else {
			throw std::runtime_error{"Delete: PATH is no FILE or DIR! (maybe PATH is LINK or DEVICE)"};
		}
	} else {
		return false;
	}
}

// low level
bool Susi::IOController::makeDir(std::string dir) {

	Poco::Path p(true);

	//std::cout<<p.isAbsolute()<<std::endl;

	p.append(this->base_path);
	p.append(dir);

	/*
	if(!p.isAbsolute()) {
		p.makeAbsolute(this->base_path);
		std::cout<<"APPENDED:"<<p.toString()<<std::endl;
	} else {
		std::cout<<"ABSOLUT:"<<p.toString()<<std::endl;
	}
*/
	//std::cout<<"APPENDED:"<<p.toString()<<std::endl;
	//std::cout<<"FILENAME:"<<p.getFileName()<<std::endl;

	Poco::File f(p);
	f.createDirectories();

	/*
	Poco::Path p(Poco::Path::current());
	Poco::File f;

	p.pushDirectory("Thomas");
	p.pushDirectory("Test");

	//p.setFileName("test.dat");

	f = Poco::File(p);
	f.createDirectories();

	std::string s = p.toString();

	std::cout<<s<<" "<<p.depth()<<std::endl;

	Poco::Path p2("./");

	std::string s2 = p2.toString();

	std::cout<<s2<<" "<<p2.depth()<<std::endl;

	std::cout
		<< "cwd: "  << Poco::Path::current() << std::endl
		<< "home: " << Poco::Path::home() << std::endl
		<< "temp: " << Poco::Path::temp() << std::endl
		<< "null: " << Poco::Path::null() << std::endl;
*/
	return true;
}

bool Susi::IOController::setExecutable(std::string path, bool isExecutable) {
	Poco::File f(this->getAbsPathFromString(path));

	if(f.exists()) {
		f.setExecutable(isExecutable);
		return true;
	} else {
		throw std::runtime_error{"setExecutable: PATH is no FILE or DIR!"};
	}
}

bool Susi::IOController::getExecutable(std::string path) {
	Poco::File f(this->getAbsPathFromString(path));

	if(f.exists()) {
		return f.canExecute();
	} else {
		throw std::runtime_error{"getExecutable: PATH is no FILE or DIR!"};
	}
}

// helper function
Poco::Path Susi::IOController::getAbsPathFromString(std::string path) {
	Poco::Path p(path);
	if(p.isRelative())
		p.makeAbsolute(this->base_path);
	return p;
}

Poco::Path Susi::IOController::getAbsDirFromString(std::string path) {
	Poco::Path p = this->getAbsPathFromString(path);
	p.makeParent();
	return p;
}

bool Susi::IOController::checkDir(Poco::Path dir) {

	Poco::File f(dir);

	if(f.exists()) {
		if(f.isDirectory()) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

bool Susi::IOController::checkFile(Poco::Path dir) {
	Poco::File f(dir);

	if(f.exists()) {
		if(f.isFile()) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}<commit_msg>[IOController] removed unused stuff;<commit_after>/*
 * Copyright (c) 2014, webvariants GmbH, http://www.webvariants.de
 *
 * This file is released under the terms of the MIT license. You can find the
 * complete text in the attached LICENSE file or online at:
 *
 * http://www.opensource.org/licenses/mit-license.php
 *
 * @author: Thomas Krause (thomas.krause@webvariants.de)
 */

#include "iocontroller/IOController.h"

//Constructor
Susi::IOController::IOController() {
	// use current as base path
	this->base_path = Poco::Path(Poco::Path::current());
}

Susi::IOController::IOController(std::string base_path) {
	// init with base path
	this->base_path = Poco::Path(base_path);
}

 //high level
std::size_t Susi::IOController::writeFile(std::string filename,char* ptr, std::size_t len) {

	Poco::Path dir = this->getAbsDirFromString(filename);

	if(this->checkDir(dir)) {
		// write File
		std::ofstream s((char*)filename.c_str());
		s<<ptr;
		s.close();

		return len;
	} else {
		throw std::runtime_error{"WriteFile: Dir don't exists!"+filename};
	}
}

std::size_t Susi::IOController::writeFile(std::string filename,std::string content) {
	return this->writeFile(filename, (char*)content.c_str(), content.size());
}

std::string Susi::IOController::readFile(std::string filename) {

	if(this->checkFile(this->getAbsPathFromString(filename))) {
		std::string result = "";
		char * buffer;
		int length = 0;
		std::ifstream s((char*)filename.c_str());

		if(s) {
			// get length of file:
	    	s.seekg (0, s.end);
			length = s.tellg();
		    s.seekg (0, s.beg);

	    	buffer = new char [length];
		}

		// read data as a block:
	    s.read(buffer,length);

	    if (!s) std::cout << "error: only " << s.gcount() << " could be read";

	    s.close();

	    result += std::string(buffer,length);

	    delete[] buffer;

	    return result;
	} else {
		throw std::runtime_error{"ReadFile: File don't exists!"};
	}
}

bool Susi::IOController::movePath(std::string source_path, std::string dest_path) {
	Poco::File sf(this->getAbsPathFromString(source_path));
	Poco::Path dp = this->getAbsPathFromString(dest_path);

	if(sf.exists()) {
		sf.moveTo(dp.toString());
		return true;
	} else {
		throw std::runtime_error{"movePath: SOURCE_PATH don't exist!"};
	}
}

bool Susi::IOController::copyPath(std::string source_path, std::string dest_path) {
	Poco::File sf(this->getAbsPathFromString(source_path));
	Poco::Path dp = this->getAbsPathFromString(dest_path);

	if(sf.exists()) {
		sf.copyTo(dp.toString());
		return true;
	} else {
		throw std::runtime_error{"copyPath: SOURCE_PATH don't exist!"};
	}
}

bool Susi::IOController::deletePath(std::string path) {

	Poco::File f(this->getAbsPathFromString(path));

	if(f.exists()) {
		if(f.isFile() || f.isDirectory()) {
			if(f.isFile()) {
				f.remove(false);
				return true;
			} else {
				f.remove(true); // deletes recursive
				return true;
			}
		} else {
			throw std::runtime_error{"Delete: PATH is no FILE or DIR! (maybe PATH is LINK or DEVICE)"};
		}
	} else {
		return false;
	}
}

// low level
bool Susi::IOController::makeDir(std::string dir) {

	Poco::Path p(true);

	p.append(this->base_path);
	p.append(dir);

	Poco::File f(p);
	f.createDirectories();

	return true;
}

bool Susi::IOController::setExecutable(std::string path, bool isExecutable) {
	Poco::File f(this->getAbsPathFromString(path));

	if(f.exists()) {
		f.setExecutable(isExecutable);
		return true;
	} else {
		throw std::runtime_error{"setExecutable: PATH is no FILE or DIR!"};
	}
}

bool Susi::IOController::getExecutable(std::string path) {
	Poco::File f(this->getAbsPathFromString(path));

	if(f.exists()) {
		return f.canExecute();
	} else {
		throw std::runtime_error{"getExecutable: PATH is no FILE or DIR!"};
	}
}

// helper function
Poco::Path Susi::IOController::getAbsPathFromString(std::string path) {
	Poco::Path p(path);
	if(p.isRelative())
		p.makeAbsolute(this->base_path);
	return p;
}

Poco::Path Susi::IOController::getAbsDirFromString(std::string path) {
	Poco::Path p = this->getAbsPathFromString(path);
	p.makeParent();
	return p;
}

bool Susi::IOController::checkDir(Poco::Path dir) {

	Poco::File f(dir);

	if(f.exists()) {
		if(f.isDirectory()) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}

bool Susi::IOController::checkFile(Poco::Path dir) {
	Poco::File f(dir);

	if(f.exists()) {
		if(f.isFile()) {
			return true;
		} else {
			return false;
		}
	} else {
		return false;
	}
}<|endoftext|>