Rapicorn - Experimental UI Toolkit - Source Code
13.07.0
|
00001 // Licensed GNU LGPL v3 or later: http://www.gnu.org/licenses/lgpl.html 00002 #include <ui/widget.hh> // unguarded, because item.hh includes commands.hh 00003 00004 #ifndef __RAPICORN_COMMANDS_HH__ 00005 #define __RAPICORN_COMMANDS_HH__ 00006 00007 namespace Rapicorn { 00008 00009 struct Command : ReferenceCountable { 00010 const String ident; 00011 const String blurb; 00012 bool needs_arg; 00013 Command (const char *cident, const char *cblurb, bool has_arg); 00014 virtual bool exec (Deletable *obj, const StringSeq &args) = 0; 00015 protected: 00016 virtual ~Command(); 00017 }; 00018 00019 struct CommandList { 00020 uint n_commands; 00021 Command **commands; 00022 CommandList () : n_commands (0), commands (NULL) {} 00023 template<typename Array> 00024 CommandList (Array &a, 00025 const CommandList &chain = CommandList()) : 00026 n_commands (0), 00027 commands (NULL) 00028 { 00029 uint array_length = sizeof (a) / sizeof (a[0]); 00030 n_commands = array_length + chain.n_commands; 00031 commands = new Command*[n_commands]; 00032 uint i; 00033 for (i = 0; i < array_length; i++) 00034 commands[i] = ref_sink (a[i]); 00035 for (; i < n_commands; i++) 00036 commands[i] = ref (chain.commands[i - array_length]); 00037 } 00038 ~CommandList() 00039 { 00040 for (uint i = 0; i < n_commands; i++) 00041 unref (commands[i]); 00042 delete[] commands; 00043 } 00044 }; 00045 00046 #define RAPICORN_MakeNamedCommand(Type, cident, blurb, method, data) \ 00047 create_command (&Type::method, cident, blurb, data) 00048 #define RAPICORN_MakeSimpleCommand(Type, method, blurb) \ 00049 create_command (&Type::method, #method, blurb) 00050 00051 /* --- command implementations --- */ 00052 /* command with data and arg string */ 00053 template<class Class, class Data> 00054 struct CommandDataArg : Command { 00055 typedef bool (Class::*CommandMethod) (Data data, const StringSeq &args); 00056 bool (Class::*command_method) (Data data, const StringSeq &args); 00057 Data data; 00058 CommandDataArg (bool (Class::*method) (Data, const String&), 00059 const char *cident, const char *cblurb, const Data &method_data); 00060 virtual bool exec (Deletable *obj, const StringSeq &args); 00061 }; 00062 template<class Class, class Data> inline Command* 00063 create_command (bool (Class::*method) (Data, const String&), 00064 const char *ident, const char *blurb, const Data &method_data) 00065 { return new CommandDataArg<Class,Data> (method, ident, blurb, method_data); } 00066 00067 /* command with data */ 00068 template<class Class, class Data> 00069 struct CommandData : Command { 00070 typedef bool (Class::*CommandMethod) (Data data); 00071 bool (Class::*command_method) (Data data); 00072 Data data; 00073 CommandData (bool (Class::*method) (Data), 00074 const char *cident, const char *cblurb, const Data &method_data); 00075 virtual bool exec (Deletable *obj, const StringSeq&); 00076 }; 00077 template<class Class, class Data> inline Command* 00078 create_command (bool (Class::*method) (Data), 00079 const char *ident, const char *blurb, const Data &method_data) 00080 { return new CommandData<Class,Data> (method, ident, blurb, method_data); } 00081 00082 /* command with arg string */ 00083 template<class Class> 00084 struct CommandArg: Command { 00085 typedef bool (Class::*CommandMethod) (const StringSeq &args); 00086 bool (Class::*command_method) (const StringSeq &args); 00087 CommandArg (bool (Class::*method) (const String&), 00088 const char *cident, const char *cblurb); 00089 virtual bool exec (Deletable *obj, const StringSeq &args); 00090 }; 00091 template<class Class> inline Command* 00092 create_command (bool (Class::*method) (const String&), 00093 const char *ident, const char *blurb) 00094 { return new CommandArg<Class> (method, ident, blurb); } 00095 00096 /* simple command */ 00097 template<class Class> 00098 struct CommandSimple : Command { 00099 typedef bool (Class::*CommandMethod) (); 00100 bool (Class::*command_method) (); 00101 CommandSimple (bool (Class::*method) (), 00102 const char *cident, const char *cblurb); 00103 virtual bool exec (Deletable *obj, const StringSeq&); 00104 }; 00105 template<class Class> inline Command* 00106 create_command (bool (Class::*method) (), 00107 const char *ident, const char *blurb) 00108 { return new CommandSimple<Class> (method, ident, blurb); } 00109 00110 /* --- implementations --- */ 00111 /* command with data and arg string */ 00112 template<class Class, typename Data> 00113 CommandDataArg<Class,Data>::CommandDataArg (bool (Class::*method) (Data, const String&), 00114 const char *cident, const char *cblurb, const Data &method_data) : 00115 Command (cident, cblurb, true), 00116 command_method (method), 00117 data (method_data) 00118 {} 00119 template<class Class, typename Data> bool 00120 CommandDataArg<Class,Data>::exec (Deletable *obj, const StringSeq &args) 00121 { 00122 Class *instance = dynamic_cast<Class*> (obj); 00123 if (!instance) 00124 fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_name().c_str()); 00125 return (instance->*command_method) (data, args); 00126 } 00127 00128 /* command arg string */ 00129 template<class Class> 00130 CommandArg<Class>::CommandArg (bool (Class::*method) (const String&), 00131 const char *cident, const char *cblurb) : 00132 Command (cident, cblurb, true), 00133 command_method (method) 00134 {} 00135 template<class Class> bool 00136 CommandArg<Class>::exec (Deletable *obj, const StringSeq &args) 00137 { 00138 Class *instance = dynamic_cast<Class*> (obj); 00139 if (!instance) 00140 fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_name().c_str()); 00141 return (instance->*command_method) (args); 00142 } 00143 00144 /* command with data */ 00145 template<class Class, typename Data> 00146 CommandData<Class,Data>::CommandData (bool (Class::*method) (Data), 00147 const char *cident, const char *cblurb, const Data &method_data) : 00148 Command (cident, cblurb, false), 00149 command_method (method), 00150 data (method_data) 00151 {} 00152 template<class Class, typename Data> bool 00153 CommandData<Class,Data>::exec (Deletable *obj, const StringSeq&) 00154 { 00155 Class *instance = dynamic_cast<Class*> (obj); 00156 if (!instance) 00157 fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_name().c_str()); 00158 return (instance->*command_method) (data); 00159 } 00160 00161 /* simple command */ 00162 template<class Class> 00163 CommandSimple<Class>::CommandSimple (bool (Class::*method) (), 00164 const char *cident, const char *cblurb) : 00165 Command (cident, cblurb, false), 00166 command_method (method) 00167 {} 00168 template<class Class> bool 00169 CommandSimple<Class>::exec (Deletable *obj, const StringSeq&) 00170 { 00171 Class *instance = dynamic_cast<Class*> (obj); 00172 if (!instance) 00173 fatal ("Rapicorn::Command: invalid command object: %s", obj->typeid_name().c_str()); 00174 return (instance->*command_method) (); 00175 } 00176 00177 } // Rapicorn 00178 00179 #endif /* __RAPICORN_COMMANDS_HH__ */