Jamba C++ API  4.4.0
CustomViewCreator.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2018-2019 pongasoft
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License"); you may not
5  * use this file except in compliance with the License. You may obtain a copy of
6  * the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13  * License for the specific language governing permissions and limitations under
14  * the License.
15  *
16  * @author Yan Pujante
17  */
18 #pragma once
19 
20 #include <vstgui4/vstgui/uidescription/iviewcreator.h>
21 #include <vstgui4/vstgui/uidescription/uiviewcreator.h>
22 #include <vstgui4/vstgui/uidescription/uiviewfactory.h>
23 #include <vstgui4/vstgui/uidescription/uiattributes.h>
24 #include <vstgui4/vstgui/uidescription/detail/uiviewcreatorattributes.h>
25 #include <vstgui4/vstgui/lib/crect.h>
26 #include <vstgui4/vstgui/lib/ccolor.h>
27 #include <vstgui4/vstgui/lib/cbitmap.h>
28 #include <map>
29 #include <memory>
30 #include <functional>
31 #include <pongasoft/logging/logging.h>
35 #include <pongasoft/Utils/Cpp17.h>
36 #include <pongasoft/VST/Types.h>
37 
39 
40 using namespace VSTGUI;
41 
42 //------------------------------------------------------------------------
43 // Implementation Note: Half of the API (the "getter"/"read" part of it) is not used in Release mode because the
44 // editor code is built only during Debug mode (EDITOR_MODE is defined) and only the editor code is using it.
45 // As a result, it is conditionnally compiled so that it doesn't use unecessary space in Release mode.
46 //------------------------------------------------------------------------
47 
52 {
53 public:
54  // Constructor
55  explicit ViewAttribute(std::string iName) :
56  fName(std::move(iName))
57  {}
58 
62  virtual IViewCreator::AttrType getType() = 0;
63 
68  std::string getName() const
69  {
70  return fName;
71  }
72 
79  virtual bool apply(CView *iView, const UIAttributes &iAttributes, const IUIDescription *iDescription) = 0;
80 
81 #ifdef EDITOR_MODE
82 
88  virtual bool getAttributeValue(CView *iView, const IUIDescription *iDescription, std::string &oStringValue) const = 0;
89 
93  virtual bool getPossibleListValues(std::list<const std::string *> &iValues) const
94  {
95  return false;
96  }
97 #endif
98 
99 private:
100  std::string fName;
101 };
102 
107 template<typename TView>
108 inline TView *createCustomView(CRect const &iSize,
109  const UIAttributes &iAttributes,
110  const IUIDescription * /* iDescription */) { return new TView(iSize); }
111 
114 template<typename T>
115 using AttrValMap = std::map<std::string, T>;
116 
120 template<typename T>
121 using AttrValInitList = std::initializer_list<typename AttrValMap<T>::value_type>;
122 
155 template<typename TView>
156 class TCustomViewCreator : public ViewCreatorAdapter
157 {
158 private:
164  template<typename T, typename TGetter, typename TSetter>
165  class TAttribute : public ViewAttribute
166  {
167  public:
168  using Getter = TGetter;
169  using Setter = TSetter;
170 
171  // Constructor
172  TAttribute(std::string const &iName, Getter iGetter, Setter iSetter) :
173  ViewAttribute(iName),
174 #ifdef EDITOR_MODE
175  fGetter{iGetter},
176 #endif
177  fSetter{iSetter}
178  { }
179 
180  // getType
181  IViewCreator::AttrType getType() override
182  {
183  return IViewCreator::kUnknownType;
184  }
185 
190  virtual bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, T &oValue) const
191  {
192  return false;
193  }
194 
196  bool apply(CView *iView, const UIAttributes &iAttributes, const IUIDescription *iDescription) override
197  {
198  auto *tv = dynamic_cast<TView *>(iView);
199  if(tv != nullptr)
200  {
201  auto attributeValue = iAttributes.getAttributeValue(getName());
202  if(attributeValue)
203  {
204  T value;
205  if(fromString(iDescription, *attributeValue, value))
206  {
207  std::invoke(fSetter, tv, value);
208  return true;
209  }
210  }
211  }
212  return false;
213  }
214 
215 #ifdef EDITOR_MODE
216 
220  virtual bool toString(IUIDescription const *iDescription, T const &iValue, std::string &oStringValue) const
221  {
222  return false;
223  }
224 
225 
227  bool getAttributeValue(CView *iView, const IUIDescription *iDescription, std::string &oStringValue) const override
228  {
229  auto *tv = dynamic_cast<TView *>(iView);
230  if(tv != nullptr)
231  {
232  auto value = std::invoke(fGetter, tv);
233  return toString(iDescription, value, oStringValue);
234  }
235  return false;
236  }
237 
238  private:
239  Getter fGetter;
240 #endif
241 
242  private:
244  };
245 
249  template<typename T>
250  using ByValAttribute = TAttribute<T, T (TView::*)() const, void (TView::*)(T)>;
251 
255  template<typename T>
256  using ByRefAttribute = TAttribute<T, T const &(TView::*)() const, void (TView::*)(T const &)>;
257 
263  {
264  public:
265  TagAttribute(std::string const &iName,
266  typename ByValAttribute<TagID>::Getter iGetter,
267  typename ByValAttribute<TagID>::Setter iSetter) :
268  ByValAttribute<TagID>(iName, iGetter, iSetter) {}
269 
270  // getType
271  IViewCreator::AttrType getType() override
272  {
273  return IViewCreator::kTagType;
274  }
275 
276  // fromString
277  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, TagID &oValue) const override
278  {
279  if(iAttributeValue.length() != 0)
280  {
281  auto tag = static_cast<TagID>(iDescription->getTagForName(iAttributeValue.c_str()));
282  if(tag == UNDEFINED_TAG_ID)
283  {
284  char *endPtr = nullptr;
285  tag = static_cast<TagID>(strtol(iAttributeValue.c_str(), &endPtr, 10));
286  if(endPtr == iAttributeValue.c_str())
287  {
288  return false;
289  }
290  }
291  oValue = tag;
292  }
293  else
294  // when selecting "NONE" iAttributeValue is an empty string
295  oValue = UNDEFINED_PARAM_ID;
296 
297  return true;
298  }
299 
300 #ifdef EDITOR_MODE
301  // toString
302  bool toString(IUIDescription const *iDescription, const TagID &iValue, std::string &oStringValue) const override
303  {
304  if(iValue != UNDEFINED_TAG_ID)
305  {
306  UTF8StringPtr controlTag = iDescription->lookupControlTagName(iValue);
307  if(controlTag)
308  {
309  oStringValue = controlTag;
310  return true;
311  }
312  }
313 
314  return false;
315  }
316 #endif
317  };
318 
323  template<typename TInt>
324  class IntegerAttribute : public ByValAttribute<TInt>
325  {
326  public:
329 
330  // Constructor
331  IntegerAttribute(std::string const &iName, Getter iGetter, Setter iSetter) :
332  ByValAttribute<TInt>(iName, iGetter, iSetter) {}
333 
334  // getType
335  IViewCreator::AttrType getType() override
336  {
337  return IViewCreator::kIntegerType;
338  }
339 
340  // fromString
341  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, TInt &oValue) const override
342  {
343  char *endPtr = nullptr;
344  auto value = static_cast<TInt>(strtol(iAttributeValue.c_str(), &endPtr, 10));
345  if(endPtr == iAttributeValue.c_str())
346  {
347  DLOG_F(WARNING, "could not convert <%s> to an integer", iAttributeValue.c_str());
348  return false;
349  }
350  oValue = value;
351  return true;
352  }
353 
354 #ifdef EDITOR_MODE
355  // toString
356  bool toString(IUIDescription const *iDescription, const TInt &iValue, std::string &oStringValue) const override
357  {
358  std::stringstream str;
359  str << iValue;
360  oStringValue = str.str();
361  return true;
362  }
363 #endif
364  };
365 
370  template<typename TFloat>
371  class FloatAttribute : public ByValAttribute<TFloat>
372  {
373  public:
376 
377  // Constructor
378  FloatAttribute(std::string const &iName, Getter iGetter, Setter iSetter) :
379  ByValAttribute<TFloat>(iName, iGetter, iSetter) {}
380 
381  // getType
382  IViewCreator::AttrType getType() override
383  {
384  return IViewCreator::kFloatType;
385  }
386 
387  // fromString
388  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, TFloat &oValue) const override
389  {
390  TFloat value;
391  if(Utils::stringToFloat<TFloat>(iAttributeValue, value))
392  {
393  oValue = value;
394  return true;
395  }
396  DLOG_F(WARNING, "could not convert <%s> to a float", iAttributeValue.c_str());
397  return false;
398  }
399 
400 #ifdef EDITOR_MODE
401  // toString
402  bool toString(IUIDescription const *iDescription, const TFloat &iValue, std::string &oStringValue) const override
403  {
404  std::stringstream str;
405  str << iValue;
406  oStringValue = str.str();
407  return true;
408  }
409 #endif
410  };
411 
416  class ColorAttribute : public ByRefAttribute<CColor>
417  {
418  public:
419 
420  // Constructor
421  ColorAttribute(std::string const &iName,
422  typename ByRefAttribute<CColor>::Getter iGetter,
423  typename ByRefAttribute<CColor>::Setter iSetter) :
424  ByRefAttribute<CColor>(iName, iGetter, iSetter) {}
425 
426  // getType
427  IViewCreator::AttrType getType() override
428  {
429  return IViewCreator::kColorType;
430  }
431 
432  // fromString
433  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, CColor &oValue) const override
434  {
435  CColor color;
436  if(UIViewCreator::stringToColor(&iAttributeValue, color, iDescription))
437  {
438  oValue = color;
439  return true;
440  }
441  return false;
442  }
443 
444 #ifdef EDITOR_MODE
445  // toString
446  bool toString(IUIDescription const *iDescription, const CColor &iValue, std::string &oStringValue) const override
447  {
448  return UIViewCreator::colorToString(iValue, oStringValue, iDescription);
449  }
450 #endif
451  };
452 
457  class GradientAttribute : public ByValAttribute<GradientPtr>
458  {
459  public:
460 
461  // Constructor
462  GradientAttribute(std::string const &iName,
463  typename ByValAttribute<GradientPtr>::Getter iGetter,
464  typename ByValAttribute<GradientPtr>::Setter iSetter) :
465  ByValAttribute<GradientPtr>(iName, iGetter, iSetter) {}
466 
467  // getType
468  IViewCreator::AttrType getType() override
469  {
470  return IViewCreator::kGradientType;
471  }
472 
473  // fromString
474  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, GradientPtr &oValue) const override
475  {
476  auto gradient = iDescription->getGradient(iAttributeValue.c_str());
477  if(gradient)
478  {
479  oValue = gradient;
480  return true;
481  }
482  return false;
483  }
484 
485 #ifdef EDITOR_MODE
486  // toString
487  bool toString(IUIDescription const *iDescription, GradientPtr const &iValue, std::string &oStringValue) const override
488  {
489  if(iValue)
490  {
491  auto name = iDescription->lookupGradientName(iValue);
492  if(name)
493  {
494  oStringValue = name;
495  return true;
496  }
497 
498  }
499  return false;
500  }
501 #endif
502  };
503 
508  class BooleanAttribute : public ByValAttribute<bool>
509  {
510  public:
511  // Constructor
512  BooleanAttribute(std::string const &iName,
513  typename ByValAttribute<bool>::Getter iGetter,
514  typename ByValAttribute<bool>::Setter iSetter) :
515  ByValAttribute<bool>(iName, iGetter, iSetter) {}
516 
517  // getType
518  IViewCreator::AttrType getType() override
519  {
520  return IViewCreator::kBooleanType;
521  }
522 
523  // fromString
524  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, bool &oValue) const override
525  {
526  if(iAttributeValue == "true")
527  {
528  oValue = true;
529  return true;
530  }
531 
532  if(iAttributeValue == "false")
533  {
534  oValue = false;
535  return true;
536  }
537 
538  return false;
539  }
540 
541 #ifdef EDITOR_MODE
542  // toString
543  bool toString(IUIDescription const *iDescription, const bool &iValue, std::string &oStringValue) const override
544  {
545  oStringValue = iValue ? "true" : "false";
546  return true;
547  }
548 #endif
549  };
550 
555  class BitmapAttribute : public ByValAttribute<BitmapPtr>
556  {
557  public:
558  // Constructor
559  BitmapAttribute(std::string const &iName,
560  typename ByValAttribute<BitmapPtr>::Getter iGetter,
561  typename ByValAttribute<BitmapPtr>::Setter iSetter) :
562  ByValAttribute<BitmapPtr>(iName, iGetter, iSetter) {}
563 
564  // getType
565  IViewCreator::AttrType getType() override
566  {
567  return IViewCreator::kBitmapType;
568  }
569 
570  // fromString
571  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, BitmapPtr &oValue) const override
572  {
573  BitmapPtr bitmap;
574  if(UIViewCreator::stringToBitmap(&iAttributeValue, bitmap, iDescription))
575  {
576  oValue = bitmap;
577  return true;
578  }
579  return false;
580  }
581 
582 #ifdef EDITOR_MODE
583  // toString
584  bool toString(IUIDescription const *iDescription, BitmapPtr const &iValue, std::string &oStringValue) const override
585  {
586  if(iValue)
587  return UIViewCreator::bitmapToString(iValue, oStringValue, iDescription);
588  else
589  return false;
590  }
591 #endif
592  };
593 
598  class FontAttribute : public ByValAttribute<FontPtr>
599  {
600  public:
601  // Constructor
602  FontAttribute(std::string const &iName,
603  typename ByValAttribute<FontPtr>::Getter iGetter,
604  typename ByValAttribute<FontPtr>::Setter iSetter) :
605  ByValAttribute<FontPtr>(iName, iGetter, iSetter) {}
606 
607  // getType
608  IViewCreator::AttrType getType() override
609  {
610  return IViewCreator::kFontType;
611  }
612 
613  // fromString
614  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, FontPtr &oValue) const override
615  {
616  auto font = iDescription->getFont(iAttributeValue.c_str());
617  if(font)
618  {
619  oValue = font;
620  return true;
621  }
622  return false;
623  }
624 
625 #ifdef EDITOR_MODE
626  // toString
627  bool toString(IUIDescription const *iDescription, FontPtr const &iValue, std::string &oStringValue) const override
628  {
629  if(iValue)
630  {
631  auto fontName = iDescription->lookupFontName(iValue);
632  if(fontName)
633  {
634  oStringValue = fontName;
635  return true;
636  }
637  }
638  return false;
639  }
640 #endif
641  };
642 
647  class MarginAttribute : public ByRefAttribute<Margin>
648  {
649  public:
650  MarginAttribute(std::string const &iName,
651  typename ByRefAttribute<Margin>::Getter iGetter,
652  typename ByRefAttribute<Margin>::Setter iSetter) :
653  ByRefAttribute<Margin>(iName, iGetter, iSetter) {}
654 
655  // fromString
656  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, Margin &oValue) const override
657  {
658  auto parts = Utils::splitFloats<CCoord>(iAttributeValue, ',');
659 
660  if(parts.empty())
661  return false;
662 
663  // look for nan in the array
664  if(std::find_if(parts.cbegin(), parts.cend(), [] (auto f) {return std::isnan(f);}) != parts.cend())
665  return false;
666 
667  if(parts.size() == 1)
668  {
669  oValue = Margin{parts[0]};
670  }
671  else
672  {
673  if(parts.size() < 4)
674  return false;
675 
676  oValue = Margin{parts[0], parts[1], parts[2], parts[3]};
677  }
678 
679  return true;
680  }
681 
682 #ifdef EDITOR_MODE
683  // toString
684  bool toString(IUIDescription const *iDescription, const Margin &iValue, std::string &oStringValue) const override
685  {
686  std::stringstream str;
687  if(iValue.fTop == iValue.fRight && iValue.fTop == iValue.fBottom && iValue.fTop == iValue.fLeft)
688  str << iValue.fTop;
689  else
690  {
691  str << iValue.fTop;
692  str << ",";
693  str << iValue.fRight;
694  str << ",";
695  str << iValue.fBottom;
696  str << ",";
697  str << iValue.fLeft;
698  }
699  oStringValue = str.str();
700  return true;
701  }
702 #endif
703  };
704 
709  class RangeAttribute : public ByRefAttribute<Range>
710  {
711  public:
712  RangeAttribute(std::string const &iName,
713  typename ByRefAttribute<Range>::Getter iGetter,
714  typename ByRefAttribute<Range>::Setter iSetter) :
715  ByRefAttribute<Range>(iName, iGetter, iSetter) {}
716 
717  // fromString
718  bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, Range &oValue) const override
719  {
720  auto parts = Utils::splitFloats<CCoord>(iAttributeValue, ',');
721 
722  if(parts.empty())
723  return false;
724 
725  // look for nan in the array
726  if(std::find_if(parts.cbegin(), parts.cend(), [] (auto f) {return std::isnan(f);}) != parts.cend())
727  return false;
728 
729  if(parts.size() == 1)
730  oValue = Range{parts[0]};
731  else
732  oValue = Range{parts[0], parts[1]};
733 
734  return true;
735  }
736 
737 #ifdef EDITOR_MODE
738  // toString
739  bool toString(IUIDescription const *iDescription, const Range &iValue, std::string &oStringValue) const override
740  {
741  std::stringstream str;
742  if(iValue.fFrom == iValue.fTo)
743  str << iValue.fFrom;
744  else
745  {
746  str << iValue.fFrom;
747  str << ",";
748  str << iValue.fTo;
749  }
750  oStringValue = str.str();
751  return true;
752  }
753 #endif
754  };
755 
759  class VectorStringAttribute : public ByRefAttribute<std::vector<std::string>>
760  {
762 
763  public:
764  // Constructor
765  VectorStringAttribute(std::string const &iName,
766  typename super_type::Getter iGetter,
767  typename super_type::Setter iSetter,
768  char iDelimiter = ',',
769  bool iSkipEmptyEntries = false) :
770  super_type(iName, iGetter, iSetter),
771  fDelimiter{iDelimiter},
772  fSkipEmptyEntries{iSkipEmptyEntries}
773  {}
774 
775  // fromString
776  bool fromString(IUIDescription const *iDescription,
777  std::string const &iAttributeValue,
778  std::vector<std::string> &oValue) const override
779  {
780  oValue = Utils::splitString(iAttributeValue, fDelimiter, fSkipEmptyEntries);
781  return true;
782  }
783 
784 #ifdef EDITOR_MODE
785  // toString
786  bool toString(IUIDescription const *iDescription,
787  const std::vector<std::string> &iValue,
788  std::string &oStringValue) const override
789  {
790  oStringValue.clear();
791  int i = 0;
792  for(auto &entry : iValue)
793  {
794  if(i > 0)
795  oStringValue += fDelimiter;
796  if(!entry.empty() || !fSkipEmptyEntries)
797  {
798  oStringValue += entry;
799  i++;
800  }
801  }
802  return true;
803  }
804 #endif
805 
806  protected:
809  };
810 
814  template<typename T>
815  class ListAttribute : public ByValAttribute<T>
816  {
818 
819  public:
820  // Constructor
821  ListAttribute(std::string const &iName,
822  typename super_type::Getter iGetter,
823  typename super_type::Setter iSetter,
824  AttrValInitList<T> const &iAttributeValues) :
825  super_type(iName, iGetter, iSetter),
826  fAttributeValuesMap(iAttributeValues)
827 #ifdef EDITOR_MODE
828  ,fAttributeValuesList{iAttributeValues}
829 #endif
830  {
831  }
832 
833  // getType
834  IViewCreator::AttrType getType() override
835  {
836  return IViewCreator::kListType;
837  }
838 
839  // fromString
840  bool fromString(IUIDescription const *iDescription,
841  std::string const &iAttributeValue,
842  T &oValue) const override
843  {
844  if(fAttributeValuesMap.find(iAttributeValue) != fAttributeValuesMap.cend())
845  {
846  oValue = fAttributeValuesMap.at(iAttributeValue);
847  return true;
848  }
849 
850  DLOG_F(WARNING, "Attribute value '%s' is not valid for '%s'", iAttributeValue.c_str(), ViewAttribute::getName().c_str());
851  return false;
852  }
853 
854 #ifdef EDITOR_MODE
855  // toString
856  bool toString(IUIDescription const *iDescription,
857  T const &iValue,
858  std::string &oStringValue) const override
859  {
860  auto pos = std::find_if(std::begin(fAttributeValuesList),
861  std::end(fAttributeValuesList),
862  [&iValue](auto entry) -> bool {
863  return entry.second == iValue;
864  });
865  if(pos != std::end(fAttributeValuesList))
866  {
867  oStringValue = pos->first;
868  return true;
869  }
870 
871  return false;
872  }
873 
874  // getPossibleListValues
875  bool getPossibleListValues(std::list<const std::string *> &iValues) const override
876  {
877  for(auto const &p : fAttributeValuesList)
878  {
879  iValues.emplace_back(&p.first);
880  }
881  return true;
882  }
883 #endif
884 
885  protected:
887 #ifdef EDITOR_MODE
888  std::vector<typename AttrValMap<T>::value_type> const fAttributeValuesList;
889 #endif
890  };
891 
892 public:
893  // Constructor
894  explicit TCustomViewCreator(char const *iViewName = nullptr,
895  char const *iDisplayName = nullptr,
896  char const *iBaseViewName = VSTGUI::UIViewCreator::kCView) :
897  fViewName{iViewName},
898  fDisplayName{iDisplayName},
899  fBaseViewName{iBaseViewName},
900  fAttributes{}
901  {
902  // this allows for inheritance!
903  if(iViewName != nullptr && iDisplayName != nullptr)
904  VSTGUI::UIViewFactory::registerViewCreator(*this);
905  }
906 
907  // Destructor
909  {
910  // we simply clear the map since it holds shared pointers which will be discarded when they are no longer
911  // held by another object
912  fAttributes.clear();
913  }
914 
915  // getViewName
916  IdStringPtr getViewName() const override
917  {
918  return fViewName;
919  }
920 
921  // getDisplayName
922  UTF8StringPtr getDisplayName() const override
923  {
924  return fDisplayName;
925  }
926 
927  // getBaseViewName
928  IdStringPtr getBaseViewName() const override
929  {
930  return fBaseViewName;
931  }
932 
936  template<typename XView>
938  {
939  for(auto attribute : iOther.fAttributes)
940  {
941  registerAttribute(attribute.second);
942  }
943 
944  if(std::string(fBaseViewName) == std::string(VSTGUI::UIViewCreator::kCView))
945  fBaseViewName = iOther.fBaseViewName;
946  }
947 
951  void registerColorAttribute(std::string const &iName,
952  typename ColorAttribute::Getter iGetter,
953  typename ColorAttribute::Setter iSetter)
954  {
955  registerAttribute<ColorAttribute>(iName, iGetter, iSetter);
956  }
957 
961  void registerGradientAttribute(std::string const &iName,
962  typename GradientAttribute::Getter iGetter,
963  typename GradientAttribute::Setter iSetter)
964  {
965  registerAttribute<GradientAttribute>(iName, iGetter, iSetter);
966  }
967 
971  void registerBitmapAttribute(std::string const &iName,
972  typename BitmapAttribute::Getter iGetter,
973  typename BitmapAttribute::Setter iSetter)
974  {
975  registerAttribute<BitmapAttribute>(iName, iGetter, iSetter);
976  }
977 
981  void registerFontAttribute(std::string const &iName,
982  typename FontAttribute::Getter iGetter,
983  typename FontAttribute::Setter iSetter)
984  {
985  registerAttribute<FontAttribute>(iName, iGetter, iSetter);
986  }
987 
991  void registerMarginAttribute(std::string const &iName,
992  typename MarginAttribute::Getter iGetter,
993  typename MarginAttribute::Setter iSetter)
994  {
995  registerAttribute<MarginAttribute>(iName, iGetter, iSetter);
996  }
997 
1001  void registerRangeAttribute(std::string const &iName,
1002  typename RangeAttribute::Getter iGetter,
1003  typename RangeAttribute::Setter iSetter)
1004  {
1005  registerAttribute<RangeAttribute>(iName, iGetter, iSetter);
1006  }
1007 
1011  void registerVectorStringAttribute(std::string const &iName,
1012  typename VectorStringAttribute::Getter iGetter,
1013  typename VectorStringAttribute::Setter iSetter,
1014  char iDelimiter = ',',
1015  bool iSkipEmptyEntries = false)
1016  {
1017  registerAttribute<VectorStringAttribute>(iName, iGetter, iSetter, iDelimiter, iSkipEmptyEntries);
1018  }
1019 
1036  template<typename T>
1037  void registerListAttribute(std::string const &iName,
1038  typename ListAttribute<T>::Getter iGetter,
1039  typename ListAttribute<T>::Setter iSetter,
1040  AttrValInitList<T> const &iAttributeValues)
1041  {
1042  registerAttribute<ListAttribute<T>>(iName, iGetter, iSetter, iAttributeValues);
1043  }
1044 
1048  void registerTagAttribute(std::string const &iName,
1049  typename TagAttribute::Getter iGetter,
1050  typename TagAttribute::Setter iSetter)
1051  {
1052  registerAttribute<TagAttribute>(iName, iGetter, iSetter);
1053  }
1054 
1058  template<typename TInt>
1059  void registerIntegerAttribute(std::string const &iName,
1060  typename IntegerAttribute<TInt>::Getter iGetter,
1061  typename IntegerAttribute<TInt>::Setter iSetter)
1062  {
1063  registerAttribute<IntegerAttribute<TInt>>(iName, iGetter, iSetter);
1064  }
1065 
1069  void registerIntAttribute(std::string const &iName,
1070  typename IntegerAttribute<int32_t>::Getter iGetter,
1071  typename IntegerAttribute<int32_t>::Setter iSetter)
1072  {
1073  registerIntegerAttribute<int32_t>(iName, iGetter, iSetter);
1074  }
1075 
1079  void registerFloatAttribute(std::string const &iName,
1080  typename FloatAttribute<float>::Getter iGetter,
1081  typename FloatAttribute<float>::Setter iSetter)
1082  {
1083  registerAttribute<FloatAttribute<float>>(iName, iGetter, iSetter);
1084  }
1085 
1089  void registerDoubleAttribute(std::string const &iName,
1090  typename FloatAttribute<double>::Getter iGetter,
1091  typename FloatAttribute<double>::Setter iSetter)
1092  {
1093  registerAttribute<FloatAttribute<double>>(iName, iGetter, iSetter);
1094  }
1095 
1099  void registerBooleanAttribute(std::string const &iName,
1100  typename BooleanAttribute::Getter iGetter,
1101  typename BooleanAttribute::Setter iSetter)
1102  {
1103  registerAttribute<BooleanAttribute>(iName, iGetter, iSetter);
1104  }
1105 
1109  CView *create(const UIAttributes &attributes, const IUIDescription *description) const override
1110  {
1111 #ifdef JAMBA_DEBUG_LOGGING
1112  DLOG_F(INFO, "CustomViewCreator<%s>::create()", getViewName());
1113 #endif
1114 
1115  return createCustomView<TView>(CRect(0, 0, 0, 0), attributes, description);
1116  }
1117 
1122  bool apply(CView *view, const UIAttributes &attributes, const IUIDescription *description) const override
1123  {
1124  auto *tv = dynamic_cast<TView *>(view);
1125 
1126  if(tv == nullptr)
1127  return false;
1128 
1129  for(auto attribute : fAttributes)
1130  {
1131  attribute.second->apply(tv, attributes, description);
1132  }
1133 
1134  return true;
1135  }
1136 
1137  // getAttributeNames
1138  bool getAttributeNames(std::list<std::string> &attributeNames) const override
1139  {
1140  for(auto attribute : fAttributes)
1141  {
1142  attributeNames.emplace_back(attribute.first);
1143  }
1144  return true;
1145  }
1146 
1147  // getAttributeType
1148  AttrType getAttributeType(const std::string &attributeName) const override
1149  {
1150  auto iter = fAttributes.find(attributeName);
1151  if(iter != fAttributes.cend())
1152  {
1153  return iter->second->getType();
1154  }
1155  return kUnknownType;
1156  }
1157 
1158 #ifdef EDITOR_MODE
1159 
1162  bool getAttributeValue(CView *iView,
1163  const std::string &iAttributeName,
1164  std::string &oStringValue,
1165  const IUIDescription *iDescription) const override
1166  {
1167  auto *cdv = dynamic_cast<TView *>(iView);
1168 
1169  if(cdv == nullptr)
1170  return false;
1171 
1172  auto iter = fAttributes.find(iAttributeName);
1173  if(iter != fAttributes.cend())
1174  {
1175  return iter->second->getAttributeValue(cdv, iDescription, oStringValue);
1176  }
1177 
1178  return false;
1179  }
1180 
1184  bool getPossibleListValues(const std::string &iAttributeName, std::list<const std::string *> &iValues) const override
1185  {
1186  auto iter = fAttributes.find(iAttributeName);
1187  if(iter != fAttributes.cend())
1188  {
1189  return iter->second->getPossibleListValues(iValues);
1190  }
1191  return false;
1192  }
1193 #endif
1194 
1195 private:
1196 
1197  // somehow this is required...
1198  template<typename XView>
1199  friend class TCustomViewCreator;
1200 
1204  void registerAttribute(std::shared_ptr<ViewAttribute> iAttribute)
1205  {
1206  // making sure there are no duplicates (cannot use loguru here!)
1207 #ifndef NDEBUG
1208  assert(fAttributes.find(iAttribute->getName()) == fAttributes.cend());
1209 #endif
1210  fAttributes[iAttribute->getName()] = std::move(iAttribute);
1211  }
1212 
1216  template<typename TViewAttribute, typename... Args>
1217  void registerAttribute(std::string const &iName,
1218  typename TViewAttribute::Getter iGetter,
1219  typename TViewAttribute::Setter iSetter,
1220  Args&& ...iArgs)
1221  {
1222  std::shared_ptr<ViewAttribute> cva;
1223  cva.reset(new TViewAttribute(iName, iGetter, iSetter, std::forward<Args>(iArgs)...));
1224  registerAttribute(cva);
1225  }
1226 
1227 
1228  char const *fViewName;
1229  char const *fDisplayName;
1230  char const *fBaseViewName;
1231 
1232  // use a map of shared pointers so that they can easily be copied (see registerAttributes)
1233  std::map<std::string, std::shared_ptr<ViewAttribute>> fAttributes;
1234 };
1235 
1236 namespace impl {
1237  template<typename T>
1238  using creator_ctor_t = decltype(typename T::Creator());
1239 
1240  template<typename T>
1241  constexpr auto is_creator_ctor_detected = Utils::cpp17::experimental::is_detected_v<creator_ctor_t, T>;
1242 }
1243 
1313 template<typename TView, typename TBaseView = void>
1315 {
1316 public:
1317  explicit CustomViewCreator(char const *iViewName = nullptr,
1318  char const *iDisplayName = nullptr,
1319  char const *iBaseViewName = VSTGUI::UIViewCreator::kCView) :
1320  TCustomViewCreator<TView>(iViewName, iDisplayName, iBaseViewName)
1321  {
1322  if constexpr(impl::is_creator_ctor_detected<TBaseView>)
1323  TCustomViewCreator<TView>::registerAttributes(typename TBaseView::Creator());
1324  }
1325 };
1326 
1327 }
1328 
char const * fBaseViewName
Definition: CustomViewCreator.h:1230
BitmapAttribute(std::string const &iName, typename ByValAttribute< BitmapPtr >::Getter iGetter, typename ByValAttribute< BitmapPtr >::Setter iSetter)
Definition: CustomViewCreator.h:559
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:518
CView * create(const UIAttributes &attributes, const IUIDescription *description) const override
This is the factory method which will instantiate the view.
Definition: CustomViewCreator.h:1109
void registerFloatAttribute(std::string const &iName, typename FloatAttribute< float >::Getter iGetter, typename FloatAttribute< float >::Setter iSetter)
Registers a float attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:1079
Inherit from this class to provide the factory for a custom view.
Definition: CustomViewCreator.h:1314
void registerColorAttribute(std::string const &iName, typename ColorAttribute::Getter iGetter, typename ColorAttribute::Setter iSetter)
Registers a color attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:951
void registerGradientAttribute(std::string const &iName, typename GradientAttribute::Getter iGetter, typename GradientAttribute::Setter iSetter)
Registers a gradient attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:961
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:608
IntegerAttribute(std::string const &iName, Getter iGetter, Setter iSetter)
Definition: CustomViewCreator.h:331
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:468
Generic base class that implements the logic for a ViewAttribute that uses a getter and setter in TVi...
Definition: CustomViewCreator.h:165
constexpr TagID UNDEFINED_TAG_ID
Constant used to test whether the TagID represents a valid id or an undefined one.
Definition: Types.h:61
Specialization for an float attribute (which can be a double or a float, etc..).
Definition: CustomViewCreator.h:371
TCustomViewCreator(char const *iViewName=nullptr, char const *iDisplayName=nullptr, char const *iBaseViewName=VSTGUI::UIViewCreator::kCView)
Definition: CustomViewCreator.h:894
Specialization for the margin attribute.
Definition: CustomViewCreator.h:647
ListAttribute(std::string const &iName, typename super_type::Getter iGetter, typename super_type::Setter iSetter, AttrValInitList< T > const &iAttributeValues)
Definition: CustomViewCreator.h:821
RangeAttribute(std::string const &iName, typename ByRefAttribute< Range >::Getter iGetter, typename ByRefAttribute< Range >::Setter iSetter)
Definition: CustomViewCreator.h:712
VectorStringAttribute(std::string const &iName, typename super_type::Getter iGetter, typename super_type::Setter iSetter, char iDelimiter=',', bool iSkipEmptyEntries=false)
Definition: CustomViewCreator.h:765
void registerMarginAttribute(std::string const &iName, typename MarginAttribute::Getter iGetter, typename MarginAttribute::Setter iSetter)
Registers a Margin attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:991
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, TFloat &oValue) const override
Definition: CustomViewCreator.h:388
FloatAttribute(std::string const &iName, Getter iGetter, Setter iSetter)
Definition: CustomViewCreator.h:378
void registerAttributes(TCustomViewCreator< XView > const &iOther)
This method is called to register all the attributes from another CustomViewCreator (used in case of ...
Definition: CustomViewCreator.h:937
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:181
Specialization for a vector of strings.
Definition: CustomViewCreator.h:759
FontAttribute(std::string const &iName, typename ByValAttribute< FontPtr >::Getter iGetter, typename ByValAttribute< FontPtr >::Setter iSetter)
Definition: CustomViewCreator.h:602
TSetter Setter
Definition: CustomViewCreator.h:169
AttrType getAttributeType(const std::string &attributeName) const override
Definition: CustomViewCreator.h:1148
T fTo
Definition: Lerp.h:341
void registerListAttribute(std::string const &iName, typename ListAttribute< T >::Getter iGetter, typename ListAttribute< T >::Setter iSetter, AttrValInitList< T > const &iAttributeValues)
Registers a list attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:1037
Specialization for the range attribute.
Definition: CustomViewCreator.h:709
Specialization for a bitmap attribute.
Definition: CustomViewCreator.h:555
Specialization for an Integer attribute (which can be any kind of integer, like short,...
Definition: CustomViewCreator.h:324
CustomViewCreator(char const *iViewName=nullptr, char const *iDisplayName=nullptr, char const *iBaseViewName=VSTGUI::UIViewCreator::kCView)
Definition: CustomViewCreator.h:1317
std::initializer_list< typename AttrValMap< T >::value_type > AttrValInitList
Defines the type to initialize an [AttrValMap], for an example check [TCustomViewCreator::registerLis...
Definition: CustomViewCreator.h:121
TView * createCustomView(CRect const &iSize, const UIAttributes &iAttributes, const IUIDescription *)
Factory method which creates the actual view.
Definition: CustomViewCreator.h:108
void registerTagAttribute(std::string const &iName, typename TagAttribute::Getter iGetter, typename TagAttribute::Setter iSetter)
Registers a tag attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:1048
Specialization for the color attribute.
Definition: CustomViewCreator.h:416
TAttribute< T, T const &(StepButtonView ::*)() const, void(StepButtonView ::*)(T const &)> ByRefAttribute
ByRefAttribute defines getter/setter by const reference.
Definition: CustomViewCreator.h:256
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, TagID &oValue) const override
Definition: CustomViewCreator.h:277
ParamID TagID
Defining a type for tags.
Definition: Types.h:57
TAttribute(std::string const &iName, Getter iGetter, Setter iSetter)
Definition: CustomViewCreator.h:172
std::vector< std::string > splitString(const std::string &iString, char iDelimiter, bool iSkipEmptyEntries)
Split a string according to a delimiter and returns a vector.
Definition: StringUtils.cpp:30
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, BitmapPtr &oValue) const override
Definition: CustomViewCreator.h:571
MarginAttribute(std::string const &iName, typename ByRefAttribute< Margin >::Getter iGetter, typename ByRefAttribute< Margin >::Setter iSetter)
Definition: CustomViewCreator.h:650
char const * fDisplayName
Definition: CustomViewCreator.h:1229
bool apply(CView *view, const UIAttributes &attributes, const IUIDescription *description) const override
Extract all the attribute values and apply them to the view.
Definition: CustomViewCreator.h:1122
std::string getName() const
Name of the attribute (which ends up being an attribute in the xml file) Ex: <view back-color="~ Blac...
Definition: CustomViewCreator.h:68
bool getAttributeNames(std::list< std::string > &attributeNames) const override
Definition: CustomViewCreator.h:1138
CFontDesc * FontPtr
Definition: Types.h:53
AttrValMap< T > const fAttributeValuesMap
Definition: CustomViewCreator.h:886
Specialization for a tag attribute (vst type TagID).
Definition: CustomViewCreator.h:262
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, GradientPtr &oValue) const override
Definition: CustomViewCreator.h:474
TAttribute< T, T(StepButtonView ::*)() const, void(StepButtonView ::*)(T)> ByValAttribute
ByValAttribute defines getter/setter by value (copy)
Definition: CustomViewCreator.h:250
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, FontPtr &oValue) const override
Definition: CustomViewCreator.h:614
CCoord fTop
Definition: LookAndFeel.h:58
char const * fViewName
Definition: CustomViewCreator.h:1228
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:565
ViewAttribute(std::string iName)
Definition: CustomViewCreator.h:55
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:335
TagAttribute(std::string const &iName, typename ByValAttribute< TagID >::Getter iGetter, typename ByValAttribute< TagID >::Setter iSetter)
Definition: CustomViewCreator.h:265
bool apply(CView *iView, const UIAttributes &iAttributes, const IUIDescription *iDescription) override
apply => calls the setter on the view to set the attribute (use fromString)
Definition: CustomViewCreator.h:196
TGetter Getter
Definition: CustomViewCreator.h:168
Margin is a similar concept to css: used to create space around elements, outside of any defined bord...
Definition: LookAndFeel.h:32
CCoord fRight
Definition: LookAndFeel.h:59
std::string fName
Definition: CustomViewCreator.h:100
Definition: Types.h:29
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:382
Specialization for the color attribute.
Definition: CustomViewCreator.h:457
constexpr auto is_creator_ctor_detected
Definition: CustomViewCreator.h:1241
Specialization for a bitmap attribute.
Definition: CustomViewCreator.h:598
void registerFontAttribute(std::string const &iName, typename FontAttribute::Getter iGetter, typename FontAttribute::Setter iSetter)
Registers a font attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:981
std::map< std::string, T > AttrValMap
Defines a map of string to attribute value.
Definition: CustomViewCreator.h:115
void registerAttribute(std::shared_ptr< ViewAttribute > iAttribute)
Internal method to register an attribute...
Definition: CustomViewCreator.h:1204
T fFrom
Definition: Lerp.h:340
void registerBooleanAttribute(std::string const &iName, typename BooleanAttribute::Getter iGetter, typename BooleanAttribute::Setter iSetter)
Registers a boolean attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:1099
~TCustomViewCreator() override
Definition: CustomViewCreator.h:908
decltype(typename T::Creator()) creator_ctor_t
Definition: CustomViewCreator.h:1238
Definition: CustomController.h:24
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, bool &oValue) const override
Definition: CustomViewCreator.h:524
IdStringPtr getViewName() const override
Definition: CustomViewCreator.h:916
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:427
std::map< std::string, std::shared_ptr< ViewAttribute > > fAttributes
Definition: CustomViewCreator.h:1233
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, Margin &oValue) const override
Definition: CustomViewCreator.h:656
void registerRangeAttribute(std::string const &iName, typename RangeAttribute::Getter iGetter, typename RangeAttribute::Setter iSetter)
Registers a Range attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:1001
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, std::vector< std::string > &oValue) const override
Definition: CustomViewCreator.h:776
CCoord fLeft
Definition: LookAndFeel.h:61
Specialization for a list of possible values defined by the AttributeMap
Definition: CustomViewCreator.h:815
IdStringPtr getBaseViewName() const override
Definition: CustomViewCreator.h:928
void registerIntegerAttribute(std::string const &iName, typename IntegerAttribute< TInt >::Getter iGetter, typename IntegerAttribute< TInt >::Setter iSetter)
Registers an Integer (any kind) attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:1059
void registerVectorStringAttribute(std::string const &iName, typename VectorStringAttribute::Getter iGetter, typename VectorStringAttribute::Setter iSetter, char iDelimiter=',', bool iSkipEmptyEntries=false)
Registers a Range attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:1011
GradientAttribute(std::string const &iName, typename ByValAttribute< GradientPtr >::Getter iGetter, typename ByValAttribute< GradientPtr >::Setter iSetter)
Definition: CustomViewCreator.h:462
ColorAttribute(std::string const &iName, typename ByRefAttribute< CColor >::Getter iGetter, typename ByRefAttribute< CColor >::Setter iSetter)
Definition: CustomViewCreator.h:421
void registerIntAttribute(std::string const &iName, typename IntegerAttribute< int32_t >::Getter iGetter, typename IntegerAttribute< int32_t >::Setter iSetter)
Registers an int attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:1069
UTF8StringPtr getDisplayName() const override
Definition: CustomViewCreator.h:922
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, CColor &oValue) const override
Definition: CustomViewCreator.h:433
virtual bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, T &oValue) const
Subclasses need to implement this method to convert a string (iAttributeValue) to a T.
Definition: CustomViewCreator.h:190
Generic custom view creator base class.
Definition: CustomViewCreator.h:156
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:834
void registerDoubleAttribute(std::string const &iName, typename FloatAttribute< double >::Getter iGetter, typename FloatAttribute< double >::Setter iSetter)
Registers a double attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:1089
void registerAttribute(std::string const &iName, typename TViewAttribute::Getter iGetter, typename TViewAttribute::Setter iSetter, Args &&...iArgs)
Generic register attribute.
Definition: CustomViewCreator.h:1217
CBitmap * BitmapPtr
Definition: Types.h:49
Specialization for the boolean attribute.
Definition: CustomViewCreator.h:508
CCoord fBottom
Definition: LookAndFeel.h:60
void registerBitmapAttribute(std::string const &iName, typename BitmapAttribute::Getter iGetter, typename BitmapAttribute::Setter iSetter)
Registers a bitmap attribute with the given name and getter/setter.
Definition: CustomViewCreator.h:971
constexpr ParamID UNDEFINED_PARAM_ID
Constant used throughout the code to test whether the ParamID represents a valid id or an undefined o...
Definition: Types.h:47
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, T &oValue) const override
Subclasses need to implement this method to convert a string (iAttributeValue) to a T.
Definition: CustomViewCreator.h:840
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, Range &oValue) const override
Definition: CustomViewCreator.h:718
BooleanAttribute(std::string const &iName, typename ByValAttribute< bool >::Getter iGetter, typename ByValAttribute< bool >::Setter iSetter)
Definition: CustomViewCreator.h:512
bool fromString(IUIDescription const *iDescription, std::string const &iAttributeValue, TInt &oValue) const override
Definition: CustomViewCreator.h:341
Base abstract class for an attribute of a view.
Definition: CustomViewCreator.h:51
IViewCreator::AttrType getType() override
Definition: CustomViewCreator.h:271
Setter fSetter
Definition: CustomViewCreator.h:243
CGradient * GradientPtr
Definition: Types.h:57