Line Code
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
// -*- C++ -*-
//
// Package:     Core
// Class  :     FWInteractionList
//
// Implementation:
//     [Notes on implementation]
//
// Original Author:  Alja Mrak-Tadel
//         Created:  Mon Apr 19 12:48:18 CEST 2010
//

// user include files
#include <cassert>
#include "TEveCompound.h"
#include "TEveManager.h"
#include "TEveSelection.h"

#include "Fireworks/Core/interface/FWInteractionList.h"
#include "Fireworks/Core/interface/FWEventItem.h"
#include "Fireworks/Core/interface/FWModelIdFromEveSelector.h"
#include "Fireworks/Core/interface/FWModelId.h"

//
// constants, enums and typedefs
//

//
// static data member definitions
//

//
// constructors and destructor
//
FWInteractionList::FWInteractionList(const FWEventItem* item) : m_item(item) {}

// FWInteractionList::FWInteractionList(const FWInteractionList& rhs)
// {
//    // do actual copying here;
// }

FWInteractionList::~FWInteractionList() {
  for (std::vector<TEveCompound*>::iterator i = m_compounds.begin(); i != m_compounds.end(); ++i) {
    // Interaction are created only in the standard use case, where user data is FWFromEveSelectorBase.
    // This is defined with return value of virtual function FWPRoxyBuilderBase::willHandleInteraction().

    if ((*i)->GetUserData())
      delete reinterpret_cast<FWFromEveSelectorBase*>((*i)->GetUserData());

    (*i)->RemoveElements();
    (*i)->DecDenyDestroy();
  }
}

//
// member functions
//

/** This function is called from FWProxyBuilderBase::build() function (e.g. on next event).
    The PB build function creates TEveElement for each element of collection and calls
    this function to add the element to "master" element, which is a TEveCompound.
*/
void FWInteractionList::added(TEveElement* el, unsigned int idx) {
  // In the case a compound for the given index already exists, just add
  // the TEveElement to it, otherwise create a new one.
  if (idx < m_compounds.size()) {
    m_compounds[idx]->AddElement(el);
    return;
  }

  // Prepare name for the tooltip on mouseover in GL viewer.Value of
  // tooltip is TEveElement::fTitle
  std::string name = m_item->modelName(idx);
  if (m_item->haveInterestingValue())
    name += m_item->modelInterestingValueAsString(idx);

  TEveCompound* c = new TEveCompound(name.c_str(), name.c_str());
  c->EnableListElements(m_item->defaultDisplayProperties().isVisible());
  c->SetMainColor(m_item->defaultDisplayProperties().color());
  c->SetMainTransparency(m_item->defaultDisplayProperties().transparency());

  // Set flags to propagat attributes.
  c->CSCImplySelectAllChildren();
  c->CSCApplyMainColorToAllChildren();
  c->CSCApplyMainTransparencyToAllChildren();

  // TEveElement is auto-destroyed if is is not added to any parent. Alternative could
  // be to use increase/decrease reference count.
  c->IncDenyDestroy();
  //  FWModelIdFromEveSelector is needed for interaction from Eve to Fireworks.
  //  FWEveViewManager gets ROOT signals with selected objects (TEveCompound)
  //  then cals doSelect() on the compound's user data.
  c->SetUserData(new FWModelIdFromEveSelector(FWModelId(m_item, idx)));
  // Order does not matter. What is added to TEveCompound is not concern of interaction list.
  // Interaction list operates ony with the compound.
  m_compounds.push_back(c);
  m_compounds.back()->AddElement(el);
  // printf("%s[%d] FWInteractionList::added has childern %d\n",m_item->name().c_str(), idx,  m_compounds[idx]->NumChildren());
}

/** This method is called from FWEveViewManager::modelChanges(), which
     has modelChanges callback same as all other view maangers.
*/
void FWInteractionList::modelChanges(const FWModelIds& iIds) {
  assert(m_compounds.size() >= m_item->size());

  for (std::set<FWModelId>::const_iterator it = iIds.begin(); it != iIds.end(); ++it) {
    const FWEventItem::ModelInfo& info = m_item->modelInfo(it->index());
    // std::cout <<" FWInteractionList::modelChanges  color "<< info.displayProperties().color()  << "(*it).index() " <<(*it).index() << "  " << m_item->name() <<std::endl;
    const FWDisplayProperties& p = info.displayProperties();
    TEveElement* comp = m_compounds[it->index()];
    comp->EnableListElements(p.isVisible(), p.isVisible());
    comp->SetMainColor(p.color());
    comp->SetMainTransparency(p.transparency());

    if (info.isSelected()) {
      if (comp->GetSelectedLevel() != 1)
        gEve->GetSelection()->AddElement(comp);
    } else {
      if (comp->GetSelectedLevel() == 1)
        gEve->GetSelection()->RemoveElement(comp);
    }
  }
}

/**
  This method is called from FWEveViewManager::itemChanged(), which is a callback of
  signal FWEventItem::itemChanged_.
*/
void FWInteractionList::itemChanged() {
  for (size_t i = 0, e = m_item->size(); i < e; ++i) {
    // Assert for sizes is not necessary, becuse it is already in a
    // proxy builder.
    TEveElement* comp = m_compounds[i];

    std::string name = m_item->modelName(i);
    if (m_item->haveInterestingValue())
      name += m_item->modelInterestingValueAsString(i);

    comp->SetElementTitle(name.c_str());

    const FWEventItem::ModelInfo& info = m_item->modelInfo(i);
    const FWDisplayProperties& p = info.displayProperties();

    if (p.isVisible() != comp->GetRnrSelf())
      comp->EnableListElements(p.isVisible(), p.isVisible());

    if (p.color() != comp->GetMainColor())
      comp->SetMainColor(p.color());

    if (p.transparency() != comp->GetMainTransparency())
      comp->SetMainTransparency(p.transparency());
  }
}