mirror of
https://github.com/schrodinger/pymol-open-source.git
synced 2026-06-04 20:04:21 +08:00
477 lines
14 KiB
C++
477 lines
14 KiB
C++
|
|
/*
|
|
A* -------------------------------------------------------------------
|
|
B* This file contains source code for the PyMOL computer program
|
|
C* copyright 1998-2000 by Warren Lyford Delano of DeLano Scientific.
|
|
D* -------------------------------------------------------------------
|
|
E* It is unlawful to modify or remove this copyright notice.
|
|
F* -------------------------------------------------------------------
|
|
G* Please see the accompanying LICENSE file for further information.
|
|
H* -------------------------------------------------------------------
|
|
I* Additional authors of this source file include:
|
|
-*
|
|
-*
|
|
-*
|
|
Z* -------------------------------------------------------------------
|
|
*/
|
|
#ifndef _H_Setting
|
|
#define _H_Setting
|
|
|
|
#include <vector>
|
|
#include <string>
|
|
#include <unordered_map>
|
|
|
|
#include"os_python.h"
|
|
#include"PyMOLGlobals.h"
|
|
#include"pymol/memory.h"
|
|
#include"Result.h"
|
|
|
|
typedef char SettingName[255];
|
|
|
|
/**
|
|
* Setting record for atom/astate/bond/bstate level settings
|
|
*/
|
|
struct SettingUniqueEntry {
|
|
int setting_id;
|
|
union {
|
|
int int_;
|
|
float float_;
|
|
float float3_[3];
|
|
} value;
|
|
int next; /* for per-atom setting lists & memory management */
|
|
};
|
|
|
|
struct CSettingUnique {
|
|
std::unordered_map<int, int> id2offset;
|
|
std::unique_ptr<std::unordered_map<int, int>> old2new;
|
|
std::vector<SettingUniqueEntry> entry;
|
|
constexpr static int numInitEntries = 10;
|
|
int next_free{};
|
|
};
|
|
|
|
/**
|
|
* Setting record for global/object/ostate level settings
|
|
*/
|
|
struct SettingRec {
|
|
union {
|
|
int int_;
|
|
float float_;
|
|
float float3_[3];
|
|
std::string * str_;
|
|
};
|
|
|
|
bool defined;
|
|
bool changed;
|
|
|
|
private:
|
|
void setChanged() {
|
|
defined = true;
|
|
changed = true;
|
|
}
|
|
|
|
public:
|
|
void set_i(int value) {
|
|
int_ = value;
|
|
setChanged();
|
|
}
|
|
|
|
void set_f(float value) {
|
|
float_ = value;
|
|
setChanged();
|
|
}
|
|
|
|
void set_3f(float v0, float v1, float v2) {
|
|
float3_[0] = v0;
|
|
float3_[1] = v1;
|
|
float3_[2] = v2;
|
|
setChanged();
|
|
}
|
|
|
|
void set_3f(const float * value) {
|
|
set_3f(value[0], value[1], value[2]);
|
|
}
|
|
|
|
void set_s(const char * value) {
|
|
if (!value) {
|
|
delete_s();
|
|
} else if (!str_) {
|
|
str_ = new std::string(value);
|
|
} else {
|
|
str_->assign(value);
|
|
}
|
|
setChanged();
|
|
}
|
|
|
|
void delete_s() {
|
|
if (str_) {
|
|
delete str_;
|
|
str_ = nullptr;
|
|
}
|
|
}
|
|
};
|
|
|
|
#define cSetting_tuple -1 // for get_setting_tuple
|
|
#define cSetting_blank 0
|
|
#define cSetting_boolean 1
|
|
#define cSetting_int 2
|
|
#define cSetting_float 3
|
|
#define cSetting_float3 4
|
|
#define cSetting_color 5
|
|
#define cSetting_string 6
|
|
|
|
|
|
/* Atomic Settings */
|
|
|
|
void SettingUniqueDetachChain(PyMOLGlobals * G, int index);
|
|
|
|
/* New API
|
|
* NOTE: get commands are not range-checked, so be careful
|
|
* in contrast, set commands expand the current list
|
|
*/
|
|
|
|
int SettingUniqueSetTypedValue(PyMOLGlobals * G, int unique_id, int setting_id,
|
|
int setting_type, const void *value);
|
|
|
|
/*
|
|
* bool overload
|
|
*/
|
|
inline
|
|
int SettingUniqueSetTypedValue(PyMOLGlobals * G, int unique_id, int setting_id,
|
|
int setting_type, const bool *value) {
|
|
int i = *value;
|
|
return SettingUniqueSetTypedValue(G, unique_id, setting_id, setting_type, &i);
|
|
}
|
|
|
|
bool SettingUniqueUnset(PyMOLGlobals * G, int unique_id, int setting_id);
|
|
|
|
#ifndef _PYMOL_NOPY
|
|
bool SettingUniqueSetPyObject(PyMOLGlobals * G, int unique_id, int setting_id, PyObject *value);
|
|
#endif
|
|
|
|
int SettingUniqueCheck(PyMOLGlobals * G, int unique_id, int setting_id);
|
|
PyObject *SettingUniqueGetPyObject(PyMOLGlobals * G, int unique_id, int index);
|
|
|
|
void SettingUniqueResetAll(PyMOLGlobals * G);
|
|
PyObject *SettingUniqueAsPyList(PyMOLGlobals * G);
|
|
int SettingUniqueFromPyList(PyMOLGlobals * G, PyObject * list, int partial_restore);
|
|
int SettingUniqueConvertOldSessionID(PyMOLGlobals * G, int old_unique_id);
|
|
|
|
int SettingUniqueCopyAll(PyMOLGlobals * G, int src_unique_id, int dst_unique_id);
|
|
void SettingInitGlobal(PyMOLGlobals * G, int alloc, int reset_gui, int use_default);
|
|
void SettingStoreDefault(PyMOLGlobals * G);
|
|
void SettingPurgeDefault(PyMOLGlobals * G);
|
|
|
|
void SettingFreeGlobal(PyMOLGlobals * G);
|
|
|
|
CSetting *SettingNew(PyMOLGlobals * G);
|
|
CSetting* SettingCopyAll(PyMOLGlobals* G, const CSetting* src, CSetting* dst);
|
|
void SettingFreeP(CSetting * I);
|
|
void SettingCheckHandle(PyMOLGlobals * G, pymol::copyable_ptr<CSetting>& handle);
|
|
|
|
#define SettingSet_b SettingSet_i
|
|
int SettingSet_i(CSetting * I, int index, int value);
|
|
int SettingSet_f(CSetting * I, int index, float value);
|
|
int SettingSet_s(CSetting * I, int index, const char *value);
|
|
int SettingSet_3fv(CSetting * I, int index, const float *value);
|
|
|
|
int SettingGetTextValue(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index,
|
|
char *buffer);
|
|
const char * SettingGetTextPtr(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2,
|
|
int index, char *buffer);
|
|
|
|
int SettingUnset(CSetting * I, int index);
|
|
|
|
void SettingRestoreDefault(CSetting * I, int index, const CSetting * src=nullptr);
|
|
|
|
int SettingGetType(int index);
|
|
inline int SettingGetType(PyMOLGlobals *, int index) {
|
|
return SettingGetType(index);
|
|
}
|
|
|
|
template <typename V> inline int SettingGetType();
|
|
template <> inline int SettingGetType<bool>() { return cSetting_boolean; }
|
|
template <> inline int SettingGetType<int>() { return cSetting_int; }
|
|
template <> inline int SettingGetType<float>() { return cSetting_float; }
|
|
template <> inline int SettingGetType<const float*>() { return cSetting_float3; }
|
|
template <> inline int SettingGetType<float*>() { return cSetting_float3; }
|
|
template <> inline int SettingGetType<const char*>() { return cSetting_string; }
|
|
template <> inline int SettingGetType<char*>() { return cSetting_string; }
|
|
|
|
#define SettingSetGlobal_b SettingSet<bool>
|
|
#define SettingSetGlobal_i SettingSet<int>
|
|
#define SettingSetGlobal_s SettingSet<const char *>
|
|
#define SettingSetGlobal_f SettingSet<float>
|
|
|
|
int SettingSetSmart_i(PyMOLGlobals * G, CSetting * set1, CSetting * set2, int index,
|
|
int value);
|
|
|
|
int SettingSet_color(CSetting * I, int index, const char *value);
|
|
|
|
int SettingSetFromString(PyMOLGlobals * G, CSetting * I, int index, const char *st);
|
|
int SettingStringToTypedValue(PyMOLGlobals * G, int index, const char *st, int *type,
|
|
int *value);
|
|
|
|
#ifndef _PYMOL_NOPY
|
|
int SettingSetFromTuple(PyMOLGlobals * G, CSetting * I, int index, PyObject * tuple);
|
|
PyObject *SettingGetPyObject(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index);
|
|
PyObject *SettingGetTuple(PyMOLGlobals * G, const CSetting * set1, const CSetting * set2, int index); /* (type,(value,)) */
|
|
PyObject *SettingGetSettingIndices();
|
|
PyObject *SettingUniqueGetIndicesAsPyList(PyMOLGlobals * G, int unique_id);
|
|
#endif
|
|
|
|
std::vector<int> SettingGetUpdateList(PyMOLGlobals * G, const char * name="", int state=0);
|
|
|
|
void SettingGenerateSideEffects(PyMOLGlobals * G, int index, const char *sele, int state, int quiet);
|
|
|
|
int SettingGetIndex(PyMOLGlobals * G, const char *name);
|
|
int SettingGetName(PyMOLGlobals * G, int index, SettingName name);
|
|
const char * SettingGetName(int index);
|
|
|
|
PyObject *SettingAsPyList(CSetting * I, bool incl_blacklisted=false);
|
|
int SettingFromPyList(CSetting * I, PyObject * list);
|
|
|
|
int SettingSetGlobalsFromPyList(PyMOLGlobals * G, PyObject * list);
|
|
PyObject *SettingGetGlobalsAsPyList(PyMOLGlobals * G);
|
|
|
|
|
|
CSetting *SettingNewFromPyList(PyMOLGlobals * G, PyObject * list);
|
|
|
|
int SettingCheckFontID(PyMOLGlobals * G, CSetting * set1, CSetting * set2, int font_id);
|
|
|
|
// The following defines the enum with all cSetting_<settingname> indices
|
|
#include "SettingInfo.h"
|
|
|
|
#define cStereo_default 0 /* stereo_mode=0 only used for startup */
|
|
#define cStereo_quadbuffer 1
|
|
#define cStereo_crosseye 2
|
|
#define cStereo_walleye 3
|
|
#define cStereo_geowall 4
|
|
#define cStereo_sidebyside 5
|
|
#define cStereo_stencil_by_row 6
|
|
#define cStereo_stencil_by_column 7
|
|
#define cStereo_stencil_checkerboard 8
|
|
#define cStereo_stencil_custom 9 /* for hardware developers to use */
|
|
#define cStereo_anaglyph 10
|
|
#define cStereo_dynamic 11 /* dynamic polarization */
|
|
#define cStereo_clone_dynamic 12
|
|
#define cStereo_openvr 13
|
|
|
|
struct CSetting {
|
|
PyMOLGlobals* G;
|
|
SettingRec info[cSetting_INIT]{};
|
|
|
|
CSetting(PyMOLGlobals*);
|
|
CSetting(const CSetting&);
|
|
CSetting& operator=(const CSetting&);
|
|
~CSetting();
|
|
};
|
|
|
|
namespace pymol
|
|
{
|
|
struct CObject;
|
|
}
|
|
|
|
/**
|
|
* State index iterator which iterates either over a single state (state >= 0),
|
|
* the current state (state == -2), or all states (state == -1). Takes
|
|
* static singletons into account. Zero iterations if state >= nstate.
|
|
*
|
|
* StateIterator iter(G, I->Setting, state, I->NState);
|
|
* while (iter.next()) {
|
|
* printf("in state %d\n", iter.state);
|
|
* }
|
|
*/
|
|
class StateIterator {
|
|
StateIndex_t end;
|
|
|
|
public:
|
|
StateIndex_t state;
|
|
|
|
StateIterator(PyMOLGlobals*, CSetting*, StateIndex_t, int nstate);
|
|
StateIterator(pymol::CObject*, StateIndex_t);
|
|
|
|
bool next() {
|
|
return (++state < end);
|
|
};
|
|
};
|
|
|
|
/**
|
|
* Similar to StateIterator but easily useable
|
|
* with ranged-for loops
|
|
*/
|
|
class StateIteratorV2 {
|
|
StateIndex_t m_beg;
|
|
StateIndex_t m_end;
|
|
StateIndex_t m_cur;
|
|
|
|
public:
|
|
StateIteratorV2(pymol::CObject*, StateIndex_t);
|
|
|
|
/**
|
|
* @return begin state iterator
|
|
*/
|
|
StateIndex_t* begin();
|
|
|
|
/**
|
|
* @return end state iterator
|
|
*/
|
|
StateIndex_t* end();
|
|
};
|
|
|
|
/*
|
|
* Setting levels (global, object, ...)
|
|
*/
|
|
|
|
enum {
|
|
cSettingLevel_unused = 0,
|
|
cSettingLevel_global,
|
|
cSettingLevel_object,
|
|
cSettingLevel_ostate,
|
|
cSettingLevel_atom,
|
|
cSettingLevel_astate,
|
|
cSettingLevel_bond,
|
|
cSettingLevel_bstate
|
|
};
|
|
|
|
// Setting level info table
|
|
extern const struct SettingLevelInfoType {
|
|
// name of this level, for feedback
|
|
const char * name;
|
|
// bitmask of valid (sub-)levels
|
|
unsigned char mask;
|
|
} SettingLevelInfo[];
|
|
|
|
const char * SettingLevelGetName(unsigned index);
|
|
bool SettingLevelCheckMask(PyMOLGlobals * G, int index, unsigned char mask);
|
|
bool SettingLevelCheck(PyMOLGlobals * G, int index, unsigned char level);
|
|
|
|
bool CPyMOLInitSetting(OVLexicon * Lex, std::unordered_map<int, int>& Setting);
|
|
pymol::Result<int> get_setting_id(CPyMOL* I, const char* setting);
|
|
|
|
/*
|
|
* Overloaded setters for templatted programming
|
|
*/
|
|
|
|
inline void SettingSet(CSetting * s, int i, bool v) { SettingSet_b(s, i, v); }
|
|
inline void SettingSet(CSetting * s, int i, int v) { SettingSet_i(s, i, v); }
|
|
inline void SettingSet(CSetting * s, int i, long int v) { SettingSet_i(s, i, v); }
|
|
inline void SettingSet(CSetting * s, int i, float v) { SettingSet_f(s, i, v); }
|
|
inline void SettingSet(CSetting * s, int i, const char *v) { SettingSet_s(s, i, v); }
|
|
inline void SettingSet(CSetting * s, int i, const float *v) { SettingSet_3fv(s, i, v); }
|
|
|
|
template <typename V>
|
|
void SettingUniqueSet(PyMOLGlobals * G, int uid, int index, V value) {
|
|
SettingUniqueSetTypedValue(G, uid, index, SettingGetType<V>(), &value);
|
|
}
|
|
|
|
template <typename V> void SettingSet(PyMOLGlobals * G, pymol::copyable_ptr<CSetting>& handle, int index, V value) {
|
|
SettingCheckHandle(G, handle);
|
|
SettingSet(handle.get(), index, value);
|
|
}
|
|
|
|
// global setting
|
|
template <typename V> bool SettingSet(PyMOLGlobals * G, int index, V value) {
|
|
SettingSet(G->Setting, index, value);
|
|
return true;
|
|
}
|
|
|
|
// light setting array
|
|
extern int light_setting_indices[];
|
|
|
|
/*
|
|
* Getters for templatted programming
|
|
*/
|
|
|
|
const CSetting * _SettingGetFirstDefined(int index,
|
|
PyMOLGlobals * G,
|
|
const CSetting * set1,
|
|
const CSetting * set2);
|
|
|
|
template <typename V> V _SettingGet(int index, const CSetting *);
|
|
template <typename V> V SettingGet(PyMOLGlobals * G,
|
|
const CSetting * set1,
|
|
const CSetting * set2, int index) {
|
|
return SettingGet<V>(index, _SettingGetFirstDefined(index, G, set1, set2));
|
|
}
|
|
template <typename V> V SettingGet(PyMOLGlobals * G, int index) {
|
|
return SettingGet<V>(index, G->Setting);
|
|
}
|
|
|
|
template <typename V> V SettingGet(int index, const CSetting* set)
|
|
{
|
|
using T = typename std::conditional<std::is_enum<V>::value, int, V>::type;
|
|
return static_cast<V>(_SettingGet<T>(index, set));
|
|
}
|
|
|
|
/**
|
|
* Get setting value if it's defined in the given set, and assign value to
|
|
* `out` variable and return true. Otherwise return false and leave `out`
|
|
* untouched.
|
|
*/
|
|
template <typename V>
|
|
bool SettingGetIfDefined(const CSetting * s, int index, V * out) {
|
|
if (s && s->info[index].defined) {
|
|
*out = SettingGet<V>(index, s);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Return setting value if it's defined in the given set, or `default_` otherwise.
|
|
*/
|
|
template <typename V>
|
|
V SettingGetWD(const CSetting* s, int index, V default_) {
|
|
V out;
|
|
if (SettingGetIfDefined<V>(s, index, &out))
|
|
return out;
|
|
return default_;
|
|
}
|
|
|
|
#define SettingGet_b SettingGet<bool>
|
|
#define SettingGet_i SettingGet<int>
|
|
#define SettingGet_color SettingGet<int>
|
|
#define SettingGet_f SettingGet<float>
|
|
#define SettingGet_s SettingGet<const char *>
|
|
#define SettingGet_3fv SettingGet<const float *>
|
|
|
|
#define SettingGetGlobal_b SettingGet<bool>
|
|
#define SettingGetGlobal_i SettingGet<int>
|
|
#define SettingGetGlobal_color SettingGet<int>
|
|
#define SettingGetGlobal_f SettingGet<float>
|
|
#define SettingGetGlobal_s SettingGet<const char *>
|
|
#define SettingGetGlobal_3fv SettingGet<const float *>
|
|
|
|
#define SettingGetIfDefined_b(G, s, i, o) SettingGetIfDefined(s, i, o)
|
|
#define SettingGetIfDefined_i(G, s, i, o) SettingGetIfDefined(s, i, o)
|
|
|
|
/*
|
|
* templatted unique settings
|
|
*/
|
|
|
|
bool SettingUniqueGetTypedValuePtr(PyMOLGlobals * G, int unique_id, int index,
|
|
int setting_type, void * out);
|
|
|
|
/*
|
|
* bool overload
|
|
*/
|
|
inline
|
|
bool SettingUniqueGetTypedValuePtr(PyMOLGlobals * G, int unique_id, int index,
|
|
int setting_type, bool * out) {
|
|
int i = *out;
|
|
bool r = SettingUniqueGetTypedValuePtr(G, unique_id, index, setting_type, &i);
|
|
*out = i;
|
|
return r;
|
|
}
|
|
|
|
/**
|
|
* SettingGetIfDefined() equivalent for unique settings.
|
|
*/
|
|
template <typename V>
|
|
bool SettingUniqueGetIfDefined(PyMOLGlobals * G, int unique_id, int index, V * out) {
|
|
return SettingUniqueGetTypedValuePtr(G, unique_id, index,
|
|
SettingGetType<V>(), out);
|
|
}
|
|
|
|
#endif
|