Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions core/gui/inc/TToggle.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,32 +44,36 @@ class TMethod;
#include "TMethod.h"
#endif

class TDataMember;

class TToggle: public TNamed {

private:
Bool_t fState; //Object's state - "a local copy"
Long_t fOnValue; //Value recognized as switched ON (Def=1)
Long_t fOffValue; //Value recognized as switched OFF(Def=0)
Longptr_t fValue; //Local copy of a value returned by called function
Bool_t fState = kFALSE; //Object's state - "a local copy"
Long_t fOnValue = 1; //Value recognized as switched ON (Def=1)
Long_t fOffValue = 0; //Value recognized as switched OFF(Def=0)
Longptr_t fValue = -1; //Local copy of a value returned by called function

protected:
Bool_t fInitialized; //True if either SetToggledObject or SetToggledVariable called - enables Toggle() method.
TObject *fObject; //The object this Toggle belongs to
TMethodCall *fGetter; //Method to Get a value of fObject;
TMethodCall *fSetter; //Method to Set a value of fObject;
Int_t fInitialized = 0; //0 - off, 1 - only object and member is set, 2 - also getters and setters for the object is set
TObject *fObject = nullptr; //The object this Toggle belongs to
TDataMember *fMember = nullptr; //Data member which will be toggled
TMethodCall *fGetter = nullptr; //Method to Get a value of fObject;
TMethodCall *fSetter = nullptr; //Method to Set a value of fObject;

Int_t *fTglVariable; //Alternatively: pointer to an integer value to be Toggled instead of TObjectl
Int_t *fTglVariable = nullptr; //Alternatively: pointer to an integer value to be Toggled instead of TObjectl

public:
TToggle();
virtual void SetToggledObject(TObject *obj, TMethod *anymethod);
virtual void SetToggledObject(TObject *obj, TDataMember *member);

// you just provide any method which has got an initialized pointer
// to TDataMember... The rest is done automatically...

virtual void SetToggledVariable(Int_t &var);

virtual Bool_t IsInitialized(){ return fInitialized; }
virtual Bool_t IsInitialized() { return fInitialized > 0; }

virtual Bool_t GetState();
virtual void SetState(Bool_t state);
Expand All @@ -83,8 +87,8 @@ class TToggle: public TNamed {
virtual Int_t GetValue() { return fValue; }
virtual void SetValue(Long_t val);

TMethodCall *GetGetter() const { return fGetter; }
TMethodCall *GetSetter() const { return fSetter; }
TMethodCall *GetGetter() const;
TMethodCall *GetSetter() const;

ClassDefOverride(TToggle,0) //Facility for toggling datamembers on/off
};
Expand Down
137 changes: 79 additions & 58 deletions core/gui/src/TToggle.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ automaticaly find a matching "get-method" by lookin for a method
with name GetXXX, IsXXX or HasXXX for given object.
*/

#include "TToggle.h"

#include "TMethod.h"
#include "TMethodCall.h"
#include "TToggle.h"
#include "TDataMember.h"

#include <cstdio>
Expand All @@ -40,15 +41,6 @@ with name GetXXX, IsXXX or HasXXX for given object.

TToggle::TToggle()
{
fState = kFALSE;
fValue = -1;
fOnValue = 1;
fOffValue = 0;
fInitialized = 0;
fObject = nullptr;
fGetter = nullptr;
fSetter = nullptr;
fTglVariable = nullptr;
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -57,8 +49,8 @@ TToggle::TToggle()

void TToggle::SetToggledVariable(Int_t &var)
{
fTglVariable=&var;
fValue=var;
fTglVariable = &var;
fValue = var;
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -67,9 +59,11 @@ void TToggle::SetToggledVariable(Int_t &var)

Bool_t TToggle::GetState()
{
if (fInitialized)
if (fGetter) fGetter->Execute(fObject, fValue);
return (fState = (fValue == fOnValue));
if (auto fget = GetGetter())
fget->Execute(fObject, fValue);

fState = (fValue == fOnValue);
return fState;
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -78,16 +72,7 @@ Bool_t TToggle::GetState()

void TToggle::SetState(Bool_t state)
{
if (fInitialized) {
char stringon[20];
char stringoff[20];
snprintf(stringon,sizeof(stringon),"%li",fOnValue);
snprintf(stringoff,sizeof(stringoff),"%li",fOffValue);

fSetter->Execute(fObject, state ? stringon:stringoff);
fState=state;
fValue= ( state ? fOnValue : fOffValue);
}
SetValue(state ? fOnValue : fOffValue);
}

////////////////////////////////////////////////////////////////////////////////
Expand All @@ -96,12 +81,10 @@ void TToggle::SetState(Bool_t state)

void TToggle::SetValue(Long_t val)
{
if (fInitialized) {
char stringval[20];
snprintf(stringval,sizeof(stringval),"%li",val);
fSetter->Execute(fObject, stringval);
fState=(val==fOnValue);
fValue= val;
if (auto fset = GetSetter()) {
fset->Execute(fObject, TString::Format("%li", val).Data());
fState = (val == fOnValue);
fValue = val;
}
}

Expand All @@ -110,43 +93,81 @@ void TToggle::SetValue(Long_t val)

void TToggle::Toggle()
{
if (fInitialized){
if (IsInitialized()) {
if (fTglVariable){
*fTglVariable = !(*fTglVariable);
fValue=(*fTglVariable);
fState=*fTglVariable;
fValue = (*fTglVariable);
fState = *fTglVariable;
}
if (fGetter && fSetter){
fGetter->Execute(fObject,fValue);
fValue=( (fValue==fOnValue) ? fOffValue:fOnValue);
fState=(!(fValue!=fOnValue));
char stringon[20];
snprintf(stringon,sizeof(stringon),"%zi",(size_t)fValue);
fSetter->Execute(fObject, stringon);
auto fget = GetGetter();
auto fset = GetSetter();
if (fget && fset) {
fget->Execute(fObject, fValue);
fValue = (fValue == fOnValue) ? fOffValue : fOnValue;
fState = (fValue == fOnValue);
fset->Execute(fObject, TString::Format("%zi", (size_t)fValue).Data());
}
}
}

////////////////////////////////////////////////////////////////////////////////
/// Initializes it to toggle an object's datamember using this object's
/// method.
/// Initializes it to toggle an object's datamember using this object's method.

void TToggle::SetToggledObject(TObject *obj, TMethod *anymethod)
{
fObject = obj;
Comment thread
linev marked this conversation as resolved.
TDataMember *m = anymethod->FindDataMember();
if (!m) {
// try to see if the TMethod has a getter associated via the *GETTER=
// comment string
if (anymethod->GetterMethod()) {
fGetter = anymethod->GetterMethod();
fSetter = anymethod->SetterMethod();
fInitialized = 1;
} else
Error("SetToggledObject", "cannot determine getter method for %s", anymethod->GetName());
} else {
fGetter = m->GetterMethod(obj->IsA());
fSetter = m->SetterMethod(obj->IsA());
fInitialized = 1;
TDataMember *member = anymethod->FindDataMember();
if (member)
TToggle::SetToggledObject(obj, member);
else if (!anymethod)
Error("SetToggledObject", "Method pointer not provided");
else if (!anymethod->GetterMethod())
Error("SetToggledObject", "cannot determine getter method for %s", anymethod->GetName());
else {
// try to see if the TMethod has a getter associated via the *GETTER= comment string
fObject = obj;
// TMethodCall pointer can be stored - it is not recerated
fGetter = anymethod->GetterMethod();
fSetter = anymethod->SetterMethod();
fInitialized = 2;
Comment thread
linev marked this conversation as resolved.
}
}

////////////////////////////////////////////////////////////////////////////////
/// Initializes it to toggle an object's datamember

void TToggle::SetToggledObject(TObject *obj, TDataMember *member)
{
fObject = obj;
fMember = member;
fInitialized = 1;

// one cannot remember TMethodCall pointers from TDataMember
// while they will be recreated any time they requested again
fGetter = nullptr;
fSetter = nullptr;
}


////////////////////////////////////////////////////////////////////////////////
/// return getter method
/// request new for the TDataMember while it can be recreated at any time

TMethodCall *TToggle::GetGetter() const
{
if ((fInitialized == 1) && fMember && fObject)
return const_cast<TDataMember *>(fMember)->GetterMethod(fObject->IsA());

return fGetter;
}

////////////////////////////////////////////////////////////////////////////////
/// return setter method
/// request new for the TDataMember while it can be recreated at any time

TMethodCall *TToggle::GetSetter() const
{
if ((fInitialized == 1) && fMember && fObject)
return const_cast<TDataMember *>(fMember)->SetterMethod(fObject->IsA());

return fSetter;
}
10 changes: 9 additions & 1 deletion core/meta/src/TDataMember.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@ but also in Dump() and Inspect() methods and by the THtml class.
#include "TList.h"
#include "TListOfDataMembers.h"
#include "TMethod.h"
#include "TMethodArg.h"
#include "TMethodCall.h"
#include "TRealData.h"
#include "TROOT.h"
Expand Down Expand Up @@ -727,9 +728,16 @@ void TDataMember::ExtractOptionsFromComment()
Fatal("TDataMember","Internal error, found \"SetMethod\" but not \"\\\"\" in %s.",GetTitle());
return;
}
// setter method may accept enum data type - therefore check if it exists at all
if (GetClass()->GetMethod(ptr1,"1"))
// FIXME: wrong in case called derives via multiple inheritance from this class
fValueSetter = new TMethodCall(GetClass(),ptr1,"1");
fValueSetter = new TMethodCall(GetClass(), ptr1, "1");
else if (auto method = IsEnum() ? GetClass()->GetMethodAny(ptr1) : nullptr) {
// if data member is enum, take setter and cast 1 to argument data type
auto arg = dynamic_cast<TMethodArg *>(method->GetListOfMethodArgs()->First());
auto sarg = TString::Format("(%s) 1", arg ? arg->GetFullTypeName() : "int");
fValueSetter = new TMethodCall(GetClass(), ptr1, sarg.Data());
Comment thread
linev marked this conversation as resolved.
}
}
}

Expand Down
26 changes: 10 additions & 16 deletions gui/gui/src/TRootContextMenu.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -308,20 +308,18 @@ void TRootContextMenu::CreateMenu(TObject *object)
TList *methodList = new TList;
object->IsA()->GetMenuItems(methodList);

TMethod *method;
TClass *classPtr = 0;
TClass *classPtr = nullptr;
TIter next(methodList);
Bool_t needSep = kFALSE;

while ((method = (TMethod*) next())) {
while (auto method = (TMethod*) next()) {
if (classPtr != method->GetClass()) {
needSep = kTRUE;
classPtr = method->GetClass();
}

TDataMember *m;
EMenuItemKind menuKind = method->IsMenuItem();
TGPopupMenu *currentMenu = 0;
TGPopupMenu *currentMenu = nullptr;
TString last_component;

switch (menuKind) {
Expand All @@ -335,12 +333,12 @@ void TRootContextMenu::CreateMenu(TObject *object)
AddEntrySorted(currentMenu,last_component.Length() ? last_component.Data() : method->GetName(), entry++, method,0,currentMenu != this);
break;
case kMenuSubMenu:
if ((m = method->FindDataMember())) {
if (auto member = method->FindDataMember()) {

// search for arguments to the MENU statement
currentMenu = FindHierarchy(method->GetCommentString(),last_component);

if (m->GetterMethod()) {
if (member->GetterMethod()) {
TGPopupMenu *r = new TGPopupMenu(gClient->GetDefaultRoot());
if (needSep && currentMenu == this) {
AddSeparator();
Expand All @@ -352,18 +350,14 @@ void TRootContextMenu::CreateMenu(TObject *object)
currentMenu->AddPopup(method->GetName(), r);
}
fTrash->Add(r);
TIter nxt(m->GetOptions());
TOptionListItem *it;
while ((it = (TOptionListItem*) nxt())) {
const char *name = it->fOptName;
Long_t val = it->fValue;

TIter nxt(member->GetOptions());
while (auto it = (TOptionListItem*) nxt()) {
TToggle *t = new TToggle;
t->SetToggledObject(object, method);
t->SetOnValue(val);
t->SetToggledObject(object, member);
t->SetOnValue(it->fValue);
fTrash->Add(t);

r->AddEntry(name, togglelist++, t);
r->AddEntry(it->fOptName, togglelist++, t);
if (t->GetState())
r->CheckEntry(togglelist-1);
}
Expand Down
16 changes: 6 additions & 10 deletions gui/qt6canvas/src/QRootContextMenu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -154,26 +154,22 @@ void QRootContextMenu::DisplayPopup(Int_t x, Int_t y)
addMenuAction(&menu, &map, method->GetName(), entry++, method);
break;
case kMenuSubMenu:
if (auto m = method->FindDataMember()) {
if (auto member = method->FindDataMember()) {
if (needSep) {
menu.addSeparator();
needSep = kFALSE;
}

if (m->GetterMethod()) {

if (member->GetterMethod()) {
QMenu *r = menu.addMenu(method->GetName());
TIter nxt(m->GetOptions());
TIter nxt(member->GetOptions());
while (auto it = (TOptionListItem*) nxt()) {
const char *name = it->fOptName;
Long_t val = it->fValue;

TToggle *t = new TToggle;
t->SetToggledObject(object, method);
t->SetOnValue(val);
t->SetToggledObject(object, member);
t->SetOnValue(it->fValue);
fTrash.Add(t);

auto act = addMenuAction(r, &map, name, togglelist++, t);
auto act = addMenuAction(r, &map, it->fOptName.Data(), togglelist++, t);
act->setCheckable(true);
if (t->GetState())
act->setChecked(true);
Expand Down
Loading