From 66075ceb2742e356052019710b6f2cbf929342ba Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 22 Nov 2017 11:28:22 +0200 Subject: [PATCH 01/34] GCC/MINGW: non compatible fixes to make it compilable --- tools/vsimporter/xib2nib/src/NIBWriter.cpp | 2 +- tools/vsimporter/xib2nib/src/ObjectConverter.cpp | 2 +- tools/vsimporter/xib2nib/src/UIButton.h | 1 + tools/vsimporter/xib2nib/src/UITextView.cpp | 2 +- tools/vsimporter/xib2nib/src/UITextView.h | 2 +- tools/vsimporter/xib2nib/src/XIBObject.cpp | 4 ++++ tools/vsimporter/xib2nib/src/XIBObject.h | 4 +++- tools/vsimporter/xib2nib/src/XIBObjectTypes.cpp | 2 +- tools/vsimporter/xib2nib/src/xib2nib.cpp | 9 +++++---- 9 files changed, 18 insertions(+), 10 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/NIBWriter.cpp b/tools/vsimporter/xib2nib/src/NIBWriter.cpp index 2054261883..c8c84a817f 100644 --- a/tools/vsimporter/xib2nib/src/NIBWriter.cpp +++ b/tools/vsimporter/xib2nib/src/NIBWriter.cpp @@ -22,7 +22,7 @@ #include #include #include "UIViewController.h" -#include "..\WBITelemetry\WBITelemetry.h" +#include "../WBITelemetry/WBITelemetry.h" int curPlaceholder = 1; diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp index 02c15dd127..90a92220f5 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp @@ -71,7 +71,7 @@ #include -#include "..\WBITelemetry\WBITelemetry.h" +#include "../WBITelemetry/WBITelemetry.h" #define IS_CONVERTER(newinst, classnamevar, name, type) \ if (strcmp(classnamevar, name) == 0) { \ diff --git a/tools/vsimporter/xib2nib/src/UIButton.h b/tools/vsimporter/xib2nib/src/UIButton.h index 529f472594..2359e73627 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.h +++ b/tools/vsimporter/xib2nib/src/UIButton.h @@ -16,6 +16,7 @@ #pragma once #include "UIControl.h" +#include struct EdgeInsets { float top; diff --git a/tools/vsimporter/xib2nib/src/UITextView.cpp b/tools/vsimporter/xib2nib/src/UITextView.cpp index 48b405f876..498aff1d07 100644 --- a/tools/vsimporter/xib2nib/src/UITextView.cpp +++ b/tools/vsimporter/xib2nib/src/UITextView.cpp @@ -99,7 +99,7 @@ void UITextView::InitFromStory(XIBObject* obj) { // InitFromStory is called on it XIBObject* textNode = (XIBObject*)obj->FindMemberAndHandle("text"); if (textNode) { - _text = _strdup(textNode->_node.text().as_string()); + _text = strdup(textNode->_node.text().as_string()); } _font = (UIFont*)obj->FindMemberAndHandle("fontDescription"); diff --git a/tools/vsimporter/xib2nib/src/UITextView.h b/tools/vsimporter/xib2nib/src/UITextView.h index dc311759b4..b359b5a656 100644 --- a/tools/vsimporter/xib2nib/src/UITextView.h +++ b/tools/vsimporter/xib2nib/src/UITextView.h @@ -36,5 +36,5 @@ class UITextView : public UIScrollView { UITextView(); virtual void InitFromXIB(XIBObject* obj); virtual void ConvertStaticMappings(NIBWriter* writer, XIBObject* obj); - virtual void UITextView::InitFromStory(XIBObject* obj); + virtual void InitFromStory(XIBObject* obj); }; diff --git a/tools/vsimporter/xib2nib/src/XIBObject.cpp b/tools/vsimporter/xib2nib/src/XIBObject.cpp index 1f116ae6b8..92e01a8b52 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.cpp +++ b/tools/vsimporter/xib2nib/src/XIBObject.cpp @@ -659,3 +659,7 @@ void XIBObject::getDocumentCoverage(pugi::xml_document& doc) { doc.traverse(walker); } + +XIBObject *XIBObject::createDataWriter(char *dataOut, int size) { + return new XIBObjectDataWriter(dataOut, size); +} diff --git a/tools/vsimporter/xib2nib/src/XIBObject.h b/tools/vsimporter/xib2nib/src/XIBObject.h index 3796e5e94c..defa506454 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.h +++ b/tools/vsimporter/xib2nib/src/XIBObject.h @@ -129,7 +129,7 @@ class XIBObject { char* dataOut = (char*)malloc(sizeof(TData) + 1); dataOut[0] = 6; memcpy(&dataOut[1], &data, sizeof(TData)); - AddOutputMember(writer, strdup(pPropName), new XIBObjectDataWriter(dataOut, sizeof(TData) + 1)); + AddOutputMember(writer, strdup(pPropName), createDataWriter(dataOut, sizeof(TData) + 1)); } void AddSize(NIBWriter* writer, char* pPropName, CGSize size); @@ -151,5 +151,7 @@ class XIBObject { const char* getAttrAndHandle(const char* name); XIBObject* FindMemberAndHandle(char* keyName); +private: + XIBObject* createDataWriter(char *dataOut, int size); }; #endif diff --git a/tools/vsimporter/xib2nib/src/XIBObjectTypes.cpp b/tools/vsimporter/xib2nib/src/XIBObjectTypes.cpp index 2d7f771f73..213e1f907c 100644 --- a/tools/vsimporter/xib2nib/src/XIBObjectTypes.cpp +++ b/tools/vsimporter/xib2nib/src/XIBObjectTypes.cpp @@ -43,7 +43,7 @@ XIBObjectString::XIBObjectString(const char* str) { } void XIBObjectString::InitFromStory(XIBObject* obj) { - _strVal = _strdup(obj->_node.text().as_string()); + _strVal = strdup(obj->_node.text().as_string()); } const char* XIBObjectString::stringValue() { diff --git a/tools/vsimporter/xib2nib/src/xib2nib.cpp b/tools/vsimporter/xib2nib/src/xib2nib.cpp index ac071f2074..75ed45d36c 100644 --- a/tools/vsimporter/xib2nib/src/xib2nib.cpp +++ b/tools/vsimporter/xib2nib/src/xib2nib.cpp @@ -19,10 +19,11 @@ #include #include #include -#include +//#include #include #include -#include +//#include +#include #include "XIBObject.h" #include "XIBObjectTypes.h" @@ -32,7 +33,7 @@ #include "miscutils.h" #include "versionutils.h" -#include "..\WBITelemetry\WBITelemetry.h" +#include "../WBITelemetry/WBITelemetry.h" // These globals should only be employed when dealing with storyboard files (.storyboard) // They are only set once when we determine that the input format is a storyboard @@ -248,7 +249,7 @@ int main(int argc, char* argv[]) { } TELEMETRY_SET_INTERNAL(isMSFTInternalMachine()); - string machineID = getMachineID(); + std::string machineID = getMachineID(); if (!machineID.empty()) { TELEMETRY_SET_MACHINEID(machineID.c_str()); } From 3fdf411f4dac6ef2f296f57b2f77479a64772a11 Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 22 Nov 2017 11:36:55 +0200 Subject: [PATCH 02/34] fixed: nil object type --- tools/vsimporter/xib2nib/src/ObjectConverter.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp index 90a92220f5..90c38f4cc2 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp @@ -207,6 +207,7 @@ XIBObject* ObjectConverter::ConverterForStoryObject(const char* className, pugi: IS_CONVERTER(ret, className, "pongPressGestureRecognizer", UIPongPressGestureRecognizer) IS_CONVERTER(ret, className, "customObject", ObjectConverterSwapper) + IS_CONVERTER(ret, className, "nil", XIBObjectNil) if (ret == NULL) { TELEMETRY_EVENT_DATA(L"UnRecognizedTag", className); From 90da0a6265ea905795e686978a1b3aa07c5fcf35 Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 22 Nov 2017 11:40:30 +0200 Subject: [PATCH 03/34] fixed: written proper NIB header values --- tools/vsimporter/xib2nib/src/NIBWriter.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/tools/vsimporter/xib2nib/src/NIBWriter.cpp b/tools/vsimporter/xib2nib/src/NIBWriter.cpp index c8c84a817f..87dddd8b5a 100644 --- a/tools/vsimporter/xib2nib/src/NIBWriter.cpp +++ b/tools/vsimporter/xib2nib/src/NIBWriter.cpp @@ -79,7 +79,8 @@ XIBObject* NIBWriter::AddOutputObject(XIBObject* pObj) { } typedef struct { - int _a, _b; + int _numHeaders; + int _sizeDw; int _numObjects; // 2 int _objectsOffset; // 3 int _numKeyNames; // 4 @@ -451,6 +452,9 @@ void NIBWriter::WriteData() { header._numObjects++; } + header._numHeaders = 1; + header._sizeDw = 9; + fseek(fpOut, headerPos, SEEK_SET); fwrite(&header, sizeof(header), 1, fpOut); } From c5908ff63d9c9171756291bb26da25766d505ab0 Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 22 Nov 2017 11:42:32 +0200 Subject: [PATCH 04/34] fixed: class entry and class name output to nib --- tools/vsimporter/xib2nib/src/NIBWriter.cpp | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/NIBWriter.cpp b/tools/vsimporter/xib2nib/src/NIBWriter.cpp index 87dddd8b5a..29f1422f9a 100644 --- a/tools/vsimporter/xib2nib/src/NIBWriter.cpp +++ b/tools/vsimporter/xib2nib/src/NIBWriter.cpp @@ -380,11 +380,9 @@ void NIBWriter::WriteData() { for (int i = 0; i < classNames._numStrings; i++) { char* pName = classNames._stringTable[i]; int len = strlen(pName) + 1; - WriteInt(len, 2); - if (len == 0x1b) { - int filler = 6; - fwrite(&filler, 1, 4, fpOut); - } + WriteInt(len, 1); + int tp = 0x80; + fwrite(&tp, 1, 1, fpOut); fwrite(pName, 1, len, fpOut); header._numClassNames++; @@ -403,7 +401,7 @@ void NIBWriter::WriteData() { for (int i = 0; i < keyNames._numStrings; i++) { char* pName = keyNames._stringTable[i]; - int len = strlen(pName) + 1; + int len = strlen(pName); WriteInt(len, 1); fwrite(pName, 1, len, fpOut); From 804ea0d3f5a3520b24b67445aa85f8a704d1da90 Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 22 Nov 2017 11:53:41 +0200 Subject: [PATCH 05/34] fixed2: connections now handled in one place: ObjectConverter otherwise it resulted in duplicate ones fixed2: UIOutletCollection is now one to many map(as in recent nib) instead of n entries --- .../xib2nib/src/ObjectConverter.cpp | 89 +++++++++++-------- .../vsimporter/xib2nib/src/ObjectConverter.h | 3 + .../vsimporter/xib2nib/src/UIProxyObject.cpp | 28 ------ .../UIRuntimeOutletCollectionConnection.cpp | 29 +++++- .../src/UIRuntimeOutletCollectionConnection.h | 4 +- tools/vsimporter/xib2nib/src/UIView.cpp | 16 ---- 6 files changed, 83 insertions(+), 86 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp index 90c38f4cc2..76bca9b5c5 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp @@ -69,6 +69,7 @@ #include "UIProgressView.h" #include "UIPongPressGestureRecognizer.h" +#include #include #include "../WBITelemetry/WBITelemetry.h" @@ -250,6 +251,56 @@ void ObjectConverter::InitFromStory(XIBObject* obj) { _connections = (XIBArray*)FindMemberClass("connections"); } void ObjectConverter::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { + if (_connections) { + std::map outletCollectionMap; + + for (int i = 0; i < _connections->count(); i++) { + XIBObject* curObj = _connections->objectAtIndex(i); + if (strcmp(curObj->_outputClassName, "UIRuntimeOutletConnection") == 0) { + UIRuntimeOutletConnection* cur = (UIRuntimeOutletConnection*)curObj; + + UIRuntimeOutletConnection* newOutlet = new UIRuntimeOutletConnection(); + newOutlet->_label = cur->_label; + newOutlet->_source = cur->_source; + newOutlet->_destination = cur->_destination; + writer->_connections->AddMember(NULL, newOutlet); + writer->AddOutputObject(newOutlet); + } else if (strcmp(curObj->_outputClassName, "UIRuntimeEventConnection") == 0) { + UIRuntimeEventConnection* cur = (UIRuntimeEventConnection*)curObj; + + UIRuntimeEventConnection* newOutlet = new UIRuntimeEventConnection(); + newOutlet->_label = cur->_label; + newOutlet->_source = cur->_source; + newOutlet->_destination = cur->_destination; + newOutlet->_eventMask = cur->_eventMask; + writer->_connections->AddMember(NULL, newOutlet); + writer->AddOutputObject(newOutlet); + } else if (strcmp(curObj->_outputClassName, "UIRuntimeOutletCollectionConnection") == 0) { + UIRuntimeOutletCollectionConnection* cur = (UIRuntimeOutletCollectionConnection*)curObj; + + UIRuntimeOutletCollectionConnection* collection = outletCollectionMap[cur->_label]; + if (!collection) { + collection = new UIRuntimeOutletCollectionConnection(); + collection->_label = cur->_label; + collection->_source = cur->_source; + collection->addDestinations(cur->_destinations); + collection->_collectionClassName = cur->_collectionClassName; + outletCollectionMap[cur->_label] = collection; + } else { + collection->addDestinations(cur->_destinations); + } + } else { + assert(0); + } + } + + // drop collections if any + for( const auto& entry : outletCollectionMap ) { + writer->_connections->AddMember(NULL, entry.second); + writer->AddOutputObject(entry.second); + } + } + } ObjectConverter* ObjectConverter::Clone() { return this; @@ -295,42 +346,4 @@ void ObjectConverterSwapper::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj->AddOutputMember(writer, "UIClassName", new XIBObjectString(obj->_swappedClassName)); obj->_outputClassName = "UIClassSwapper"; } - - // Add outlets - if (_connectedObjects) { - for (int i = 0; i < _connectedObjects->count(); i++) { - XIBObject* curObj = (UIRuntimeOutletConnection*)_connectedObjects->objectAtIndex(i); - if (strcmp(curObj->_outputClassName, "UIRuntimeOutletConnection") == 0) { - UIRuntimeOutletConnection* cur = (UIRuntimeOutletConnection*)curObj; - - UIRuntimeOutletConnection* newOutlet = new UIRuntimeOutletConnection(); - newOutlet->_label = cur->_label; - newOutlet->_source = cur->_source; - newOutlet->_destination = cur->_destination; - writer->_connections->AddMember(NULL, newOutlet); - writer->AddOutputObject(newOutlet); - } else if (strcmp(curObj->_outputClassName, "UIRuntimeEventConnection") == 0) { - UIRuntimeEventConnection* cur = (UIRuntimeEventConnection*)curObj; - - UIRuntimeEventConnection* newOutlet = new UIRuntimeEventConnection(); - newOutlet->_label = cur->_label; - newOutlet->_source = cur->_source; - newOutlet->_destination = cur->_destination; - newOutlet->_eventMask = cur->_eventMask; - writer->_connections->AddMember(NULL, newOutlet); - writer->AddOutputObject(newOutlet); - } else if (strcmp(curObj->_outputClassName, "UIRuntimeOutletCollectionConnection") == 0) { - UIRuntimeOutletCollectionConnection* cur = (UIRuntimeOutletCollectionConnection*)curObj; - - UIRuntimeOutletCollectionConnection* newOutlet = new UIRuntimeOutletCollectionConnection(); - newOutlet->_label = cur->_label; - newOutlet->_source = cur->_source; - newOutlet->_destination = cur->_destination; - writer->_connections->AddMember(NULL, newOutlet); - writer->AddOutputObject(newOutlet); - } else { - assert(0); - } - } - } } diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.h b/tools/vsimporter/xib2nib/src/ObjectConverter.h index 0b95ec31cf..090e68618f 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.h +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.h @@ -28,6 +28,9 @@ class ObjectConverter : public XIBObject { XIBArray* _connections; XIBArray* _variations; + ObjectConverter() { + _connections = NULL; + }; virtual void InitFromXIB(XIBObject* obj); virtual void InitFromStory(XIBObject* obj); virtual void ConvertStaticMappings(NIBWriter* writer, XIBObject* obj); diff --git a/tools/vsimporter/xib2nib/src/UIProxyObject.cpp b/tools/vsimporter/xib2nib/src/UIProxyObject.cpp index 4e6dbfe67d..8a4df8f15c 100644 --- a/tools/vsimporter/xib2nib/src/UIProxyObject.cpp +++ b/tools/vsimporter/xib2nib/src/UIProxyObject.cpp @@ -39,34 +39,6 @@ void UIProxyObject::InitFromStory(XIBObject* obj) { } void UIProxyObject::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { - // Add outlets - if (_connectedObjects) { - for (int i = 0; i < _connectedObjects->count(); i++) { - XIBObject* curObj = (UIRuntimeOutletConnection*)_connectedObjects->objectAtIndex(i); - if (strcmp(curObj->_outputClassName, "UIRuntimeOutletConnection") == 0) { - UIRuntimeOutletConnection* cur = (UIRuntimeOutletConnection*)curObj; - - UIRuntimeOutletConnection* newOutlet = new UIRuntimeOutletConnection(); - newOutlet->_label = cur->_label; - newOutlet->_source = cur->_source; - newOutlet->_destination = cur->_destination; - writer->_connections->AddMember(NULL, newOutlet); - writer->AddOutputObject(newOutlet); - } else if (strcmp(curObj->_outputClassName, "UIRuntimeEventConnection") == 0) { - UIRuntimeEventConnection* cur = (UIRuntimeEventConnection*)curObj; - - UIRuntimeEventConnection* newOutlet = new UIRuntimeEventConnection(); - newOutlet->_label = cur->_label; - newOutlet->_source = cur->_source; - newOutlet->_destination = cur->_destination; - newOutlet->_eventMask = cur->_eventMask; - writer->_connections->AddMember(NULL, newOutlet); - writer->AddOutputObject(newOutlet); - } else { - assert(0); - } - } - } writer->_allUIObjects->AddMember(NULL, obj); AddString(writer, "UIProxiedObjectIdentifier", _identifier); diff --git a/tools/vsimporter/xib2nib/src/UIRuntimeOutletCollectionConnection.cpp b/tools/vsimporter/xib2nib/src/UIRuntimeOutletCollectionConnection.cpp index c37d5bd2be..bb27ac7d68 100644 --- a/tools/vsimporter/xib2nib/src/UIRuntimeOutletCollectionConnection.cpp +++ b/tools/vsimporter/xib2nib/src/UIRuntimeOutletCollectionConnection.cpp @@ -21,6 +21,7 @@ UIRuntimeOutletCollectionConnection::UIRuntimeOutletCollectionConnection() { _outputClassName = "UIRuntimeOutletCollectionConnection"; _className = "UIRuntimeOutletCollectionConnection"; _collectionClassName = NULL; + _destinations = NULL; _addsToExisting = false; } @@ -30,7 +31,13 @@ void UIRuntimeOutletCollectionConnection::InitFromXIB(XIBObject* obj) { _outputClassName = "UIRuntimeOutletCollectionConnection"; _label = obj->GetString("label", NULL); _source = obj->FindMember("source"); - _destination = obj->FindMember("destination"); + XIBObject* destObj = obj->FindMember("destination"); + if (destObj) { + _destinations = new XIBArray(); + _destinations->_className = "NSMutableArray"; + _destinations->AddMember(NULL, destObj); + } + _collectionClassName = obj->GetString("cachedDesigntimeCollectionClassName", NULL); _addsToExisting = obj->GetBool("addsContentToExistingCollection", false); } @@ -49,7 +56,11 @@ void UIRuntimeOutletCollectionConnection::InitFromStory(XIBObject* obj) { _source = _parent->_parent; ObjectConverter* destObj = (ObjectConverter*)findReference(destId); - _destination = destObj; + if (destObj) { + _destinations = new XIBArray(); + _destinations->_className = "NSMutableArray"; + _destinations->AddMember(NULL, destObj); + } // Check if the destination property is part of our heirarchy XIBObject* curObj = this; @@ -70,7 +81,19 @@ void UIRuntimeOutletCollectionConnection::ConvertStaticMappings(NIBWriter* write ObjectConverter::ConvertStaticMappings(writer, obj); AddString(writer, "UILabel", _label); AddOutputMember(writer, "UISource", _source); - AddOutputMember(writer, "UIDestination", _destination); + AddOutputMember(writer, "UIDestination", _destinations); AddString(writer, "runtimeCollectionClassName", _collectionClassName); AddBool(writer, "addsContentToExistingCollection", _addsToExisting); } + +void UIRuntimeOutletCollectionConnection::addDestinations(XIBArray *objs) { + if (!objs || objs->count() == 0) + return; + if (!_destinations) { + _destinations = new XIBArray(); + _destinations->_className = "NSMutableArray"; + } + + for (int i = 0; i < objs->count(); i++) + _destinations->AddMember(NULL, objs->objectAtIndex(i)); +} diff --git a/tools/vsimporter/xib2nib/src/UIRuntimeOutletCollectionConnection.h b/tools/vsimporter/xib2nib/src/UIRuntimeOutletCollectionConnection.h index 20ad732bad..6e982c3b4c 100644 --- a/tools/vsimporter/xib2nib/src/UIRuntimeOutletCollectionConnection.h +++ b/tools/vsimporter/xib2nib/src/UIRuntimeOutletCollectionConnection.h @@ -19,13 +19,15 @@ class UIRuntimeOutletCollectionConnection : public ObjectConverter { public: const char* _label; - XIBObject *_source, *_destination; + XIBObject *_source; const char* _collectionClassName; bool _addsToExisting; public: + XIBArray *_destinations; UIRuntimeOutletCollectionConnection(); + void addDestinations(XIBArray* objs); virtual void InitFromXIB(XIBObject* obj); virtual void InitFromStory(XIBObject* obj); virtual void ConvertStaticMappings(NIBWriter* writer, XIBObject* obj); diff --git a/tools/vsimporter/xib2nib/src/UIView.cpp b/tools/vsimporter/xib2nib/src/UIView.cpp index 62696873ca..61ff78b1a7 100644 --- a/tools/vsimporter/xib2nib/src/UIView.cpp +++ b/tools/vsimporter/xib2nib/src/UIView.cpp @@ -285,22 +285,6 @@ void UIView::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { writer->_allUIObjects->AddMember(NULL, this); } - if (_connections) { - for (int i = 0; i < _connections->count(); i++) { - XIBObject* curObj = _connections->objectAtIndex(i); - if (strcmp(curObj->_outputClassName, "UIRuntimeOutletCollectionConnection") == 0) { - UIRuntimeOutletCollectionConnection* cur = (UIRuntimeOutletCollectionConnection*)curObj; - - UIRuntimeOutletCollectionConnection* newOutlet = new UIRuntimeOutletCollectionConnection(); - newOutlet->_label = cur->_label; - newOutlet->_source = cur->_source; - newOutlet->_destination = cur->_destination; - writer->_connections->AddMember(NULL, newOutlet); - writer->AddOutputObject(newOutlet); - } - } - } - if (_subviews->count() > 0) { int count = _subviews->count(); for (int i = 0; i < count; i++) { From f497bf89085e9505c0adb9de29a79934bd096184 Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 22 Nov 2017 11:56:12 +0200 Subject: [PATCH 06/34] fixed: structs migrated from float to double as in recent nib --- tools/vsimporter/xib2nib/src/UIButton.h | 8 ++++---- tools/vsimporter/xib2nib/src/XIBObject.h | 11 ++++++----- 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/UIButton.h b/tools/vsimporter/xib2nib/src/UIButton.h index 2359e73627..0c923abb37 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.h +++ b/tools/vsimporter/xib2nib/src/UIButton.h @@ -19,10 +19,10 @@ #include struct EdgeInsets { - float top; - float left; - float bottom; - float right; + double top; + double left; + double bottom; + double right; EdgeInsets() : top(INFINITY), left(INFINITY), bottom(INFINITY), right(INFINITY) { } diff --git a/tools/vsimporter/xib2nib/src/XIBObject.h b/tools/vsimporter/xib2nib/src/XIBObject.h index defa506454..8f6fb5c122 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.h +++ b/tools/vsimporter/xib2nib/src/XIBObject.h @@ -46,14 +46,15 @@ class XIBArray; #include "NIBWriter.h" -typedef struct { float width, height; } CGSize; +typedef struct { + double width, height; } CGSize; typedef struct { - float x, y; - float width, height; + double x, y; + double width, height; } UIRect; -typedef struct { float x, y; } UIPoint; +typedef struct { double x, y; } UIPoint; const char* getNodeAttrib(pugi::xml_node node, const char* name); @@ -127,7 +128,7 @@ class XIBObject { template void AddData(NIBWriter* writer, char* pPropName, const TData& data) { char* dataOut = (char*)malloc(sizeof(TData) + 1); - dataOut[0] = 6; + dataOut[0] = 7; // NIBOBJ_DOUBLE TODO: works only with DOUBLE entries memcpy(&dataOut[1], &data, sizeof(TData)); AddOutputMember(writer, strdup(pPropName), createDataWriter(dataOut, sizeof(TData) + 1)); } From 240739dc31464e5476a21bf578de39667a36304c Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 22 Nov 2017 12:06:53 +0200 Subject: [PATCH 07/34] fixed: wrong limit check when writing integers fixed: not saving real values XIBObjectNumber moved to separate location and extended with extra types --- tools/vsimporter/xib2nib/src/XIBObjectInt.cpp | 34 ++++++------- tools/vsimporter/xib2nib/src/XIBObjectInt.h | 12 ++--- .../xib2nib/src/XIBObjectNumber.cpp | 51 +++++++++++++++++++ .../vsimporter/xib2nib/src/XIBObjectNumber.h | 31 +++++++++++ .../vsimporter/xib2nib/src/XIBObjectTypes.cpp | 9 +++- tools/vsimporter/xib2nib/src/XIBObjectTypes.h | 4 ++ 6 files changed, 111 insertions(+), 30 deletions(-) create mode 100644 tools/vsimporter/xib2nib/src/XIBObjectNumber.cpp create mode 100644 tools/vsimporter/xib2nib/src/XIBObjectNumber.h diff --git a/tools/vsimporter/xib2nib/src/XIBObjectInt.cpp b/tools/vsimporter/xib2nib/src/XIBObjectInt.cpp index e803bb0f10..2184bb056a 100644 --- a/tools/vsimporter/xib2nib/src/XIBObjectInt.cpp +++ b/tools/vsimporter/xib2nib/src/XIBObjectInt.cpp @@ -15,8 +15,9 @@ //****************************************************************************** #include "XIBObjectInt.h" +#include -XIBObjectInt::XIBObjectInt(int val) { +XIBObjectInt::XIBObjectInt(long long val) { _val = val; } @@ -24,32 +25,27 @@ int XIBObjectInt::intValue() { return _val; } +long long XIBObjectInt::longValue() { + return _val; +} + bool XIBObjectInt::NeedsSerialization() { return false; } void XIBObjectInt::WriteData(NIBWriter* writer) { - unsigned int fullVal = (unsigned int)_val; - - if (fullVal <= 0xFF) { + if (_val >= SCHAR_MIN && _val <= SCHAR_MAX) { writer->WriteByte(NIBOBJ_INT8); - writer->WriteBytes(&fullVal, 1); - } else if (fullVal <= 0xFFFF) { + writer->WriteBytes(&_val, 1); + } else if (_val >= SHRT_MIN && _val <= SHRT_MAX) { writer->WriteByte(NIBOBJ_INT16); - writer->WriteBytes(&fullVal, 2); - } else { + writer->WriteBytes(&_val, 2); + } else if (_val >= INT_MIN && _val <= INT_MAX) { writer->WriteByte(NIBOBJ_INT32); - writer->WriteBytes(&fullVal, 4); + writer->WriteBytes(&_val, 4); + } else { + writer->WriteByte(NIBOBJ_INT64); + writer->WriteBytes(&_val, 8); } } -XIBObjectNumber::XIBObjectNumber(int num) { - _val = num; - _className = "NSNumber"; -} - -void XIBObjectNumber::EmitObject(NIBWriter* writer) { - _outputClassName = "NSNumber"; - - AddOutputMember(writer, "NS.intval", new XIBObjectInt(_val)); -} diff --git a/tools/vsimporter/xib2nib/src/XIBObjectInt.h b/tools/vsimporter/xib2nib/src/XIBObjectInt.h index 7f0ac99956..6dcc620932 100644 --- a/tools/vsimporter/xib2nib/src/XIBObjectInt.h +++ b/tools/vsimporter/xib2nib/src/XIBObjectInt.h @@ -21,11 +21,12 @@ class XIBObjectInt : public XIBObject { private: - int _val; + long long _val; public: - XIBObjectInt(int val); + XIBObjectInt(long long val); int intValue(); + long long longValue(); virtual bool NeedsSerialization(); void WriteData(NIBWriter* writer); }; @@ -40,12 +41,5 @@ class XIBObjectDataWriter : public XIBObject { void WriteData(NIBWriter* writer); }; -class XIBObjectNumber : public XIBObject { - int _val; - -public: - XIBObjectNumber(int val); - void EmitObject(NIBWriter* writer); -}; #endif \ No newline at end of file diff --git a/tools/vsimporter/xib2nib/src/XIBObjectNumber.cpp b/tools/vsimporter/xib2nib/src/XIBObjectNumber.cpp new file mode 100644 index 0000000000..dfe561c4b5 --- /dev/null +++ b/tools/vsimporter/xib2nib/src/XIBObjectNumber.cpp @@ -0,0 +1,51 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#include "XIBObjectNumber.h" +#include "XIBObjectInt.h" +#include "XIBObjectDouble.h" + +XIBObjectNumber::XIBObjectNumber(int num) { + _className = "NSNumber"; + _keyName = "NS.intval"; + _val = new XIBObjectInt(num); +} + +XIBObjectNumber::XIBObjectNumber(long long num) { + _className = "NSNumber"; + _keyName = "NS.intval"; + _val = new XIBObjectInt(num); +} + +XIBObjectNumber::XIBObjectNumber(bool val) { + _className = "NSNumber"; + _keyName = "NS.intval"; + _val = new XIBObjectInt(val ? 1 : 0); +} + +XIBObjectNumber::XIBObjectNumber(double val) { + _className = "NSNumber"; + _keyName = "NS.dblval"; + _val = new XIBObjectDouble(val); +} + +void XIBObjectNumber::EmitObject(NIBWriter* writer) { + _outputClassName = "NSNumber"; + + AddOutputMember(writer, _keyName, _val); +} + + diff --git a/tools/vsimporter/xib2nib/src/XIBObjectNumber.h b/tools/vsimporter/xib2nib/src/XIBObjectNumber.h new file mode 100644 index 0000000000..30ce425da8 --- /dev/null +++ b/tools/vsimporter/xib2nib/src/XIBObjectNumber.h @@ -0,0 +1,31 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + + +#pragma once +#include "XIBObject.h" + +class XIBObjectNumber : public XIBObject { + XIBObject *_val; + const char *_keyName; +public: + explicit XIBObjectNumber(long long val); + explicit XIBObjectNumber(int val); + explicit XIBObjectNumber(bool val); + explicit XIBObjectNumber(double val); + void EmitObject(NIBWriter* writer); +}; + diff --git a/tools/vsimporter/xib2nib/src/XIBObjectTypes.cpp b/tools/vsimporter/xib2nib/src/XIBObjectTypes.cpp index 213e1f907c..6f2d7dc784 100644 --- a/tools/vsimporter/xib2nib/src/XIBObjectTypes.cpp +++ b/tools/vsimporter/xib2nib/src/XIBObjectTypes.cpp @@ -190,17 +190,22 @@ int XIBObjectBool::intValue() { } XIBObjectReal::XIBObjectReal(pugi::xml_node node) { + _val = strtod(node.child_value(), NULL); _node = node; } +XIBObjectReal::XIBObjectReal(double val) { + _val = val; +}; + + bool XIBObjectReal::NeedsSerialization() { return false; } void XIBObjectReal::WriteData(NIBWriter* writer) { writer->WriteByte(NIBOBJ_DOUBLE); - double dVal = 0.0f; - writer->WriteBytes(&dVal, 8); + writer->WriteBytes(&_val, 8); } XIBArray::XIBArray(pugi::xml_node node) { diff --git a/tools/vsimporter/xib2nib/src/XIBObjectTypes.h b/tools/vsimporter/xib2nib/src/XIBObjectTypes.h index 29e5326d6f..b56b272c8f 100644 --- a/tools/vsimporter/xib2nib/src/XIBObjectTypes.h +++ b/tools/vsimporter/xib2nib/src/XIBObjectTypes.h @@ -21,6 +21,7 @@ #include "XIBObjectFloat.h" #include "XIBObjectDouble.h" #include "XIBObjectInt.h" +#include "XIBObjectNumber.h" #include "XIBDictionary.h" #include "XIBObjectNil.h" @@ -60,8 +61,11 @@ class XIBObjectBool : public XIBObject { }; class XIBObjectReal : public XIBObject { +private: + double _val; public: XIBObjectReal(pugi::xml_node node); + XIBObjectReal(double val); virtual bool NeedsSerialization(); void WriteData(NIBWriter* writer); }; From 9188701042e431c4c39c8009587e692df9477103 Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 22 Nov 2017 12:08:03 +0200 Subject: [PATCH 08/34] fixed: UIColor copy creation (instead of copy self was modified) --- tools/vsimporter/xib2nib/src/UIColor.cpp | 30 ++++++++++++------------ 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/UIColor.cpp b/tools/vsimporter/xib2nib/src/UIColor.cpp index 3510c62915..2fca8cc819 100644 --- a/tools/vsimporter/xib2nib/src/UIColor.cpp +++ b/tools/vsimporter/xib2nib/src/UIColor.cpp @@ -152,19 +152,19 @@ void UIColor::InitFromStory(XIBObject* obj) { void UIColor::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { if (!_outputClassName) - _outputClassName = "UIColor"; + obj->_outputClassName = "UIColor"; if (!_isStory) { switch (_colorSpaceOut) { case colorSpaceRGB: case colorSpaceFull: if (_r == _g && _r == _b) { - AddOutputMember(writer, "UIWhite", new XIBObjectFloat(_r)); + obj->AddOutputMember(writer, "UIWhite", new XIBObjectFloat(_r)); } - AddOutputMember(writer, "UIRed", new XIBObjectFloat(_r)); - AddOutputMember(writer, "UIGreen", new XIBObjectFloat(_g)); - AddOutputMember(writer, "UIBlue", new XIBObjectFloat(_b)); - AddOutputMember(writer, "UIAlpha", new XIBObjectFloat(_a)); + obj->AddOutputMember(writer, "UIRed", new XIBObjectFloat(_r)); + obj->AddOutputMember(writer, "UIGreen", new XIBObjectFloat(_g)); + obj->AddOutputMember(writer, "UIBlue", new XIBObjectFloat(_b)); + obj->AddOutputMember(writer, "UIAlpha", new XIBObjectFloat(_a)); break; default: @@ -172,27 +172,27 @@ void UIColor::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { } if (_systemName) { - AddString(writer, "UISystemColorName", _systemName); - AddString(writer, "UIPatternSelector", _systemName); + obj->AddString(writer, "UISystemColorName", _systemName); + obj->AddString(writer, "UIPatternSelector", _systemName); } } else { switch (_colorSpaceOut) { case colorSpaceWhite: - AddOutputMember(writer, "UIWhite", new XIBObjectFloat(_white)); - AddOutputMember(writer, "UIAlpha", new XIBObjectFloat(_a)); + obj->AddOutputMember(writer, "UIWhite", new XIBObjectFloat(_white)); + obj->AddOutputMember(writer, "UIAlpha", new XIBObjectFloat(_a)); break; case colorSpaceRGB: case colorSpaceFull: - AddOutputMember(writer, "UIAlpha", new XIBObjectFloat(_a)); - AddOutputMember(writer, "UIRed", new XIBObjectFloat(_r)); - AddOutputMember(writer, "UIGreen", new XIBObjectFloat(_g)); - AddOutputMember(writer, "UIBlue", new XIBObjectFloat(_b)); + obj->AddOutputMember(writer, "UIAlpha", new XIBObjectFloat(_a)); + obj->AddOutputMember(writer, "UIRed", new XIBObjectFloat(_r)); + obj->AddOutputMember(writer, "UIGreen", new XIBObjectFloat(_g)); + obj->AddOutputMember(writer, "UIBlue", new XIBObjectFloat(_b)); break; } if (_systemName) { - AddString(writer, "UISystemColorName", _systemName); + obj->AddString(writer, "UISystemColorName", _systemName); } } } From 9e50b656b82eecacdee557c69f84185b9e852f0a Mon Sep 17 00:00:00 2001 From: dkimitsa Date: Wed, 22 Nov 2017 12:13:42 +0200 Subject: [PATCH 09/34] added: support for key-value pairs and user defined attributes --- tools/vsimporter/xib2nib/src/NIBWriter.cpp | 3 +- tools/vsimporter/xib2nib/src/NIBWriter.h | 1 + .../xib2nib/src/ObjectConverter.cpp | 13 ++ .../vsimporter/xib2nib/src/ObjectConverter.h | 2 + .../xib2nib/src/UINibKeyValuePair.cpp | 111 ++++++++++++++++++ .../xib2nib/src/UINibKeyValuePair.h | 30 +++++ tools/vsimporter/xib2nib/src/XIBObject.h | 2 + tools/vsimporter/xib2nib/src/XIBObjectValue.h | 91 ++++++++++++++ 8 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp create mode 100644 tools/vsimporter/xib2nib/src/UINibKeyValuePair.h create mode 100644 tools/vsimporter/xib2nib/src/XIBObjectValue.h diff --git a/tools/vsimporter/xib2nib/src/NIBWriter.cpp b/tools/vsimporter/xib2nib/src/NIBWriter.cpp index 29f1422f9a..0e1689b43f 100644 --- a/tools/vsimporter/xib2nib/src/NIBWriter.cpp +++ b/tools/vsimporter/xib2nib/src/NIBWriter.cpp @@ -148,6 +148,7 @@ NIBWriter::NIBWriter(FILE* out, XIBDictionary* externalReferences, XIBObject* ba _connections = new XIBArray(); _topObjects = new XIBArray(); _visibleWindows = new XIBArray(); + _keyValuePairs = new XIBArray(); _accessibilityObjects = new XIBAccessibilityArray(); } @@ -166,7 +167,7 @@ void NIBWriter::WriteObjects() { nibRoot->AddMember("UINibConnectionsKey", _connections); nibRoot->AddMember("UINibVisibleWindowsKey", _visibleWindows); nibRoot->AddMember("UINibAccessibilityConfigurationsKey", _accessibilityObjects); - nibRoot->AddMember("UINibKeyValuePairsKey", new XIBArray()); + nibRoot->AddMember("UINibKeyValuePairsKey", _keyValuePairs); AddOutputObject(nibRoot); // Sort connection records alphabetically using stable, uh, bubble sort diff --git a/tools/vsimporter/xib2nib/src/NIBWriter.h b/tools/vsimporter/xib2nib/src/NIBWriter.h index f8cde440a6..87e55e4e0f 100644 --- a/tools/vsimporter/xib2nib/src/NIBWriter.h +++ b/tools/vsimporter/xib2nib/src/NIBWriter.h @@ -54,6 +54,7 @@ class NIBWriter { XIBObject* _topObjects; XIBObject* _accessibilityObjects; XIBObject* _visibleWindows; + XIBObject* _keyValuePairs; XIBDictionary* _externalReferencesDictionary; diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp index 76bca9b5c5..cc3761565c 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp @@ -68,6 +68,7 @@ #include "UIStackView.h" #include "UIProgressView.h" #include "UIPongPressGestureRecognizer.h" +#include "UINibKeyValuePair.h" #include #include @@ -199,6 +200,9 @@ XIBObject* ObjectConverter::ConverterForStoryObject(const char* className, pugi: IS_CONVERTER(ret, className, "swipeGestureRecognizer", UISwipeGestureRecognizer) IS_CONVERTER(ret, className, "tapGestureRecognizer", UITapGestureRecognizer) IS_CONVERTER(ret, className, "window", UIWindow) + // support for user defined attributes (and IBInspectable) + IS_CONVERTER(ret, className, "userDefinedRuntimeAttribute", UINibKeyValuePair) + IS_CONVERTER(ret, className, "userDefinedRuntimeAttributes", XIBArray) // Stubbed mapping - full functionality is not provided but these stubs will unblock the import process IS_CONVERTER(ret, className, "pageControl", UIPageControl) @@ -244,11 +248,13 @@ void ConvertOffset(struct _PropertyMapper* prop, NIBWriter* writer, XIBObject* p void ObjectConverter::InitFromXIB(XIBObject* obj) { _connections = NULL; + _userDefinedAttributes = NULL; _connectedObjects = NULL; } void ObjectConverter::InitFromStory(XIBObject* obj) { setSelfHandled(); _connections = (XIBArray*)FindMemberClass("connections"); + _userDefinedAttributes = (XIBArray*)FindMemberClass("userDefinedRuntimeAttributes"); } void ObjectConverter::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { if (_connections) { @@ -301,6 +307,13 @@ void ObjectConverter::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { } } + if (_userDefinedAttributes) { + for (int i = 0; i < _userDefinedAttributes->count(); i++) { + XIBObject *curObj = _userDefinedAttributes->objectAtIndex(i); + writer->_keyValuePairs->AddMember(NULL, curObj); + writer->AddOutputObject(curObj); + } + } } ObjectConverter* ObjectConverter::Clone() { return this; diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.h b/tools/vsimporter/xib2nib/src/ObjectConverter.h index 090e68618f..4dd4b7760a 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.h +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.h @@ -26,10 +26,12 @@ typedef struct _PropertyMapper { class ObjectConverter : public XIBObject { public: XIBArray* _connections; + XIBArray* _userDefinedAttributes; XIBArray* _variations; ObjectConverter() { _connections = NULL; + _userDefinedAttributes = NULL; }; virtual void InitFromXIB(XIBObject* obj); virtual void InitFromStory(XIBObject* obj); diff --git a/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp b/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp new file mode 100644 index 0000000000..7ab1491997 --- /dev/null +++ b/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp @@ -0,0 +1,111 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#include +#include "UIProxyObject.h" +#include "UINibKeyValuePair.h" +#include "XIBObjectValue.h" +#include "XIBObject.h" + +UINibKeyValuePair::UINibKeyValuePair() { +} + +void UINibKeyValuePair::InitFromXIB(XIBObject* obj) { + ObjectConverter::InitFromXIB(obj); + // not interested much in outdated xcode +} + +void UINibKeyValuePair::InitFromStory(XIBObject* obj) { + ObjectConverter::InitFromStory(obj); + + _className = "UINibKeyValuePair"; + _outputClassName = "UINibKeyValuePair"; + + _keyPath = getAttrAndHandle("keyPath"); + const char* type = getAttrAndHandle("type"); + _source = _parent->_parent; + if (!type ) { + assert(0); // shall not happen + } else if (strcmp(type , "boolean") == 0) { + const char* str = getAttrAndHandle("value"); + _value = new XIBObjectNumber(strcmp(str, "YES") == 0); + } else if (strcmp(type , "string") == 0) { + const char* str = getAttrAndHandle("value"); + _value = new XIBObjectString(str); + } else if (strcmp(type , "number") == 0) { + XIBObject *obj = FindMemberAndHandle("value"); + const char *str = obj->getAttrAndHandle("value"); + if (strcmp(obj->_node.name(), "integer") == 0) { + _value = new XIBObjectNumber(strtoll(str, NULL, 0)); + } else if (strcmp(obj->_node.name(), "real") == 0) { + _value = new XIBObjectNumber(strtod(str, NULL)); + } else if (strcmp(obj->_node.name(), "float") == 0) { + _value = new XIBObjectNumber(strtof(str, NULL)); + } else if (strcmp(obj->_node.name(), "double") == 0) { + _value = new XIBObjectNumber(strtod(str, NULL)); + } else { + assert(0); // shall not happen + } + } else if (strcmp(type , "point") == 0) { + XIBObject *obj= FindMemberAndHandle("value"); + if (obj) { + UIPoint pt = {0}; + pt.x = static_cast(strtod(obj->getAttrAndHandle("x"), NULL)); + pt.y = static_cast(strtod(obj->getAttrAndHandle("y"), NULL)); + _value = new XIBObjectValue(pt); + } + } else if (strcmp(type , "size") == 0) { + XIBObject *obj= FindMemberAndHandle("value"); + if (obj) { + CGSize size = {0}; + size.width = static_cast(strtod(obj->getAttrAndHandle("width"), NULL)); + size.height = static_cast(strtod(obj->getAttrAndHandle("height"), NULL)); + _value = new XIBObjectValue(size); + } + } else if (strcmp(type , "rect") == 0) { + XIBObject *obj= FindMemberAndHandle("value"); + if (obj) { + UIRect rect = {0}; + rect.x = static_cast(strtod(obj->getAttrAndHandle("x"), NULL)); + rect.y = static_cast(strtod(obj->getAttrAndHandle("y"), NULL)); + rect.width = static_cast(strtod(obj->getAttrAndHandle("width"), NULL)); + rect.height = static_cast(strtod(obj->getAttrAndHandle("height"), NULL)); + _value = new XIBObjectValue(rect); + } + } else if (strcmp(type , "range") == 0) { + XIBObject *obj= FindMemberAndHandle("value"); + if (obj) { + NSRange range = {0}; + range.location = strtoll(obj->getAttrAndHandle("location"), NULL, 0); + range.length = strtoll(obj->getAttrAndHandle("length"), NULL, 0); + _value = new XIBObjectValue(range); + } + } else if (strcmp(type , "color") == 0) { + _value = FindMemberAndHandle("value"); + } else if (strcmp(type , "image") == 0) { + const char* str = getAttrAndHandle("value"); + _value = new XIBObjectString(str); + } else if (strcmp(type , "nil") == 0) { + _value = new XIBObjectNil(); + } +} + +void UINibKeyValuePair::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { + AddOutputMember(writer, "UIObject", _source); + AddString(writer, "UIKeyPath", _keyPath); + AddOutputMember(writer, "UIValue", _value); + ObjectConverter::ConvertStaticMappings(writer, obj); +} diff --git a/tools/vsimporter/xib2nib/src/UINibKeyValuePair.h b/tools/vsimporter/xib2nib/src/UINibKeyValuePair.h new file mode 100644 index 0000000000..c83c0f8c20 --- /dev/null +++ b/tools/vsimporter/xib2nib/src/UINibKeyValuePair.h @@ -0,0 +1,30 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#pragma once +#include "ObjectConverter.h" + +class UINibKeyValuePair : public ObjectConverter { +public: + const char* _keyPath; + XIBObject *_source; + XIBObject *_value; +public: + UINibKeyValuePair(); + virtual void InitFromXIB(XIBObject* obj); + virtual void InitFromStory(XIBObject* obj); + virtual void ConvertStaticMappings(NIBWriter* writer, XIBObject* obj); +}; diff --git a/tools/vsimporter/xib2nib/src/XIBObject.h b/tools/vsimporter/xib2nib/src/XIBObject.h index 8f6fb5c122..91fc52c8db 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.h +++ b/tools/vsimporter/xib2nib/src/XIBObject.h @@ -56,6 +56,8 @@ typedef struct { typedef struct { double x, y; } UIPoint; +typedef struct { long long location, length; } NSRange; + const char* getNodeAttrib(pugi::xml_node node, const char* name); class XIBObject { diff --git a/tools/vsimporter/xib2nib/src/XIBObjectValue.h b/tools/vsimporter/xib2nib/src/XIBObjectValue.h new file mode 100644 index 0000000000..a9b58502de --- /dev/null +++ b/tools/vsimporter/xib2nib/src/XIBObjectValue.h @@ -0,0 +1,91 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + + +#pragma once +#include "XIBObject.h" +#include +#include +#include + +#define NSPointNSValueType 1 +#define NSSizeNSValueType 2 +#define NSRectNSValueType 3 +#define NSRangeNSValueType 4 + +template +class XIBObjectValue : public XIBObject { + TData _data; +public: + explicit XIBObjectValue(TData &v ) : _data(v) { + _outputClassName = "NSValue"; + } + + void EmitObject(NIBWriter* writer) { + EmitObject(writer, _data); + } + +private: + + const char *to_str(const UIPoint &point) { + std::stringstream ss; + ss << "{" << point.x << ", " < Date: Tue, 28 Nov 2017 12:35:26 +0200 Subject: [PATCH 10/34] UIColor: added NSColorSpace and friends required by iOS to accept color --- tools/vsimporter/xib2nib/src/UIColor.cpp | 34 ++++++++++++++++++------ 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/UIColor.cpp b/tools/vsimporter/xib2nib/src/UIColor.cpp index 2fca8cc819..0f7bb1a5fb 100644 --- a/tools/vsimporter/xib2nib/src/UIColor.cpp +++ b/tools/vsimporter/xib2nib/src/UIColor.cpp @@ -129,15 +129,15 @@ void UIColor::InitFromStory(XIBObject* obj) { if (strcmp(space, "calibratedWhite") == 0) { _colorSpaceOut = colorSpaceWhite; - _white = strtod(getAttrAndHandle("white"), NULL); - _a = strtod(getAttrAndHandle("alpha"), NULL); + _white = strtof(getAttrAndHandle("white"), NULL); + _a = strtof(getAttrAndHandle("alpha"), NULL); } else if (strcmp(space, "calibratedRGB") == 0 || strcmp(space, "deviceRGB") == 0 || strcmp(space, "adobeRGB1998") == 0 || strcmp(space, "sRGB") == 0) { _colorSpaceOut = colorSpaceRGB; - _a = strtod(getAttrAndHandle("alpha"), NULL); - _r = strtod(getAttrAndHandle("red"), NULL); - _g = strtod(getAttrAndHandle("green"), NULL); - _b = strtod(getAttrAndHandle("blue"), NULL); + _a = strtof(getAttrAndHandle("alpha"), NULL); + _r = strtof(getAttrAndHandle("red"), NULL); + _g = strtof(getAttrAndHandle("green"), NULL); + _b = strtof(getAttrAndHandle("blue"), NULL); } else { spaceIsHandled = false; } @@ -177,18 +177,36 @@ void UIColor::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { } } else { switch (_colorSpaceOut) { - case colorSpaceWhite: + case colorSpaceWhite: { obj->AddOutputMember(writer, "UIWhite", new XIBObjectFloat(_white)); obj->AddOutputMember(writer, "UIAlpha", new XIBObjectFloat(_a)); + char buf[128]; + if (_a != 1) + snprintf(buf, 128, "%.3f %.3f", _white, _a); + else + snprintf(buf, 128, "%.3f", _white); + obj->AddString(writer, "NSWhite", strdup(buf)); + obj->AddInt(writer, "NSColorSpace", 4); + obj->AddInt(writer, "UIColorComponentCount", 2); break; + } case colorSpaceRGB: - case colorSpaceFull: + case colorSpaceFull: { obj->AddOutputMember(writer, "UIAlpha", new XIBObjectFloat(_a)); obj->AddOutputMember(writer, "UIRed", new XIBObjectFloat(_r)); obj->AddOutputMember(writer, "UIGreen", new XIBObjectFloat(_g)); obj->AddOutputMember(writer, "UIBlue", new XIBObjectFloat(_b)); + char buf[128]; + if (_a != 1) + snprintf(buf, 128, "%.3f %.3f %.3f %.3f", _r, _g, _b, _a); + else + snprintf(buf, 128, "%.3f %.3f %.3f", _r, _g, _b); + obj->AddString(writer, "NSRGB", strdup(buf)); + obj->AddInt(writer, "NSColorSpace", 2); + obj->AddInt(writer, "UIColorComponentCount", 4); break; + } } if (_systemName) { From f9a32991812e65de9c3ae77055ed50f92a66bacf Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Wed, 29 Nov 2017 09:28:24 +0200 Subject: [PATCH 11/34] Storyboard segue: added limited support for all types of segue, fixed double entries in nib, multiple time regeneration of on VC and other bugs --- tools/vsimporter/xib2nib/src/NIBWriter.cpp | 12 ++++-- .../xib2nib/src/ObjectConverter.cpp | 12 +++++- .../xib2nib/src/UIBarButtonItem.cpp | 17 -------- tools/vsimporter/xib2nib/src/UIButton.cpp | 18 -------- .../xib2nib/src/UIStoryboardSegue.cpp | 43 ++++++++++++++++--- .../xib2nib/src/UIStoryboardSegue.h | 14 +++++- .../xib2nib/src/UIViewController.cpp | 18 ++++---- 7 files changed, 78 insertions(+), 56 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/NIBWriter.cpp b/tools/vsimporter/xib2nib/src/NIBWriter.cpp index 0e1689b43f..28091b0cfa 100644 --- a/tools/vsimporter/xib2nib/src/NIBWriter.cpp +++ b/tools/vsimporter/xib2nib/src/NIBWriter.cpp @@ -235,6 +235,10 @@ void NIBWriter::AddOutletConnection(XIBObject* src, XIBObject* dst, char* propNa } XIBObject* NIBWriter::AddProxy(char* propName) { + XIBObject* existingProxy = NIBWriter::FindProxy(propName); + if (existingProxy) + return existingProxy; + UIProxyObject* newProxy = new UIProxyObject(); newProxy->_identifier = strdup(propName); _allUIObjects->AddMember(NULL, newProxy); @@ -318,7 +322,7 @@ void NIBWriter::ExportController(const char* controllerId) { } // Check if we've already written out the controller - if (_g_exportedControllers.find(controllerId) != _g_exportedControllers.end()) { + if (_g_exportedControllers.find(controllerIdentifier) != _g_exportedControllers.end()) { return; } @@ -333,9 +337,9 @@ void NIBWriter::ExportController(const char* controllerId) { NIBWriter* writer = new NIBWriter(fpOut, NULL, NULL); - XIBObject* firstResponderProxy = writer->AddProxy("IBFirstResponder"); - XIBObject* ownerProxy = writer->AddProxy("IBFilesOwner"); - XIBObject* storyboard = writer->AddProxy("UIStoryboardPlaceholder"); + XIBObject* ownerProxy = writer->FindProxy("IBFilesOwner"); + if (!ownerProxy) + ownerProxy = writer->AddProxy("IBFilesOwner"); XIBArray* arr = (XIBArray*)objects; for (int i = 0; i < arr->count(); i++) { diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp index cc3761565c..00ab3b03f9 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp @@ -262,7 +262,17 @@ void ObjectConverter::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { for (int i = 0; i < _connections->count(); i++) { XIBObject* curObj = _connections->objectAtIndex(i); - if (strcmp(curObj->_outputClassName, "UIRuntimeOutletConnection") == 0) { + if (strcmp(curObj->_className, "segue") == 0) { + UIStoryboardSegue* segue = (UIStoryboardSegue*)curObj; + + UIRuntimeEventConnection* newEvent = new UIRuntimeEventConnection(); + newEvent->_label = "perform:"; + newEvent->_source = this; + newEvent->_destination = segue; + newEvent->_eventMask = 0x40; + writer->_connections->AddMember(NULL, newEvent); + writer->AddOutputObject(newEvent); + } else if (strcmp(curObj->_outputClassName, "UIRuntimeOutletConnection") == 0) { UIRuntimeOutletConnection* cur = (UIRuntimeOutletConnection*)curObj; UIRuntimeOutletConnection* newOutlet = new UIRuntimeOutletConnection(); diff --git a/tools/vsimporter/xib2nib/src/UIBarButtonItem.cpp b/tools/vsimporter/xib2nib/src/UIBarButtonItem.cpp index 6543f0fe83..7775f2efd9 100644 --- a/tools/vsimporter/xib2nib/src/UIBarButtonItem.cpp +++ b/tools/vsimporter/xib2nib/src/UIBarButtonItem.cpp @@ -100,23 +100,6 @@ void UIBarButtonItem::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { if (_customView) { AddOutputMember(writer, "UICustomView", _customView); } - if (_connections) { - for (int i = 0; i < _connections->count(); i++) { - XIBObject* curObj = _connections->objectAtIndex(i); - if (strcmp(curObj->_className, "segue") == 0) { - UIStoryboardSegue* segue = (UIStoryboardSegue*)curObj; - - UIRuntimeEventConnection* newEvent = new UIRuntimeEventConnection(); - newEvent->_label = "perform:"; - newEvent->_source = this; - newEvent->_destination = segue; - writer->_connections->AddMember(NULL, newEvent); - writer->AddOutputObject(newEvent); - - // AddOutputMember(writer, "UIOutlet", refObj); - } - } - } ObjectConverterSwapper::ConvertStaticMappings(writer, obj); } diff --git a/tools/vsimporter/xib2nib/src/UIButton.cpp b/tools/vsimporter/xib2nib/src/UIButton.cpp index 50cd091831..185e8f8e3a 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.cpp +++ b/tools/vsimporter/xib2nib/src/UIButton.cpp @@ -314,24 +314,6 @@ void UIButton::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { obj->AddData(writer, "UITitleEdgeInsets", _titleEdgeInsets); } - if (_connections) { - for (int i = 0; i < _connections->count(); i++) { - XIBObject* curObj = _connections->objectAtIndex(i); - - if (strcmp(curObj->_className, "segue") == 0) { - UIStoryboardSegue* segue = (UIStoryboardSegue*)curObj; - - UIRuntimeEventConnection* newEvent = new UIRuntimeEventConnection(); - newEvent->_label = "perform:"; - newEvent->_source = this; - newEvent->_destination = segue; - newEvent->_eventMask = 0x40; - writer->_connections->AddMember(NULL, newEvent); - writer->AddOutputObject(newEvent); - } - } - } - WriteStatefulContent(writer, this); UIControl::ConvertStaticMappings(writer, obj); } diff --git a/tools/vsimporter/xib2nib/src/UIStoryboardSegue.cpp b/tools/vsimporter/xib2nib/src/UIStoryboardSegue.cpp index 1e7230f850..096df46098 100644 --- a/tools/vsimporter/xib2nib/src/UIStoryboardSegue.cpp +++ b/tools/vsimporter/xib2nib/src/UIStoryboardSegue.cpp @@ -16,11 +16,13 @@ #include #include "UIStoryboardSegue.h" +#include "UIViewController.h" UIStoryboardSegue::UIStoryboardSegue() { _destination = NULL; _type = segueRelationship; _identifier = NULL; + _actionName = NULL; } void UIStoryboardSegue::InitFromXIB(XIBObject* obj) { @@ -44,11 +46,34 @@ void UIStoryboardSegue::InitFromStory(XIBObject* obj) { bool isHandled = true; if (strcmp(pKind, "modal") == 0) { _type = segueModal; + _outputClassName = "UIStoryboardModalSegueTemplate"; } else if (strcmp(pKind, "push") == 0) { _type = seguePush; + _outputClassName = "UIStoryboardPushSegueTemplate"; } else if (strcmp(pKind, "relationship") == 0) { _type = segueRelationship; + } else if (strcmp(pKind, "show") == 0) { + _type = segueShow; + _outputClassName = "UIStoryboardShowSegueTemplate"; + _actionName = "showViewController:sender:"; + } else if (strcmp(pKind, "showDetail") == 0) { + _type = segueShowDetails; + _outputClassName = "UIStoryboardShowSegueTemplate"; + _actionName = "showDetailViewController:sender:"; + } else if (strcmp(pKind, "presentation") == 0) { + _type = seguePresentModally; + _outputClassName = "UIStoryboardPresentationSegueTemplate"; + } else if (strcmp(pKind, "popoverPresentation") == 0) { + _type = seguePresentAsPopover; + _outputClassName = "UIStoryboardPopoverPresentationSegueTemplate"; + } else if (strcmp(pKind, "custom") == 0) { + _type = segueCustom; + _outputClassName = "UIStoryboardSegueTemplate"; + } else if (strcmp(pKind, "replace") == 0) { + _type = segueCustom; + _outputClassName = "UIStoryboardPushSegueTemplate"; } else { + _type = segueUnsupported; isHandled = false; } @@ -56,16 +81,20 @@ void UIStoryboardSegue::InitFromStory(XIBObject* obj) { getAttrAndHandle("kind"); } } - - if (_type == segueModal) { - _outputClassName = "UIStoryboardModalSegueTemplate"; - } else if (_type == seguePush) { - _outputClassName = "UIStoryboardPushSegueTemplate"; - } } void UIStoryboardSegue::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { ObjectConverter::ConvertStaticMappings(writer, obj); AddString(writer, "UIIdentifier", _identifier); - AddString(writer, "UIDestinationViewControllerIdentifier", _destination); + + // find story view controller by id and try to use it storyboardIdentifier if set as destination + XIBObject* controller = XIBObject::findReference(_destination); + UIViewController* uiViewController = dynamic_cast(controller); + if (uiViewController && uiViewController->_storyboardIdentifier) + AddString(writer, "UIDestinationViewControllerIdentifier", uiViewController->_storyboardIdentifier); + else + + AddString(writer, "UIDestinationViewControllerIdentifier", _destination); + if (_actionName != NULL) + AddString(writer, "UIActionName", _actionName); } diff --git a/tools/vsimporter/xib2nib/src/UIStoryboardSegue.h b/tools/vsimporter/xib2nib/src/UIStoryboardSegue.h index 64a288886f..48844a2308 100644 --- a/tools/vsimporter/xib2nib/src/UIStoryboardSegue.h +++ b/tools/vsimporter/xib2nib/src/UIStoryboardSegue.h @@ -17,13 +17,25 @@ #pragma once #include "ObjectConverter.h" -typedef enum { segueRelationship, segueModal, seguePush } SegueType; +typedef enum { + segueRelationship, + segueModal, // deprecated + seguePush, // deprecated + segueShow, + segueShowDetails, + seguePresentModally, + seguePresentAsPopover, + segueCustom, + + segueUnsupported, +} SegueType; class UIStoryboardSegue : public ObjectConverter { public: const char* _destination; SegueType _type; const char* _identifier; + const char* _actionName; UIStoryboardSegue(); virtual void InitFromXIB(XIBObject* obj); diff --git a/tools/vsimporter/xib2nib/src/UIViewController.cpp b/tools/vsimporter/xib2nib/src/UIViewController.cpp index c71d4a802c..247fe17ee8 100644 --- a/tools/vsimporter/xib2nib/src/UIViewController.cpp +++ b/tools/vsimporter/xib2nib/src/UIViewController.cpp @@ -102,7 +102,7 @@ void ScanForSegues(XIBArray* out, XIBObject* obj) { if (curMember->_obj->_className && strcmp(curMember->_obj->_className, "segue") == 0) { UIStoryboardSegue* curSegue = (UIStoryboardSegue*)curMember->_obj; - if (curSegue->_type == segueModal || curSegue->_type == seguePush) { + if (curSegue->_type != segueUnsupported) { curSegue->_parent = out; out->AddMember(NULL, curMember->_obj); } @@ -117,6 +117,8 @@ void UIViewController::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) XIBArray* segueTemplates = new XIBArray(); + if (_storyboardIdentifier) + AddString(writer, "UIStoryboardIdentifier", _storyboardIdentifier); if (_tabBarItem) AddOutputMember(writer, "UITabBarItem", _tabBarItem); if (_navigationItem) @@ -148,9 +150,7 @@ void UIViewController::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) viewWriter->ExportObject(_view); XIBObject* ownerProxy = viewWriter->AddProxy("IBFilesOwner"); - viewWriter->_topObjects->AddMember(NULL, ownerProxy); XIBObject* firstResponderProxy = viewWriter->AddProxy("IBFirstResponder"); - viewWriter->_topObjects->AddMember(NULL, firstResponderProxy); // Add view connection viewWriter->AddOutletConnection(ownerProxy, _view, "view"); @@ -171,14 +171,16 @@ void UIViewController::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) XIBObject* storyboard = writer->AddProxy("UIStoryboardPlaceholder"); writer->AddOutletConnection(this, storyboard, "storyboard"); - for (int i = 0; i < segueTemplates->count(); i++) { - UIStoryboardSegue* curSegue = (UIStoryboardSegue*)segueTemplates->objectAtIndex(i); - - writer->AddOutletConnection(curSegue, this, "viewController"); - } if (segueTemplates->count() > 0) { AddOutputMember(writer, "UIStoryboardSegueTemplates", segueTemplates); + for (int i = 0; i < segueTemplates->count(); i++) { + UIStoryboardSegue* curSegue = (UIStoryboardSegue*)segueTemplates->objectAtIndex(i); + + writer->AddOutletConnection(curSegue, this, "viewController"); + writer->_allUIObjects->AddMember(NULL, curSegue); + } + for (int i = 0; i < segueTemplates->count(); i++) { UIStoryboardSegue* curSegue = (UIStoryboardSegue*)segueTemplates->objectAtIndex(i); From 4a84ff0f9e3a0388926a485edf5458d9c814055a Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Fri, 2 Feb 2018 10:01:52 +0200 Subject: [PATCH 12/34] Massive changes: 1) added support for UILayoutGuide to support safeArea of iOS11 2) added command line parsing 3) added support for minimum deployment target to be able to produce different output 4) if there is some functionality is not supported due min_dep_version nibs are now exported to folder with two files runtime.nib and unlimited objects-11.0+.nib 5) added support for customModule altogether to customClass. It is required to mange proper swift class name --- tools/vsimporter/xib2nib/src/NIBWriter.cpp | 66 +--- tools/vsimporter/xib2nib/src/NIBWriter.h | 10 +- .../xib2nib/src/NSLayoutConstraint.cpp | 36 +- .../xib2nib/src/NSLayoutConstraint.h | 6 +- .../xib2nib/src/ObjectConverter.cpp | 11 + .../vsimporter/xib2nib/src/UILayoutGuide.cpp | 89 +++++ tools/vsimporter/xib2nib/src/UILayoutGuide.h | 28 ++ tools/vsimporter/xib2nib/src/UIView.cpp | 19 +- tools/vsimporter/xib2nib/src/UIView.h | 1 + .../xib2nib/src/UIViewController.cpp | 8 +- tools/vsimporter/xib2nib/src/XIBObject.cpp | 2 +- tools/vsimporter/xib2nib/src/xib2nib.cpp | 323 +++++++++++++++--- 12 files changed, 464 insertions(+), 135 deletions(-) create mode 100644 tools/vsimporter/xib2nib/src/UILayoutGuide.cpp create mode 100644 tools/vsimporter/xib2nib/src/UILayoutGuide.h diff --git a/tools/vsimporter/xib2nib/src/NIBWriter.cpp b/tools/vsimporter/xib2nib/src/NIBWriter.cpp index 28091b0cfa..214ae939d5 100644 --- a/tools/vsimporter/xib2nib/src/NIBWriter.cpp +++ b/tools/vsimporter/xib2nib/src/NIBWriter.cpp @@ -21,7 +21,6 @@ #include "UIProxyObject.h" #include #include -#include "UIViewController.h" #include "../WBITelemetry/WBITelemetry.h" int curPlaceholder = 1; @@ -130,6 +129,8 @@ NIBWriter::NIBWriter(FILE* out) { _baseObject = NULL; _connections = NULL; _visibleWindows = NULL; + _minimumDeploymentTarget = DEPLOYMENT_TARGET_RECENT; + _wasLimitedByDeplymentTarget = false; fpOut = out; } @@ -139,6 +140,8 @@ NIBWriter::NIBWriter(FILE* out, XIBDictionary* externalReferences, XIBObject* ba _baseObject = NULL; _connections = NULL; _visibleWindows = NULL; + _minimumDeploymentTarget = DEPLOYMENT_TARGET_RECENT; + _wasLimitedByDeplymentTarget = false; fpOut = out; curPlaceholder = 1; @@ -296,67 +299,6 @@ XIBObject* NIBWriter::GetProxyFor(XIBObject* obj) { return newProxy; } -std::map _g_exportedControllers; - -void NIBWriter::ExportAllControllers() { - for (const char* cur : UIViewController::_viewControllerNames) { - ExportController(cur); - } -} - -void NIBWriter::ExportController(const char* controllerId) { - char szFilename[255]; - - XIBObject* controller = XIBObject::findReference(controllerId); - UIViewController* uiViewController = dynamic_cast(controller); - if (!uiViewController) { - // object isn't really a controller - printf("Object %s is not a controller\n", controller->stringValue()); - return; - } - - const char* controllerIdentifier = uiViewController->_storyboardIdentifier; - if (controllerIdentifier == NULL) { - // not all viewcontrollers will have a storyboard identifier. If they don't use the controller Id for the key. - controllerIdentifier = controllerId; - } - - // Check if we've already written out the controller - if (_g_exportedControllers.find(controllerIdentifier) != _g_exportedControllers.end()) { - return; - } - - sprintf(szFilename, "%s.nib", controllerIdentifier); - - _g_exportedControllers[controllerIdentifier] = controllerIdentifier; - - XIBArray* objects = (XIBArray*)controller->_parent; - - printf("Writing %s\n", GetOutputFilename(szFilename).c_str()); - FILE* fpOut = fopen(GetOutputFilename(szFilename).c_str(), "wb"); - - NIBWriter* writer = new NIBWriter(fpOut, NULL, NULL); - - XIBObject* ownerProxy = writer->FindProxy("IBFilesOwner"); - if (!ownerProxy) - ownerProxy = writer->AddProxy("IBFilesOwner"); - - XIBArray* arr = (XIBArray*)objects; - for (int i = 0; i < arr->count(); i++) { - XIBObject* curObj = arr->objectAtIndex(i); - - writer->ExportObject(curObj); - if (curObj->getAttrib("sceneMemberID")) { - if (strcmp(curObj->getAttrib("sceneMemberID"), "viewController") == 0) { - writer->AddOutletConnection(ownerProxy, curObj, "sceneViewController"); - } - } - } - - writer->WriteObjects(); - - fclose(fpOut); -} void NIBWriter::WriteData() { fwrite("NIBArchive", 10, 1, fpOut); diff --git a/tools/vsimporter/xib2nib/src/NIBWriter.h b/tools/vsimporter/xib2nib/src/NIBWriter.h index 87e55e4e0f..3c1c38ff81 100644 --- a/tools/vsimporter/xib2nib/src/NIBWriter.h +++ b/tools/vsimporter/xib2nib/src/NIBWriter.h @@ -32,6 +32,10 @@ #define NIBOBJ_NULL 0x09 #define NIBOBJ_UID 0x0A +#define DEPLOYMENT_TARGET_IOS9 0x090000 +#define DEPLOYMENT_TARGET_IOS11 0x0B0000 +#define DEPLOYMENT_TARGET_RECENT DEPLOYMENT_TARGET_IOS11 + class ProxiedObject { public: XIBObject *_obj, *_proxyObj; @@ -48,6 +52,8 @@ class NIBWriter { FILE* fpOut; public: + uint32_t _minimumDeploymentTarget; + bool _wasLimitedByDeplymentTarget; XIBObject* _allUIObjects; XIBObject* _connections; XIBObject* _baseObject; @@ -61,8 +67,6 @@ class NIBWriter { NIBWriter(FILE* out); NIBWriter(FILE* out, XIBDictionary* externalRefsDict, XIBObject* base); - static void ExportController(const char* controllerId); - static void ExportAllControllers(); void ExportObject(XIBObject* obj); void WriteObjects(); XIBObject* AddOutputObject(XIBObject* pObj); @@ -77,4 +81,4 @@ class NIBWriter { XIBObject* GetProxyFor(XIBObject* obj); }; -#endif \ No newline at end of file +#endif diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp index 6a1583834f..ee10d33271 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp @@ -16,6 +16,7 @@ #include "NSLayoutConstraint.h" #include "UIView.h" +#include "UILayoutGuide.h" #include #include @@ -52,6 +53,8 @@ NSLayoutConstraint::NSLayoutConstraint() { _constant = 0.0f; _symbolicConstant = 0.0f; _hasSymbolicConstant = false; + _layoutIdentifier = NULL; + _exportDefaultValues = false; } void NSLayoutConstraint::InitFromXIB(XIBObject* obj) { @@ -148,21 +151,40 @@ void NSLayoutConstraint::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj AddInt(writer, "NSFirstAttribute", _firstAttribute); AddInt(writer, "NSSecondAttribute", _secondAttribute); - AddInt(writer, "NSRelation", _relation); + if (_exportDefaultValues || _relation != NSLayoutRelationEqual) + AddInt(writer, "NSRelation", _relation); if (_firstItem) - AddOutputMember(writer, "NSFirstItem", _firstItem); + AddOutputMember(writer, "NSFirstItem", substituteItemUnsupported(writer, _firstItem)); if (_secondItem) - AddOutputMember(writer, "NSSecondItem", _secondItem); + AddOutputMember(writer, "NSSecondItem", substituteItemUnsupported(writer, _secondItem)); - AddOutputMember(writer, "NSMultiplier", new XIBObjectFloat(_multiplier)); - AddInt(writer, "NSPriority", _priority); + if (_exportDefaultValues || _multiplier != 1.0f) + AddOutputMember(writer, "NSMultiplier", new XIBObjectFloat(_multiplier)); + if (_exportDefaultValues || _priority != NSLayoutPriorityRequired) + AddInt(writer, "NSPriority", _priority); if (_hasSymbolicConstant) { AddOutputMember(writer, "NSSymbolicConstant", new XIBObjectFloat(_symbolicConstant)); } else { - AddOutputMember(writer, "NSConstant", new XIBObjectFloat(_constant)); + if (_exportDefaultValues || _constant != 0) + AddOutputMember(writer, "NSConstant", new XIBObjectFloat(_constant)); } + if (_layoutIdentifier) + AddString(writer, "NSLayoutIdentifier", _layoutIdentifier); + ObjectConverterSwapper::ConvertStaticMappings(writer, obj); -} \ No newline at end of file +} + +XIBObject* NSLayoutConstraint::substituteItemUnsupported(NIBWriter* writer, XIBObject* item){ + if (writer->_minimumDeploymentTarget < DEPLOYMENT_TARGET_IOS11 && (strcmp(item->_outputClassName, "UILayoutGuide") == 0)) { + writer->_wasLimitedByDeplymentTarget = true; + // constraint to layout guide that is not supported, replace them to view + UILayoutGuide *guide = (UILayoutGuide*)item; + if (guide->_owningView) + return guide->_owningView; + } + + return item; +} diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h index 29068d523b..cfab4c09cc 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h @@ -75,6 +75,8 @@ class NSLayoutConstraint : public ObjectConverterSwapper { float _constant; float _symbolicConstant; bool _hasSymbolicConstant; + const char* _layoutIdentifier; + bool _exportDefaultValues; public: NSLayoutConstraint(); @@ -83,4 +85,6 @@ class NSLayoutConstraint : public ObjectConverterSwapper { virtual void InitFromStory(XIBObject* obj); virtual void Awaken(); virtual void ConvertStaticMappings(NIBWriter* writer, XIBObject* obj); -}; \ No newline at end of file +private: + XIBObject* substituteItemUnsupported(NIBWriter* writer, XIBObject* item); +}; diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp index 00ab3b03f9..86a82343f3 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp @@ -62,6 +62,7 @@ #include "UICollectionViewController.h" #include "UIStepper.h" #include "_UILayoutGuide.h" +#include "UILayoutGuide.h" #include "UIPanGestureRecognizer.h" #include "UISwipeGestureRecognizer.h" #include "UITapGestureRecognizer.h" @@ -187,6 +188,7 @@ XIBObject* ObjectConverter::ConverterForStoryObject(const char* className, pugi: IS_CONVERTER(ret, className, "constraint", NSLayoutConstraint) IS_CONVERTER(ret, className, "layoutGuides", XIBVariation) IS_CONVERTER(ret, className, "viewControllerLayoutGuide", _UILayoutGuide) + IS_CONVERTER(ret, className, "viewLayoutGuide", UILayoutGuide) IS_CONVERTER(ret, className, "datePicker", UIDatePicker) IS_CONVERTER(ret, className, "slider", UISlider) IS_CONVERTER(ret, className, "collectionReusableView", UICollectionReusableView) @@ -356,6 +358,15 @@ void ObjectConverterSwapper::InitFromStory(XIBObject* obj) { if (getAttrib("customClass")) { _swappedClassName = getAttrAndHandle("customClass"); + const char* module = NULL; + if (getAttrib("customModule")) + module = getAttrAndHandle("customModule"); + if (module) { + // its swift, mange class name with module + char buf[128]; // should be big enough + snprintf(buf, 128, "_TtC%zu%s%zu%s", strlen(module), module, strlen(_swappedClassName), _swappedClassName); + _swappedClassName = strdup(buf); + } } } diff --git a/tools/vsimporter/xib2nib/src/UILayoutGuide.cpp b/tools/vsimporter/xib2nib/src/UILayoutGuide.cpp new file mode 100644 index 0000000000..a394824e37 --- /dev/null +++ b/tools/vsimporter/xib2nib/src/UILayoutGuide.cpp @@ -0,0 +1,89 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#include "UILayoutGuide.h" +#include "NSLayoutConstraint.h" +#include + +UILayoutGuide::UILayoutGuide() { + _systemConstraints = new XIBArray(); +} + +void UILayoutGuide::InitFromXIB(XIBObject* obj) { + // Outdated code do nothing +} + +void UILayoutGuide::InitFromStory(XIBObject* obj) { + _owningView = obj->_parent; + _outputClassName = "UILayoutGuide"; + + const char* key = getAttrib("key"); + if (key && strcmp(key, "safeArea") == 0) { + // handle today only safe area + NSLayoutConstraint* systemConstraintLeft = new NSLayoutConstraint(); + systemConstraintLeft->_firstItem = this; + systemConstraintLeft->_firstAttribute = NSLayoutAttributeLeft; + systemConstraintLeft->_secondItem = _owningView; + systemConstraintLeft->_secondAttribute = NSLayoutAttributeLeft; + systemConstraintLeft->_layoutIdentifier = "UIViewSafeAreaLayoutGuide-left"; + systemConstraintLeft->_outputClassName = "NSLayoutConstraint"; + systemConstraintLeft->_ignoreUIObject = true; + + NSLayoutConstraint* systemConstraintTop = new NSLayoutConstraint(); + systemConstraintTop->_firstItem = this; + systemConstraintTop->_firstAttribute = NSLayoutAttributeTop; + systemConstraintTop->_secondItem = _owningView; + systemConstraintTop->_secondAttribute = NSLayoutAttributeTop; + systemConstraintTop->_layoutIdentifier = "UIViewSafeAreaLayoutGuide-top"; + systemConstraintTop->_outputClassName = "NSLayoutConstraint"; + systemConstraintTop->_ignoreUIObject = true; + + NSLayoutConstraint* systemConstraintRight = new NSLayoutConstraint(); + systemConstraintRight->_firstItem = _owningView; + systemConstraintRight->_firstAttribute = NSLayoutAttributeRight; + systemConstraintRight->_secondItem = this; + systemConstraintRight->_secondAttribute = NSLayoutAttributeRight; + systemConstraintRight->_layoutIdentifier = "UIViewSafeAreaLayoutGuide-right"; + systemConstraintRight->_outputClassName = "NSLayoutConstraint"; + systemConstraintRight->_ignoreUIObject = true; + + NSLayoutConstraint* systemConstraintBottom = new NSLayoutConstraint(); + systemConstraintBottom->_firstItem = _owningView; + systemConstraintBottom->_firstAttribute = NSLayoutAttributeBottom; + systemConstraintBottom->_secondItem = this; + systemConstraintBottom->_secondAttribute = NSLayoutAttributeBottom; + systemConstraintBottom->_layoutIdentifier = "UIViewSafeAreaLayoutGuide-bottom"; + systemConstraintBottom->_outputClassName = "NSLayoutConstraint"; + systemConstraintBottom->_ignoreUIObject = true; + + _systemConstraints->AddMember(NULL, systemConstraintTop); + _systemConstraints->AddMember(NULL, systemConstraintLeft); + _systemConstraints->AddMember(NULL, systemConstraintRight); + _systemConstraints->AddMember(NULL, systemConstraintBottom); + } +} + +void UILayoutGuide::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { + obj->AddOutputMember(writer, "UILayoutGuideOwningView", _owningView); + if (_systemConstraints->count()) { + // its safeArea, don't know what to export other cases as Xcode doesn't support this yet as at v9.2 + obj->AddString(writer, "UILayoutGuideIdentifier", "UIViewSafeAreaLayoutGuide"); + obj->AddBool(writer, "UILayoutGuideOwningViewIsLocked", true); + obj->AddOutputMember(writer, "UILayoutGuideSystemConstraints", _systemConstraints); + } + + ObjectConverter::ConvertStaticMappings(writer, obj); +} diff --git a/tools/vsimporter/xib2nib/src/UILayoutGuide.h b/tools/vsimporter/xib2nib/src/UILayoutGuide.h new file mode 100644 index 0000000000..61381b165f --- /dev/null +++ b/tools/vsimporter/xib2nib/src/UILayoutGuide.h @@ -0,0 +1,28 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#pragma once +#include "ObjectConverter.h" +class UILayoutGuide : public ObjectConverter { +public: + XIBObject* _owningView; + XIBArray* _systemConstraints; + + UILayoutGuide(); + virtual void InitFromXIB(XIBObject* obj); + virtual void InitFromStory(XIBObject* obj); + virtual void ConvertStaticMappings(NIBWriter* writer, XIBObject* obj); +}; diff --git a/tools/vsimporter/xib2nib/src/UIView.cpp b/tools/vsimporter/xib2nib/src/UIView.cpp index 61ff78b1a7..86cf101ce9 100644 --- a/tools/vsimporter/xib2nib/src/UIView.cpp +++ b/tools/vsimporter/xib2nib/src/UIView.cpp @@ -20,6 +20,7 @@ #include #include #include "UIRuntimeOutletCollectionConnection.h" +#include "UILayoutGuide.h" static void InvertBool(struct _PropertyMapper* prop, NIBWriter* writer, XIBObject* propObj, XIBObject* obj) { XIBObjectBool* value = (XIBObjectBool*)propObj; @@ -40,6 +41,7 @@ UIView::UIView() { memset(&_contentStretch, 0, sizeof(_contentStretch)); _subviews = new XIBArray(); _constraints = new XIBArray(); + _layoutGuides = new XIBArray(); _hidden = false; _opaque = true; _autoresizeSubviews = true; @@ -72,7 +74,7 @@ void UIView::InitFromXIB(XIBObject* obj) { _bounds.height = 0; _center.x = 0; _center.y = 0; - sscanf(pszFramePos, "{{%f, %f}, {%f, %f}}", &_center.x, &_center.y, &_bounds.width, &_bounds.height); + sscanf(pszFramePos, "{{%lf, %lf}, {%lf, %lf}}", &_center.x, &_center.y, &_bounds.width, &_bounds.height); _center.x += _bounds.width / 2.0f; _center.y += _bounds.height / 2.0f; } else { @@ -81,7 +83,7 @@ void UIView::InitFromXIB(XIBObject* obj) { _bounds.y = 0; _bounds.width = 0; _bounds.height = 0; - sscanf(pszFramePos, "{%f, %f}", &_bounds.width, &_bounds.height); + sscanf(pszFramePos, "{%lf, %lf}", &_bounds.width, &_bounds.height); _center.x = _bounds.width / 2.0f; _center.y = _bounds.height / 2.0f; } @@ -136,6 +138,11 @@ void UIView::InitFromStory(XIBObject* obj) { _constraints = new XIBArray(); } + UILayoutGuide *safeAreaGuide = (UILayoutGuide*)FindMemberAndHandle("safeArea"); + if (safeAreaGuide) { + _layoutGuides->AddMember(NULL, safeAreaGuide); + } + if (getAttrib("tag")) { _tag = static_cast(strtod(getAttrAndHandle("tag"), NULL)); } @@ -310,6 +317,14 @@ void UIView::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { AddOutputMember(writer, "UIViewAutolayoutConstraints", _constraints); } + if (_layoutGuides->count() > 0) { + if (writer->_minimumDeploymentTarget < DEPLOYMENT_TARGET_IOS11) { + writer->_wasLimitedByDeplymentTarget = true; + } else { + AddOutputMember(writer, "UIViewLayoutGuides", _layoutGuides); + } + } + if (_autoresizeSubviews) { AddBool(writer, "UIAutoresizeSubviews", _autoresizeSubviews); } diff --git a/tools/vsimporter/xib2nib/src/UIView.h b/tools/vsimporter/xib2nib/src/UIView.h index c2db9e2aed..69afb5f044 100644 --- a/tools/vsimporter/xib2nib/src/UIView.h +++ b/tools/vsimporter/xib2nib/src/UIView.h @@ -48,6 +48,7 @@ class UIView : public ObjectConverterSwapper { public: XIBArray* _subviews; XIBArray* _constraints; + XIBArray* _layoutGuides; UIColor* _backgroundColor; UIRect _bounds; UIRect _contentStretch; diff --git a/tools/vsimporter/xib2nib/src/UIViewController.cpp b/tools/vsimporter/xib2nib/src/UIViewController.cpp index 247fe17ee8..d50d7903d9 100644 --- a/tools/vsimporter/xib2nib/src/UIViewController.cpp +++ b/tools/vsimporter/xib2nib/src/UIViewController.cpp @@ -180,12 +180,6 @@ void UIViewController::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) writer->AddOutletConnection(curSegue, this, "viewController"); writer->_allUIObjects->AddMember(NULL, curSegue); } - - for (int i = 0; i < segueTemplates->count(); i++) { - UIStoryboardSegue* curSegue = (UIStoryboardSegue*)segueTemplates->objectAtIndex(i); - - NIBWriter::ExportController(curSegue->getAttrib("destination")); - } } } if (_childViewControllers->count() > 0) { @@ -196,4 +190,4 @@ void UIViewController::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) } ObjectConverterSwapper::ConvertStaticMappings(writer, obj); -} \ No newline at end of file +} diff --git a/tools/vsimporter/xib2nib/src/XIBObject.cpp b/tools/vsimporter/xib2nib/src/XIBObject.cpp index 92e01a8b52..34b7460287 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.cpp +++ b/tools/vsimporter/xib2nib/src/XIBObject.cpp @@ -446,7 +446,7 @@ CGSize XIBObject::GetSize(char* pPropName, float defaultWidth, float defaultHeig if (pObj) { const char* pStr = pObj->stringValue(); - sscanf(pStr, "{%f, %f}", &ret.width, &ret.height); + sscanf(pStr, "{%lf, %lf}", &ret.width, &ret.height); } return ret; diff --git a/tools/vsimporter/xib2nib/src/xib2nib.cpp b/tools/vsimporter/xib2nib/src/xib2nib.cpp index 75ed45d36c..c7c4d36cec 100644 --- a/tools/vsimporter/xib2nib/src/xib2nib.cpp +++ b/tools/vsimporter/xib2nib/src/xib2nib.cpp @@ -18,6 +18,7 @@ #include #include +#include #include //#include #include @@ -29,6 +30,7 @@ #include "XIBObjectTypes.h" #include "XIBDocument.h" #include "NIBWriter.h" +#include "UIViewController.h" #include "Plist.hpp" #include "miscutils.h" #include "versionutils.h" @@ -50,9 +52,133 @@ std::string GetOutputFilename(const char* filename) { return ret; } -extern std::map _g_exportedControllers; +// convert string presentation of version to hex enctoded integer "a.b.c" > 0xaaaabbcc +static int stringToVersion(const char *str){ + int v = -1; + std::stringstream ss(str); + std::string s; + std::vector items; + while (getline(ss, s, '.')) { + items.push_back(std::stoi(s)); + } + + // small sanity for range checking + if (items.size() && items[0] >= 0 && items[0] <= 0xFFFF) { + v = items[0] << 16; + if (items.size() > 1) + v = (items[1] >= 0 && items[1] <= 0xFF) ? (v | items[1] << 8) : -1; + if (v >= 0 && items.size() > 2) + v = (items[2] >= 0 && items[2] <= 0xFF) ? (v | items[2] << 8) : -1; + } + + return v; +} + + + + +static NIBWriter* WriteStoryNibToFile(const char *szFilename, XIBArray* arr, const int minDeploymentVersion) { + FILE* fpOut = fopen(GetOutputFilename(szFilename).c_str(), "wb"); + NIBWriter* writer = new NIBWriter(fpOut, NULL, NULL); + writer->_minimumDeploymentTarget = minDeploymentVersion; + + XIBObject* ownerProxy = writer->FindProxy("IBFilesOwner"); + if (!ownerProxy) + ownerProxy = writer->AddProxy("IBFilesOwner"); + + for (int i = 0; i < arr->count(); i++) { + XIBObject* curObj = arr->objectAtIndex(i); + + writer->ExportObject(curObj); + if (curObj->getAttrib("sceneMemberID")) { + if (strcmp(curObj->getAttrib("sceneMemberID"), "viewController") == 0) { + writer->AddOutletConnection(ownerProxy, curObj, "sceneViewController"); + } + } + } + + writer->WriteObjects(); + fclose(fpOut); + + return writer; +} + +void ExportStoryBoardController(std::map exportedControllers, const char* controllerId, + const int minDeploymentVersion) { + char szFilename[255]; + + XIBObject* controller = XIBObject::findReference(controllerId); + UIViewController* uiViewController = dynamic_cast(controller); + if (!uiViewController) { + // object isn't really a controller + printf("Object %s is not a controller\n", controller->stringValue()); + return; + } + + const char* controllerIdentifier = uiViewController->_storyboardIdentifier; + if (controllerIdentifier == NULL) { + // not all viewcontrollers will have a storyboard identifier. If they don't use the controller Id for the key. + controllerIdentifier = controllerId; + } + + // Check if we've already written out the controller + if (exportedControllers.find(controllerIdentifier) != exportedControllers.end()) { + return; + } + + sprintf(szFilename, "%s.nib", controllerIdentifier); + exportedControllers[controllerIdentifier] = controllerIdentifier; + + XIBArray* viewObjects = (XIBArray*)controller->_parent; + + const char *outFile = GetOutputFilename(szFilename).c_str(); + printf("Writing %s\n", outFile); + + if (minDeploymentVersion < 0) { + // version is not limited compile to recent one + NIBWriter* writer = WriteStoryNibToFile(outFile, (XIBArray*)viewObjects, DEPLOYMENT_TARGET_RECENT); + assert(!writer->_wasLimitedByDeplymentTarget); + } else { + // there is limitation applied + // compile to test file to check if there will be limitation during the run + std::string tmp = std::string(outFile) + ".tmp"; + NIBWriter* writer = WriteStoryNibToFile(tmp.c_str(), (XIBArray*)viewObjects, minDeploymentVersion); + if (writer->_wasLimitedByDeplymentTarget) { + // limitation has applied, so begin plan b: + // create dir with outFile name + struct stat st = { 0 }; + stat(outFile, &st); + if (!(((st.st_mode) & S_IFMT) == S_IFDIR) && _mkdir(outFile) != 0) { + printf("Unable to create directory %s err=%d\n", outFile, errno); + exit(-1); + return; + } + + // move tmp file to + std::string dest = std::string(outFile) + "/runtime.nib"; + if (rename(tmp.c_str(), dest.c_str()) != 0) { + printf("Failed to move nib to %s/runtime.nib err=%d\n", outFile, errno); + exit(-1); + return; + } + + // and now generate unlimited version + dest = std::string(outFile) + "/objects-11.0+.nib"; + NIBWriter* writer = WriteStoryNibToFile(dest.c_str(), (XIBArray*)viewObjects, DEPLOYMENT_TARGET_RECENT); + assert(!writer->_wasLimitedByDeplymentTarget); + } else { + // no limitations, just rename file to target + if (rename(tmp.c_str(), outFile) != 0) { + printf("Failed to rename nib to %s err=%d\n", outFile, errno); + exit(-1); + return; + } + } + } +} -void ConvertStoryboard(pugi::xml_document& doc) { + +void ConvertStoryboard(pugi::xml_document& doc, const int minDeploymentVersion) { pugi::xml_node curNode = doc.first_child(); // Storyboard XIB file - get topmost controller, then export it @@ -70,14 +196,17 @@ void ConvertStoryboard(pugi::xml_document& doc) { // Print which XML nodes we did not handle during the parse for diagnostic purpose. XIBObject::getDocumentCoverage(doc); - NIBWriter::ExportAllControllers(); + std::map exportedControllers; + for (const char* cur : UIViewController::_viewControllerNames) { + ExportStoryBoardController(exportedControllers, cur, minDeploymentVersion); + } Plist::dictionary_type viewControllerInfo; viewControllerInfo[std::string("UIStoryboardDesignatedEntryPointIdentifier")] = std::string(initialController); viewControllerInfo[std::string("UIStoryboardVersion")] = (int)1; Plist::dictionary_type viewControllerMappings; - for (auto curController : _g_exportedControllers) { + for (auto curController : exportedControllers) { viewControllerMappings[curController.first] = curController.second; } viewControllerInfo[std::string("UIViewControllerIdentifiersToNibNames")] = viewControllerMappings; @@ -86,7 +215,29 @@ void ConvertStoryboard(pugi::xml_document& doc) { Plist::writePlistBinary(GetOutputFilename("Info.plist").c_str(), viewControllerInfo); } -void ConvertXIB3ToNib(FILE* fpOut, pugi::xml_document& doc) { +NIBWriter* WriteNibToFile(const char *outFile, XIBArray* arr, const int minDeploymentVersion) { + FILE* fpOut = fopen(outFile, "wb"); + if (!fpOut) { + printf("Error opening %s\n", outFile); + exit(-1); + return NULL; + } + + NIBWriter* writer = new NIBWriter(fpOut, NULL, NULL); + writer->_minimumDeploymentTarget = minDeploymentVersion; + for (int i = 0; i < arr->count(); i++) { + XIBObject* curObj = arr->objectAtIndex(i); + + writer->ExportObject(curObj); + } + + writer->WriteObjects(); + fclose(fpOut); + + return writer; +} + +void ConvertXIB3ToNib(const char *outFile, pugi::xml_document& doc, const int minDeploymentVersion) { pugi::xml_node curNode = doc.first_child(); // XIB3 file @@ -96,19 +247,50 @@ void ConvertXIB3ToNib(FILE* fpOut, pugi::xml_document& doc) { XIBArray* viewObjects = rootDocument->Objects(); if (viewObjects) { - NIBWriter* writer = new NIBWriter(fpOut, NULL, NULL); - - XIBArray* arr = (XIBArray*)viewObjects; - for (int i = 0; i < arr->count(); i++) { - XIBObject* curObj = arr->objectAtIndex(i); + if (minDeploymentVersion < 0) { + // version is not limited compile to recent one + NIBWriter* writer = WriteNibToFile(outFile, (XIBArray*)viewObjects, DEPLOYMENT_TARGET_RECENT); + assert(!writer->_wasLimitedByDeplymentTarget); + } else { + // there is limitation applied + // compile to test file to check if there will be limitation during the run + std::string tmp = std::string(outFile) + ".tmp"; + NIBWriter* writer = WriteNibToFile(tmp.c_str(), (XIBArray*)viewObjects, minDeploymentVersion); + if (writer->_wasLimitedByDeplymentTarget) { + // limitation has applied, so begin plan b: + // create dir with outFile name + struct stat st = { 0 }; + stat(outFile, &st); + if (!(((st.st_mode) & S_IFMT) == S_IFDIR) && _mkdir(outFile) != 0) { + printf("Unable to create directory %s err=%d\n", outFile, errno); + exit(-1); + return; + } + + // move tmp file to + std::string dest = std::string(outFile) + "/runtime.nib"; + if (rename(tmp.c_str(), dest.c_str()) != 0) { + printf("Failed to move nib to %s/runtime.nib err=%d\n", outFile, errno); + exit(-1); + return; + } - writer->ExportObject(curObj); + // and now generate unlimited version + dest = std::string(outFile) + "/objects-11.0+.nib"; + NIBWriter* writer = WriteNibToFile(dest.c_str(), (XIBArray*)viewObjects, DEPLOYMENT_TARGET_RECENT); + assert(!writer->_wasLimitedByDeplymentTarget); + } else { + // no limitations, just rename file to target + if (rename(tmp.c_str(), outFile) != 0) { + printf("Failed to rename nib to %s err=%d\n", outFile, errno); + exit(-1); + return; + } + } } - - writer->WriteObjects(); } } -void ConvertXIBToNib(FILE* fpOut, pugi::xml_document& doc) { +void ConvertXIBToNib(const char *outFile, pugi::xml_document& doc) { pugi::xml_node dataNode = doc.first_element_by_path("/archive/data"); XIBObject* root = new XIBObject(); @@ -139,7 +321,6 @@ void ConvertXIBToNib(FILE* fpOut, pugi::xml_document& doc) { // Attempt to find any associated custom class name char szPropName[255]; sprintf(szPropName, "%d.CustomClassName", objId); - const char* pClassName = obj->ClassName(); XIBObject* customName = properties->ObjectForKey(szPropName); if (customName) { @@ -232,11 +413,28 @@ void ConvertXIBToNib(FILE* fpOut, pugi::xml_document& doc) { nibRoot->AddMember("UINibAccessibilityConfigurationsKey", accessibilityObjects); nibRoot->AddMember("UINibKeyValuePairsKey", new XIBArray()); + FILE* fpOut = fopen(outFile, "wb"); + if (!fpOut) { + printf("Error opening %s\n", outFile); + exit(-1); + return; + } + NIBWriter* writer = new NIBWriter(fpOut); writer->_allUIObjects = allObjects; writer->_visibleWindows = visibleWindows; writer->AddOutputObject(nibRoot); writer->WriteData(); + + fclose(fpOut); +} + +void printUsageAndExit(int code) { + printf("Usage:\n"); + printf("xib2nib [--minimum-deployment-target version] --compile \n"); + + TELEMETRY_FLUSH(); + exit(code); } int main(int argc, char* argv[]) { @@ -255,13 +453,60 @@ int main(int argc, char* argv[]) { } TELEMETRY_EVENT_DATA(L"Xib2NibStart", getProductVersion().c_str()); + + // parsing arguments + const char *inFile = NULL; + const char *outFile = NULL; + int minVersion = -1; + + int idx = 1; + while (idx < argc) { + if (*argv[idx] == '-') { + // parse argument + if (strcmp("--compile", argv[idx]) == 0) { + if (idx + 1 < argc) { + outFile = argv[idx + 1]; + idx += 2; + } else { + printf("Error missing argument after --compile\n"); + printUsageAndExit(-1); + return -1; + } + } else if (strcmp("--minimum-deployment-target", argv[idx]) == 0) { + if (idx + 1 < argc) { + minVersion = stringToVersion(argv[idx + 1]); + if (minVersion < 0) { + printf("Error invalid version argument %s\n", argv[idx + 1]); + printUsageAndExit(-1); + return -1; + } + idx += 2; + } else { + printf("Error missing argument after --compile\n"); + printUsageAndExit(-1); + return -1; + } + } else { + printf("Error unknown parameter %s\n", argv[idx]); + printUsageAndExit(-1); + return -1; + } + } else { + inFile = argv[idx]; + idx += 1; + } + } + + if (!inFile || !outFile) { + printf("Error missing required parameters"); + printUsageAndExit(-1); + return -1; + } pugi::xml_document doc; - pugi::xml_parse_result result = doc.load_file(argv[1]); + pugi::xml_parse_result result = doc.load_file(inFile); if (!result) { - printf("Error opening %s\n", argv[1]); - TELEMETRY_FLUSH(); - exit(2); + printf("Error opening %s\n", inFile); return -1; } @@ -269,54 +514,28 @@ int main(int argc, char* argv[]) { const char* type = getNodeAttrib(rootNode, "type"); if (!type) { printf("Unable to find input type\n"); - TELEMETRY_FLUSH(); - exit(3); return -1; } if (strcmp(rootNode.name(), "document") == 0 && strcmp(type, "com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB") == 0) { - if (argc < 3) { - printf("Usage: xib2nib input.storyboard \n"); - TELEMETRY_FLUSH(); - exit(1); - return -1; - } - struct stat st = { 0 }; - stat(argv[2], &st); - if (!(((st.st_mode) & S_IFMT) == S_IFDIR) && _mkdir(argv[2]) != 0) { - printf("Unable to create directory %s err=%d\n", argv[2], errno); + stat(outFile, &st); + if (!(((st.st_mode) & S_IFMT) == S_IFDIR) && _mkdir(outFile) != 0) { + printf("Unable to create directory %s err=%d\n", outFile, errno); return -1; } g_isStoryboard = true; - strcpy_s(g_outputDirectory, arraySize(g_outputDirectory), argv[2]); - ConvertStoryboard(doc); + strcpy_s(g_outputDirectory, arraySize(g_outputDirectory), outFile); + ConvertStoryboard(doc, minVersion); } else if (strstr(type, ".XIB") != NULL) { - if (argc < 3) { - printf("Usage: xib2nib input.xib output.nib\n"); - TELEMETRY_FLUSH(); - exit(1); - return -1; - } - - FILE* fpOut = fopen(argv[2], "wb"); - if (!fpOut) { - printf("Error opening %s\n", argv[2]); - TELEMETRY_FLUSH(); - exit(3); - return -1; - } - if (strcmp(rootNode.name(), "document") == 0) { - ConvertXIB3ToNib(fpOut, doc); + ConvertXIB3ToNib(outFile, doc, minVersion); } else { - ConvertXIBToNib(fpOut, doc); + ConvertXIBToNib(outFile, doc); } - fclose(fpOut); } else { printf("Unable to determine input type type=\"%s\"\n", type); TELEMETRY_FLUSH(); - exit(4); return -1; } From 60265b2a3e7ffcacdc4a1e7367396f91239100ed Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Fri, 2 Feb 2018 10:23:01 +0200 Subject: [PATCH 13/34] Work on warnings as there was many of these in XCode which was very distractive --- .../xib2nib/src/NSLayoutConstraint.cpp | 6 +-- tools/vsimporter/xib2nib/src/UIButton.cpp | 44 +++++-------------- tools/vsimporter/xib2nib/src/UIImageView.cpp | 2 +- tools/vsimporter/xib2nib/src/UILabel.cpp | 6 +-- tools/vsimporter/xib2nib/src/UIScrollView.cpp | 24 +++------- tools/vsimporter/xib2nib/src/UITableView.cpp | 2 +- tools/vsimporter/xib2nib/src/UITextField.cpp | 32 ++++---------- tools/vsimporter/xib2nib/src/UITextView.cpp | 32 ++++---------- tools/vsimporter/xib2nib/src/UIView.cpp | 4 +- .../xib2nib/src/UIViewController.cpp | 4 +- 10 files changed, 47 insertions(+), 109 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp index ee10d33271..2b14dc79f8 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp @@ -95,18 +95,18 @@ void NSLayoutConstraint::InitFromStory(XIBObject* obj) { ObjectConverterSwapper::InitFromStory(obj); const char* attr; - if (attr = obj->getAttrAndHandle("firstAttribute")) { + if ((attr = obj->getAttrAndHandle("firstAttribute"))) { if (storyToLayout.find(attr) != storyToLayout.end()) { _firstAttribute = storyToLayout[attr]; } } - if (attr = obj->getAttrAndHandle("secondAttribute")) { + if ((attr = obj->getAttrAndHandle("secondAttribute"))) { if (storyToLayout.find(attr) != storyToLayout.end()) { _secondAttribute = storyToLayout[attr]; } } - if (attr = obj->getAttrAndHandle("constant")) { + if ((attr = obj->getAttrAndHandle("constant"))) { if (obj->getAttrAndHandle("symbolic") && strcmp(obj->getAttrAndHandle("symbolic"), "YES") == 0) { _hasSymbolicConstant = true; _symbolicConstant = strtod(attr, NULL); diff --git a/tools/vsimporter/xib2nib/src/UIButton.cpp b/tools/vsimporter/xib2nib/src/UIButton.cpp index 185e8f8e3a..7605166969 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.cpp +++ b/tools/vsimporter/xib2nib/src/UIButton.cpp @@ -176,39 +176,17 @@ void UIButton::WriteStatefulContent(NIBWriter* writer, XIBObject* obj) { } static PropertyMapper propertyMappings[] = { - "IBUIText", - "UIText", - NULL, - "IBUITextColor", - "UITextColor", - NULL, - "IBUIHighlightedColor", - "UIHighlightedColor", - NULL, - "IBUILineBreakMode", - "UILineBreakMode", - NULL, - "IBUIContentEdgeInsets.top", - "Content", - ConvertInsets, - "IBUITitleEdgeInsets.top", - "Title", - ConvertInsets, - "IBUIImageEdgeInsets.top", - "Image", - ConvertInsets, - "IBUITitleShadowOffset", - "TitleShadow", - ConvertOffset, - "IBUIShowsTouchWhenHighlighted", - "UIShowsTouchWhenHighlighted", - NULL, - "IBUIImage", - "UIImage", - NULL, - "IBUIBackgroundImage", - "UIBackgroundImage", - NULL, + {"IBUIText", "UIText", NULL}, + {"IBUITextColor", "UITextColor", NULL}, + {"IBUIHighlightedColor", "UIHighlightedColor", NULL}, + {"IBUILineBreakMode", "LineBreakMode", NULL}, + {"IBUIContentEdgeInsets.top", "Content", ConvertInsets}, + {"IBUITitleEdgeInsets.top", "Title", ConvertInsets}, + {"IBUIImageEdgeInsets.top", "Image", ConvertInsets}, + {"IBUITitleShadowOffset", "TitleShadow", ConvertOffset}, + {"IBUIShowsTouchWhenHighlighted", "UIShowsTouchWhenHighlighted", NULL}, + {"IBUIImage", "UIImage", NULL}, + {"IBUIBackgroundImage", "UIBackgroundImage", NULL}, }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); diff --git a/tools/vsimporter/xib2nib/src/UIImageView.cpp b/tools/vsimporter/xib2nib/src/UIImageView.cpp index 5dce559d30..c833131925 100644 --- a/tools/vsimporter/xib2nib/src/UIImageView.cpp +++ b/tools/vsimporter/xib2nib/src/UIImageView.cpp @@ -18,7 +18,7 @@ #include "UICustomResource.h" static PropertyMapper propertyMappings[] = { - "IBUIImage", "UIImage", NULL, + {"IBUIImage", "UIImage", NULL} }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); diff --git a/tools/vsimporter/xib2nib/src/UILabel.cpp b/tools/vsimporter/xib2nib/src/UILabel.cpp index 848e878d2f..48616004da 100644 --- a/tools/vsimporter/xib2nib/src/UILabel.cpp +++ b/tools/vsimporter/xib2nib/src/UILabel.cpp @@ -29,8 +29,8 @@ static void WriteLayoutWidth(struct _PropertyMapper* prop, NIBWriter* writer, XI } static PropertyMapper propertyMappings[] = { - "IBUIShadowColor", "UIShadowColor", NULL, "IBUILineBreakMode", "UILineBreakMode", NULL, "preferredMaxLayoutWidth", - "UIPreferredMaxLayoutWidth", WriteLayoutWidth, + {"IBUIShadowColor", "UIShadowColor", NULL}, {"IBUILineBreakMode", "UILineBreakMode", NULL}, + {"preferredMaxLayoutWidth", "UIPreferredMaxLayoutWidth", WriteLayoutWidth}, }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); @@ -202,4 +202,4 @@ void UILabel::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { ObjectConverter* UILabel::Clone() { return new UILabel(); -} \ No newline at end of file +} diff --git a/tools/vsimporter/xib2nib/src/UIScrollView.cpp b/tools/vsimporter/xib2nib/src/UIScrollView.cpp index 3052501f89..c6e00ced8c 100644 --- a/tools/vsimporter/xib2nib/src/UIScrollView.cpp +++ b/tools/vsimporter/xib2nib/src/UIScrollView.cpp @@ -25,24 +25,12 @@ static void InvertBool(struct _PropertyMapper* prop, NIBWriter* writer, XIBObjec } static PropertyMapper propertyMappings[] = { - "IBUIScrollEnabled", - "UIScrollDisabled", - InvertBool, - "IBUIDelaysContentTouches", - "UIDelaysContentTouches", - NULL, - "IBUIDelaysContentTouches", - "UIDelaysContentTouches", - NULL, - "IBUIPagingEnabled", - "UIPagingEnabled", - NULL, - "IBUIShowsHorizontalScrollIndicator", - "UIShowsHorizontalScrollIndicator", - NULL, - "IBUIShowsVerticalScrollIndicator", - "UIShowsVerticalScrollIndicator", - NULL, + {"IBUIScrollEnabled", "UIScrollDisabled", InvertBool}, + {"IBUIDelaysContentTouches", "UIDelaysContentTouches", NULL}, + {"IBUIDelaysContentTouches", "UIDelaysContentTouches", NULL}, + {"IBUIPagingEnabled", "UIPagingEnabled", NULL}, + {"IBUIShowsHorizontalScrollIndicator", "UIShowsHorizontalScrollIndicator", NULL}, + {"IBUIShowsVerticalScrollIndicator", "UIShowsVerticalScrollIndicator", NULL}, }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); diff --git a/tools/vsimporter/xib2nib/src/UITableView.cpp b/tools/vsimporter/xib2nib/src/UITableView.cpp index f6c9a6861b..87e6fe25e7 100644 --- a/tools/vsimporter/xib2nib/src/UITableView.cpp +++ b/tools/vsimporter/xib2nib/src/UITableView.cpp @@ -18,7 +18,7 @@ #include "UIColor.h" static PropertyMapper propertyMappings[] = { - "IBUIShowsSelectionImmediatelyOnTouchBegin", "UIShowsSelectionImmediatelyOnTouchBegin", NULL, + {"IBUIShowsSelectionImmediatelyOnTouchBegin", "UIShowsSelectionImmediatelyOnTouchBegin", NULL}, }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); diff --git a/tools/vsimporter/xib2nib/src/UITextField.cpp b/tools/vsimporter/xib2nib/src/UITextField.cpp index 19f8bb30d4..6d6a7d4264 100644 --- a/tools/vsimporter/xib2nib/src/UITextField.cpp +++ b/tools/vsimporter/xib2nib/src/UITextField.cpp @@ -33,30 +33,14 @@ static void WriteLayoutWidth(struct _PropertyMapper* prop, NIBWriter* writer, XI } static PropertyMapper propertyMappings[] = { - "IBUIHighlightedColor", - "UIHighlightedColor", - NULL, - "IBUIShadowColor", - "UIShadowColor", - NULL, - "IBUIBaselineAdjustment", - "UIBaselineAdjustment", - NULL, - "IBUIMinimumFontSize", - "UIMinimumFontSize", - WriteMinimumFontSize, - "IBUINumberOfLines", - "UINumberOfLines", - NULL, - "IBUITextAlignment", - "UITextAlignment", - NULL, - "IBUILineBreakMode", - "UILineBreakMode", - NULL, - "preferredMaxLayoutWidth", - "UIPreferredMaxLayoutWidth", - WriteLayoutWidth, + {"IBUIHighlightedColor", "UIHighlightedColor", NULL}, + {"IBUIShadowColor", "UIShadowColor", NULL}, + {"IBUIBaselineAdjustment", "UIBaselineAdjustment", NULL}, + {"IBUIMinimumFontSize", "UIMinimumFontSize", WriteMinimumFontSize}, + {"IBUINumberOfLines", "UINumberOfLines", NULL}, + {"IBUITextAlignment", "UITextAlignment", NULL}, + {"IBUILineBreakMode", "UILineBreakMode", NULL}, + {"preferredMaxLayoutWidth", "UIPreferredMaxLayoutWidth", WriteLayoutWidth}, }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); diff --git a/tools/vsimporter/xib2nib/src/UITextView.cpp b/tools/vsimporter/xib2nib/src/UITextView.cpp index 498aff1d07..83c33c1884 100644 --- a/tools/vsimporter/xib2nib/src/UITextView.cpp +++ b/tools/vsimporter/xib2nib/src/UITextView.cpp @@ -33,30 +33,14 @@ static void WriteLayoutWidth(struct _PropertyMapper* prop, NIBWriter* writer, XI } static PropertyMapper propertyMappings[] = { - "IBUIHighlightedColor", - "UIHighlightedColor", - NULL, - "IBUIShadowColor", - "UIShadowColor", - NULL, - "IBUIBaselineAdjustment", - "UIBaselineAdjustment", - NULL, - "IBUIMinimumFontSize", - "UIMinimumFontSize", - WriteMinimumFontSize, - "IBUINumberOfLines", - "UINumberOfLines", - NULL, - "IBUITextAlignment", - "UITextAlignment", - NULL, - "IBUILineBreakMode", - "UILineBreakMode", - NULL, - "preferredMaxLayoutWidth", - "UIPreferredMaxLayoutWidth", - WriteLayoutWidth, + {"IBUIHighlightedColor", "UIHighlightedColor", NULL}, + {"IBUIShadowColor", "UIShadowColor", NULL}, + {"IBUIBaselineAdjustment", "UIBaselineAdjustment", NULL}, + {"IBUIMinimumFontSize", "UIMinimumFontSize", WriteMinimumFontSize}, + {"IBUINumberOfLines", "UINumberOfLines", NULL}, + {"IBUITextAlignment", "UITextAlignment", NULL}, + {"IBUILineBreakMode", "UILineBreakMode", NULL}, + {"preferredMaxLayoutWidth", "UIPreferredMaxLayoutWidth", WriteLayoutWidth}, }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); diff --git a/tools/vsimporter/xib2nib/src/UIView.cpp b/tools/vsimporter/xib2nib/src/UIView.cpp index 86cf101ce9..621e9eb8e8 100644 --- a/tools/vsimporter/xib2nib/src/UIView.cpp +++ b/tools/vsimporter/xib2nib/src/UIView.cpp @@ -31,7 +31,9 @@ static void InvertBool(struct _PropertyMapper* prop, NIBWriter* writer, XIBObjec } static PropertyMapper propertyMappings[] = { - "IBUIUserInteractionEnabled", "UIUserInteractionDisabled", InvertBool, "IBUITag", "UITag", NULL, "IBUIAlpha", "UIAlpha", NULL, + {"IBUIUserInteractionEnabled", "UIUserInteractionDisabled", InvertBool}, + {"IBUITag", "UITag", NULL}, + {"IBUIAlpha", "UIAlpha", NULL}, }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); diff --git a/tools/vsimporter/xib2nib/src/UIViewController.cpp b/tools/vsimporter/xib2nib/src/UIViewController.cpp index d50d7903d9..d5cfafa6e3 100644 --- a/tools/vsimporter/xib2nib/src/UIViewController.cpp +++ b/tools/vsimporter/xib2nib/src/UIViewController.cpp @@ -21,7 +21,9 @@ #include static PropertyMapper propertyMappings[] = { - "IBUINibName", "UINibName", NULL, "IBUIResizesToFullScreen", "UIResizesToFullScreen", NULL, "IBUITitle", "UITitle", NULL, + {"IBUINibName", "UINibName", NULL}, + {"IBUIResizesToFullScreen", "UIResizesToFullScreen", NULL}, + {"IBUITitle", "UITitle", NULL}, }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); From 6cdacebc0f8da0c2312000ee338cc406ca94b100 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Tue, 6 Feb 2018 09:29:58 +0200 Subject: [PATCH 14/34] NSLayoutConstraint fixed to use Double values as apple doesn't accept floats --- .../xib2nib/src/NSLayoutConstraint.cpp | 27 ++++++++++--------- .../xib2nib/src/NSLayoutConstraint.h | 8 +++--- 2 files changed, 18 insertions(+), 17 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp index 2b14dc79f8..601bb23205 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp @@ -48,10 +48,10 @@ NSLayoutConstraint::NSLayoutConstraint() { _firstAttribute = NSLayoutAttributeNotAnAttribute; _secondAttribute = NSLayoutAttributeNotAnAttribute; _relation = NSLayoutRelationEqual; - _multiplier = 1.0f; + _multiplier = 1.0; _priority = NSLayoutPriorityRequired; - _constant = 0.0f; - _symbolicConstant = 0.0f; + _constant = 0.0; + _symbolicConstant = 0.0; _hasSymbolicConstant = false; _layoutIdentifier = NULL; _exportDefaultValues = false; @@ -72,10 +72,10 @@ void NSLayoutConstraint::InitFromXIB(XIBObject* obj) { _multiplier = obj->FindMember("multiplier")->floatValue(); } if (obj->FindMember("priority")) { - _priority = obj->FindMember("priority")->floatValue(); + _priority = obj->FindMember("priority")->intValue(); } if (obj->FindMember("constant") && obj->FindMember("constant")->FindMember("value")) { - if (obj->FindMember("constant")->ClassName() == "IBLayoutConstant") { + if (strcmp(obj->FindMember("constant")->ClassName(), "IBLayoutConstant") == 0) { _constant = obj->FindMember("constant")->FindMember("value")->floatValue(); } else { _hasSymbolicConstant = true; @@ -114,19 +114,19 @@ void NSLayoutConstraint::InitFromStory(XIBObject* obj) { _constant = strtod(attr, NULL); } } - if (attr = obj->getAttrAndHandle("priority")) { + if ((attr = obj->getAttrAndHandle("priority"))) { _priority = strtod(attr, NULL); } - if (attr = obj->getAttrAndHandle("multiplier")) { + if ((attr = obj->getAttrAndHandle("multiplier"))) { _priority = strtod(attr, NULL); } - if (attr = getAttrAndHandle("secondItem")) { + if ((attr = getAttrAndHandle("secondItem"))) { _secondItem = findReference(attr); assert(_secondItem); } - if (attr = getAttrAndHandle("firstItem")) { + if ((attr = getAttrAndHandle("firstItem"))) { _firstItem = findReference(attr); assert(_firstItem); } @@ -149,7 +149,8 @@ void NSLayoutConstraint::Awaken() { void NSLayoutConstraint::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { AddInt(writer, "NSFirstAttribute", _firstAttribute); - AddInt(writer, "NSSecondAttribute", _secondAttribute); + if (_secondAttribute) + AddInt(writer, "NSSecondAttribute", _secondAttribute); if (_exportDefaultValues || _relation != NSLayoutRelationEqual) AddInt(writer, "NSRelation", _relation); @@ -160,15 +161,15 @@ void NSLayoutConstraint::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj AddOutputMember(writer, "NSSecondItem", substituteItemUnsupported(writer, _secondItem)); if (_exportDefaultValues || _multiplier != 1.0f) - AddOutputMember(writer, "NSMultiplier", new XIBObjectFloat(_multiplier)); + AddOutputMember(writer, "NSMultiplier", new XIBObjectDouble(_multiplier)); if (_exportDefaultValues || _priority != NSLayoutPriorityRequired) AddInt(writer, "NSPriority", _priority); if (_hasSymbolicConstant) { - AddOutputMember(writer, "NSSymbolicConstant", new XIBObjectFloat(_symbolicConstant)); + AddOutputMember(writer, "NSSymbolicConstant", new XIBObjectDouble(_symbolicConstant)); } else { if (_exportDefaultValues || _constant != 0) - AddOutputMember(writer, "NSConstant", new XIBObjectFloat(_constant)); + AddOutputMember(writer, "NSConstant", new XIBObjectDouble(_constant)); } if (_layoutIdentifier) diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h index cfab4c09cc..f61663332b 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h @@ -70,10 +70,10 @@ class NSLayoutConstraint : public ObjectConverterSwapper { int _firstAttribute; int _secondAttribute; int _relation; - float _multiplier; - float _priority; - float _constant; - float _symbolicConstant; + double _multiplier; + int _priority; + double _constant; + double _symbolicConstant; bool _hasSymbolicConstant; const char* _layoutIdentifier; bool _exportDefaultValues; From be686f49b73e3cabccff3ce78a8ca86f86c9a3c5 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Tue, 6 Feb 2018 09:30:56 +0200 Subject: [PATCH 15/34] Added UIAdjustsFontSizeToFit=true when there is any adjustment as otherwise apple doesn't read UIMinimumFontSize and UIMinimumScaleFactor --- tools/vsimporter/xib2nib/src/UILabel.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tools/vsimporter/xib2nib/src/UILabel.cpp b/tools/vsimporter/xib2nib/src/UILabel.cpp index 48616004da..432a0fe3f5 100644 --- a/tools/vsimporter/xib2nib/src/UILabel.cpp +++ b/tools/vsimporter/xib2nib/src/UILabel.cpp @@ -185,8 +185,10 @@ void UILabel::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { } if (_minimumFontSize != -1.0f) { + AddBool(writer, "UIAdjustsFontSizeToFit", true); AddOutputMember(writer, "UIMinimumFontSize", new XIBObjectFloat(_minimumFontSize)); } else if (_minimumScaleFactor != -1.0f) { + AddBool(writer, "UIAdjustsFontSizeToFit", true); AddOutputMember(writer, "UIMinimumScaleFactor", new XIBObjectFloat(_minimumScaleFactor)); } else { AddBool(writer, "UIAdjustsFontSizeToFit", false); From 73bd004af8ea8763fbad61afc8543cd0ac9af2e1 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Tue, 6 Feb 2018 09:51:48 +0200 Subject: [PATCH 16/34] UILineBreakMode attribute reworked in UILabel, also it was added to UIButton --- tools/vsimporter/xib2nib/src/UIButton.cpp | 17 ++++++++++++ tools/vsimporter/xib2nib/src/UIButton.h | 1 + tools/vsimporter/xib2nib/src/UILabel.cpp | 34 ++++++++++------------- tools/vsimporter/xib2nib/src/UILabel.h | 15 ++++++++++ 4 files changed, 47 insertions(+), 20 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/UIButton.cpp b/tools/vsimporter/xib2nib/src/UIButton.cpp index 7605166969..69f1bd7040 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.cpp +++ b/tools/vsimporter/xib2nib/src/UIButton.cpp @@ -20,6 +20,7 @@ #include "UICustomResource.h" #include "UIRuntimeEventConnection.h" #include "UIFont.h" +#include "UILabel.h" #include void ConvertInsets(struct _PropertyMapper* prop, NIBWriter* writer, XIBObject* propObj, XIBObject* obj) { @@ -195,6 +196,9 @@ UIButton::UIButton() { _statefulContent = NULL; _font = NULL; + // default line break mode is middleTrucation + _lineBreakMode = UILineBreakModeMiddleTruncation; + // Default is true for both of these, so no need to write to nib if that's the case _adjustsImageWhenHighlighted = true; _adjustsImageWhenDisabled = true; @@ -239,6 +243,15 @@ void UIButton::InitFromStory(XIBObject* obj) { _font = (UIFont*)obj->FindMemberAndHandle("fontDescription"); + const char* lineBreakModeAttributeValue = getAttrib("lineBreakMode"); + if (lineBreakModeAttributeValue) { + if (storyToUILineBreakMode.find(lineBreakModeAttributeValue) != storyToUILineBreakMode.end()) { + _lineBreakMode = storyToUILineBreakMode[lineBreakModeAttributeValue]; + } else { + printf("invalid linebreak value %s, using default (tailTruncation) \n", lineBreakModeAttributeValue); + } + } + if (getAttrib("adjustsImageWhenDisabled")) { if (strcmp(getAttrAndHandle("adjustsImageWhenDisabled"), "NO") == 0) { _adjustsImageWhenDisabled = false; @@ -269,6 +282,10 @@ void UIButton::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { obj->AddOutputMember(writer, "UIFont", _font); } + if (_lineBreakMode != UILineBreakModeMiddleTruncation) { + AddInt(writer, "UILineBreakMode", _lineBreakMode); + } + // Default is true, so no need to write to nib if that's the case if (!_adjustsImageWhenHighlighted) { AddBool(writer, "UIAdjustsImageWhenHighlighted", false); diff --git a/tools/vsimporter/xib2nib/src/UIButton.h b/tools/vsimporter/xib2nib/src/UIButton.h index 0c923abb37..8b794c12f0 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.h +++ b/tools/vsimporter/xib2nib/src/UIButton.h @@ -43,6 +43,7 @@ class UIButton : public UIControl { EdgeInsets _imageEdgeInsets; EdgeInsets _contentEdgeInsets; EdgeInsets _titleEdgeInsets; + int _lineBreakMode; UIButton(); virtual void InitFromXIB(XIBObject* obj); diff --git a/tools/vsimporter/xib2nib/src/UILabel.cpp b/tools/vsimporter/xib2nib/src/UILabel.cpp index 432a0fe3f5..6b52deac68 100644 --- a/tools/vsimporter/xib2nib/src/UILabel.cpp +++ b/tools/vsimporter/xib2nib/src/UILabel.cpp @@ -34,6 +34,16 @@ static PropertyMapper propertyMappings[] = { }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); +std::map storyToUILineBreakMode = { + { "wordWrap", UILineBreakModeWordWrap }, + { "characterWrap", UILineBreakModeCharacterWrap }, + { "clip", UILineBreakModeClip }, + { "headTruncation", UILineBreakModeHeadTruncation }, + { "tailTruncation", UILineBreakModeTailTruncation }, + { "middleTruncation", UILineBreakModeMiddleTruncation }, +}; + + UILabel::UILabel() { _text = NULL; _textAlignment = 0; @@ -46,7 +56,7 @@ UILabel::UILabel() { _font = NULL; // default line break mode is tailTrucation - _lineBreakMode = 4; + _lineBreakMode = UILineBreakModeTailTruncation; } void UILabel::InitFromXIB(XIBObject* obj) { @@ -97,24 +107,8 @@ void UILabel::InitFromStory(XIBObject* obj) { const char* lineBreakModeAttributeString = "lineBreakMode"; const char* lineBreakModeAttributeValue = getAttrib(lineBreakModeAttributeString); if (lineBreakModeAttributeValue) { - if (strcmp(lineBreakModeAttributeValue, "wordWrap") == 0) { - _lineBreakMode = 0; - getAttrAndHandle(lineBreakModeAttributeString); - } else if (strcmp(lineBreakModeAttributeValue, "characterWrap") == 0) { - _lineBreakMode = 1; - getAttrAndHandle(lineBreakModeAttributeString); - } else if (strcmp(lineBreakModeAttributeValue, "clip") == 0) { - _lineBreakMode = 2; - getAttrAndHandle(lineBreakModeAttributeString); - } else if (strcmp(lineBreakModeAttributeValue, "headTruncation") == 0) { - _lineBreakMode = 3; - getAttrAndHandle(lineBreakModeAttributeString); - } else if (strcmp(lineBreakModeAttributeValue, "tailTruncation") == 0) { - _lineBreakMode = 4; - getAttrAndHandle(lineBreakModeAttributeString); - } else if (strcmp(lineBreakModeAttributeValue, "middleTruncation") == 0) { - _lineBreakMode = 5; - getAttrAndHandle(lineBreakModeAttributeString); + if (storyToUILineBreakMode.find(lineBreakModeAttributeValue) != storyToUILineBreakMode.end()) { + _lineBreakMode = storyToUILineBreakMode[lineBreakModeAttributeValue]; } else { printf("invalid linebreak value %s, using default (tailTruncation) \n", lineBreakModeAttributeValue); } @@ -176,7 +170,7 @@ void UILabel::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { AddInt(writer, "UINumberOfLines", _numberOfLines); } - if (_lineBreakMode != 4) { + if (_lineBreakMode != UILineBreakModeTailTruncation) { AddInt(writer, "UILineBreakMode", _lineBreakMode); } diff --git a/tools/vsimporter/xib2nib/src/UILabel.h b/tools/vsimporter/xib2nib/src/UILabel.h index 2c113863fe..3c7e616895 100644 --- a/tools/vsimporter/xib2nib/src/UILabel.h +++ b/tools/vsimporter/xib2nib/src/UILabel.h @@ -16,10 +16,25 @@ #pragma once #include "UIView.h" +#include class UIColor; class UIFont; +// line break mode used in both UILabel and UIButton (possible other places as well) +typedef enum { + UILineBreakModeWordWrap = 0, + UILineBreakModeCharacterWrap, + UILineBreakModeClip, + UILineBreakModeHeadTruncation, + UILineBreakModeTailTruncation, + UILineBreakModeMiddleTruncation +} UILineBreakMode; + + +// helper map initialized in UILabel.cpp +extern std::map storyToUILineBreakMode; + class UILabel : public UIView { private: CGSize _shadowOffset; From 974b17b83fcecde812b666fcaefdd65087f32de5 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Tue, 6 Feb 2018 13:41:39 +0200 Subject: [PATCH 17/34] fixed bug: multiplier was not initialized in constraint and was corrupting priority --- tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp index 601bb23205..42a376189d 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp @@ -119,7 +119,7 @@ void NSLayoutConstraint::InitFromStory(XIBObject* obj) { } if ((attr = obj->getAttrAndHandle("multiplier"))) { - _priority = strtod(attr, NULL); + _multiplier = strtod(attr, NULL); } if ((attr = getAttrAndHandle("secondItem"))) { From 37a372fdc614d267b00804467ad290d470a0d084 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Tue, 6 Feb 2018 16:38:29 +0200 Subject: [PATCH 18/34] fixed priority read out for NSLayoutConstraint --- tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp index 42a376189d..5a083b7668 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp @@ -19,6 +19,7 @@ #include "UILayoutGuide.h" #include +#include #include std::map storyToLayout = { { "left", NSLayoutAttributeLeft }, @@ -115,7 +116,7 @@ void NSLayoutConstraint::InitFromStory(XIBObject* obj) { } } if ((attr = obj->getAttrAndHandle("priority"))) { - _priority = strtod(attr, NULL); + _priority = std::stoi(attr, NULL); } if ((attr = obj->getAttrAndHandle("multiplier"))) { From 4ff2f38bdeee100815572726bc1f5752d00ca61b Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Tue, 6 Feb 2018 16:39:54 +0200 Subject: [PATCH 19/34] fixed UITableViewCell: it wasn't properly read for storyboard parsing --- .../xib2nib/src/UITableViewCell.cpp | 75 ++++++++++++++++++- .../vsimporter/xib2nib/src/UITableViewCell.h | 30 +++++++- 2 files changed, 102 insertions(+), 3 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/UITableViewCell.cpp b/tools/vsimporter/xib2nib/src/UITableViewCell.cpp index 8b298cb338..31bf410dab 100644 --- a/tools/vsimporter/xib2nib/src/UITableViewCell.cpp +++ b/tools/vsimporter/xib2nib/src/UITableViewCell.cpp @@ -15,15 +15,39 @@ //****************************************************************************** #include "UITableViewCell.h" +#include + + +static std::map storyToSelectionStyle = { + { "none", UISelectionStyleNone }, + { "blue", UISelectionStyleBlue }, + { "gray", UISelectionStyleGray }, + { "default", UISelectionStyleDefault }}; + +static std::map storyToAccessoryType = { + { "disclosureIndicator", UIAccessoryTypeDisclosureIndicator }, + { "disclosureButton", UIAccessoryTypeDetailDisclosureButton }, + { "checkmark", UIAccessoryTypeCheckmark }, + { "detailButton", UIAccessoryTypeDetailButton }}; + +static std::map storyToCellStyle = { + { "IBUITableViewCellStyleDefault", UITableViewCellStyleBasic }, + { "IBUITableViewCellStyleValue1", UITableViewCellStyleRightDetails }, + { "IBUITableViewCellStyleValue2", UITableViewCellStyleLeftDetails }, + { "IBUITableViewCellStyleSubtitle", UITableViewCellStyleSubtitle }}; UITableViewCell::UITableViewCell() { _indentationLevel = 0; - _indentationWidth = 0; - _selectionStyle = 0; + _indentationWidth = 0.0f; + _selectionStyle = UISelectionStyleDefault; + _accessoryType = UIAccessoryTypeNone; + _editingAccessoryType = UIAccessoryTypeNone; + _cellStyle = UITableViewCellStyleCustom; _reuseIdentifier = NULL; _detailTextLabel = NULL; _imageView = NULL; _textLabel = NULL; + _focusStyleCustom = false; } void UITableViewCell::InitFromXIB(XIBObject* obj) { @@ -47,7 +71,44 @@ void UITableViewCell::InitFromStory(XIBObject* obj) { obj->_outputClassName = "UITableViewCell"; + const char* attr; + if ((attr = obj->getAttrAndHandle("style"))) { + if (storyToCellStyle.find(attr) != storyToCellStyle.end()) { + _cellStyle = storyToCellStyle[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("selectionStyle"))) { + if (storyToSelectionStyle.find(attr) != storyToSelectionStyle.end()) { + _selectionStyle = storyToSelectionStyle[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("editingAccessoryType"))) { + if (storyToAccessoryType.find(attr) != storyToAccessoryType.end()) { + _editingAccessoryType = storyToAccessoryType[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("accessoryType"))) { + if (storyToAccessoryType.find(attr) != storyToAccessoryType.end()) { + _accessoryType = storyToAccessoryType[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("indentationWidth"))) { + _indentationWidth = strtof(attr, NULL); + } + + if ((attr = obj->getAttrAndHandle("focusStyle"))) { + if (strcmp(attr, "custom") == 0) + _focusStyleCustom = true; + } + + _reuseIdentifier = obj->getAttrAndHandle("reuseIdentifier"); _contentView = (UIView*)obj->FindMemberAndHandle("contentView"); + if (_contentView) + _subviews->AddMember(NULL, _contentView); } void UITableViewCell::Awaken() { @@ -92,6 +153,16 @@ void UITableViewCell::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { obj->AddOutputMember(writer, "UITextLabel", _textLabel); if (_detailTextLabel) obj->AddOutputMember(writer, "UIDetailTextLabel", _detailTextLabel); + + if (_accessoryType != UIAccessoryTypeNone) + obj->AddInt(writer, "UIAccessoryType", _accessoryType); + if (_editingAccessoryType != UIAccessoryTypeNone) + obj->AddInt(writer, "UIEditingAccessoryType", _editingAccessoryType); + if (_cellStyle != UITableViewCellStyleCustom) + obj->AddInt(writer, "UITableViewCellStyle", _cellStyle); + if (_focusStyleCustom) + obj->AddInt(writer, "UIFocusStyle", 1); + obj->AddBool(writer, "UITableCellBackgroundColorSet", true); obj->AddInt(writer, "UISelectionStyle", _selectionStyle); } diff --git a/tools/vsimporter/xib2nib/src/UITableViewCell.h b/tools/vsimporter/xib2nib/src/UITableViewCell.h index 624308300b..e7c97af56d 100644 --- a/tools/vsimporter/xib2nib/src/UITableViewCell.h +++ b/tools/vsimporter/xib2nib/src/UITableViewCell.h @@ -16,6 +16,31 @@ #pragma once #include "UIView.h" + +typedef enum { + UISelectionStyleNone = 0, + UISelectionStyleBlue, + UISelectionStyleGray, + UISelectionStyleDefault, +} UISelectionStyle; + +typedef enum { + UIAccessoryTypeNone = 0, + UIAccessoryTypeDisclosureIndicator, + UIAccessoryTypeDetailDisclosureButton, + UIAccessoryTypeCheckmark, + UIAccessoryTypeDetailButton +} UIAccessoryType; + + +typedef enum { + UITableViewCellStyleCustom = 0, + UITableViewCellStyleBasic = UITableViewCellStyleCustom, + UITableViewCellStyleRightDetails, + UITableViewCellStyleLeftDetails, + UITableViewCellStyleSubtitle, +} UITableViewCellStyle; + class UITableViewCell : public UIView { private: const char* _reuseIdentifier; @@ -25,7 +50,10 @@ class UITableViewCell : public UIView { int _selectionStyle; int _indentationLevel; float _indentationWidth; - + int _accessoryType; + int _editingAccessoryType; + int _cellStyle; + bool _focusStyleCustom; public: UITableViewCell(); virtual void Awaken(); From bc8909d616d80aba01b197dfb01ff615e1e753c8 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Wed, 7 Feb 2018 12:11:06 +0200 Subject: [PATCH 20/34] NSLayoutConstraint -- relation was not parsed --- tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp index 5a083b7668..245e0fe5ed 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp @@ -43,6 +43,10 @@ std::map storyToLayout = { { "left", NSLayoutAtt { "centerXWithinMargins", NSLayoutAttributeCenterXWithinMargins }, { "centerYWithinMargins", NSLayoutAttributeCenterYWithinMargins } }; +static std::map storyToRelation = { + { "greaterThanOrEqual", NSLayoutRelationGreaterThanOrEqual }, + { "lessThanOrEqual", NSLayoutRelationLessThanOrEqual }}; + NSLayoutConstraint::NSLayoutConstraint() { _firstItem = NULL; _secondItem = NULL; @@ -127,11 +131,18 @@ void NSLayoutConstraint::InitFromStory(XIBObject* obj) { _secondItem = findReference(attr); assert(_secondItem); } + if ((attr = getAttrAndHandle("firstItem"))) { _firstItem = findReference(attr); assert(_firstItem); } + if ((attr = obj->getAttrAndHandle("relation"))) { + if (storyToRelation.find(attr) != storyToRelation.end()) { + _relation = storyToRelation[attr]; + } + } + _outputClassName = "NSLayoutConstraint"; } From 2e7297b8b456dcdd18c36bf353e7d95e5e243d22 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Wed, 7 Feb 2018 17:01:54 +0200 Subject: [PATCH 21/34] Changes to skip NSLayoutConstaint marked as placeholder --- .../xib2nib/src/NSLayoutConstraint.cpp | 5 +++++ .../xib2nib/src/NSLayoutConstraint.h | 2 ++ tools/vsimporter/xib2nib/src/UIView.cpp | 19 ++++++++++++++++++- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp index 245e0fe5ed..3cf13c3ef8 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp @@ -59,6 +59,7 @@ NSLayoutConstraint::NSLayoutConstraint() { _symbolicConstant = 0.0; _hasSymbolicConstant = false; _layoutIdentifier = NULL; + _placeholder = false; _exportDefaultValues = false; } @@ -143,6 +144,10 @@ void NSLayoutConstraint::InitFromStory(XIBObject* obj) { } } + if ((attr = obj->getAttrAndHandle("placeholder"))) { + _placeholder = strcmp(attr, "YES") == 0; + } + _outputClassName = "NSLayoutConstraint"; } diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h index f61663332b..950c95a328 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.h @@ -27,6 +27,7 @@ enum { NSLayoutPriorityDefaultLow = 250, NSLayoutPriorityFittingSizeCompression = 50, }; + typedef float NSLayoutPriority; typedef enum { @@ -76,6 +77,7 @@ class NSLayoutConstraint : public ObjectConverterSwapper { double _symbolicConstant; bool _hasSymbolicConstant; const char* _layoutIdentifier; + bool _placeholder; bool _exportDefaultValues; public: diff --git a/tools/vsimporter/xib2nib/src/UIView.cpp b/tools/vsimporter/xib2nib/src/UIView.cpp index 621e9eb8e8..377417005d 100644 --- a/tools/vsimporter/xib2nib/src/UIView.cpp +++ b/tools/vsimporter/xib2nib/src/UIView.cpp @@ -21,6 +21,7 @@ #include #include "UIRuntimeOutletCollectionConnection.h" #include "UILayoutGuide.h" +#include "NSLayoutConstraint.h" static void InvertBool(struct _PropertyMapper* prop, NIBWriter* writer, XIBObject* propObj, XIBObject* obj) { XIBObjectBool* value = (XIBObjectBool*)propObj; @@ -316,7 +317,23 @@ void UIView::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { } if (_constraints->count() > 0) { - AddOutputMember(writer, "UIViewAutolayoutConstraints", _constraints); + // remove placeholders + XIBArray *tmp = new XIBArray(); + for (int i = 0; i < _constraints->count(); i++) { + XIBObject *obj = _constraints->objectAtIndex(i); + if (obj->_outputClassName && strcmp(obj->_outputClassName, "NSLayoutConstraint") == 0) { + NSLayoutConstraint *constraint = (NSLayoutConstraint*)obj; + if (constraint->_placeholder) + continue; + } + tmp->AddMember(NULL, obj); + } + if (tmp->count()) + AddOutputMember(writer, "UIViewAutolayoutConstraints", tmp); + // FIXME: commented out as it produce a warning that XIBArrays is not final + // so tmp will leak here + // else + // delete tmp; } if (_layoutGuides->count() > 0) { From b7a3e137a5ca83d21be634a13c2ead5b11e3ffe2 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Wed, 7 Feb 2018 17:41:46 +0200 Subject: [PATCH 22/34] fixed hugging priority and compression resistance as these are handled different way now --- .../xib2nib/src/NSLayoutConstraint.cpp | 9 +--- tools/vsimporter/xib2nib/src/UIView.cpp | 45 ++++++++++--------- tools/vsimporter/xib2nib/src/UIView.h | 8 ++-- 3 files changed, 29 insertions(+), 33 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp index 3cf13c3ef8..41b70c3618 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp @@ -154,13 +154,8 @@ void NSLayoutConstraint::InitFromStory(XIBObject* obj) { void NSLayoutConstraint::Awaken() { if (!_firstItem) { // Alludes to superview. - if (_secondItem && _secondItem->_parent) { - _firstItem = dynamic_cast(_secondItem->_parent->_parent); - assert(_firstItem); - } else { - _firstItem = dynamic_cast(_parent->_parent); - assert(_firstItem); - } + _firstItem = dynamic_cast(_parent->_parent); + assert(_firstItem); } } diff --git a/tools/vsimporter/xib2nib/src/UIView.cpp b/tools/vsimporter/xib2nib/src/UIView.cpp index 377417005d..0f9997bfcf 100644 --- a/tools/vsimporter/xib2nib/src/UIView.cpp +++ b/tools/vsimporter/xib2nib/src/UIView.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "UIRuntimeOutletCollectionConnection.h" #include "UILayoutGuide.h" #include "NSLayoutConstraint.h" @@ -38,6 +39,11 @@ static PropertyMapper propertyMappings[] = { }; static const int numPropertyMappings = sizeof(propertyMappings) / sizeof(PropertyMapper); +enum { + NSContentHugginPriorityDefault = 250, + NSContentCompressionResistancePriorityDefault = 750 +}; + UIView::UIView() { memset(&_bounds, 0, sizeof(_bounds)); memset(&_center, 0, sizeof(_center)); @@ -58,10 +64,10 @@ UIView::UIView() { _enabled = true; _translatesAutoresizeToConstraints = true; _tag = -1; - _horizontalHuggingPriority = -1.0; - _verticalHuggingPriority = -1.0; - _horizontalCompressionResistancePriority = -1.0; - _verticalCompressionResistancePriority = -1.0; + _horizontalHuggingPriority = NSContentHugginPriorityDefault; + _verticalHuggingPriority = NSContentHugginPriorityDefault; + _horizontalCompressionResistancePriority = NSContentCompressionResistancePriorityDefault; + _verticalCompressionResistancePriority = NSContentCompressionResistancePriorityDefault; } void UIView::InitFromXIB(XIBObject* obj) { @@ -272,19 +278,19 @@ void UIView::InitFromStory(XIBObject* obj) { } if (getAttrib("horizontalHuggingPriority")) { - _horizontalHuggingPriority = strtof(getAttrAndHandle("horizontalHuggingPriority"), NULL); + _horizontalHuggingPriority = std::stoi(getAttrAndHandle("horizontalHuggingPriority"), NULL); } if (getAttrib("verticalHuggingPriority")) { - _verticalHuggingPriority = strtof(getAttrAndHandle("verticalHuggingPriority"), NULL); + _verticalHuggingPriority = std::stoi(getAttrAndHandle("verticalHuggingPriority"), NULL); } if (getAttrib("horizontalCompressionResistancePriority")) { - _horizontalCompressionResistancePriority = strtof(getAttrAndHandle("horizontalCompressionResistancePriority"), NULL); + _horizontalCompressionResistancePriority = std::stoi(getAttrAndHandle("horizontalCompressionResistancePriority"), NULL); } if (getAttrib("verticalCompressionResistancePriority")) { - _verticalCompressionResistancePriority = strtof(getAttrAndHandle("verticalCompressionResistancePriority"), NULL); + _verticalCompressionResistancePriority = std::stoi(getAttrAndHandle("verticalCompressionResistancePriority"), NULL); } _outputClassName = "UIView"; @@ -397,22 +403,17 @@ void UIView::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { obj->AddInt(writer, "UITag", _tag); } - if (_horizontalHuggingPriority >= 0.0) { - AddOutputMember(writer, "UIViewHorizontalHuggingPriority", new XIBObjectFloat(_horizontalHuggingPriority)); - } - - if (_verticalHuggingPriority >= 0.0) { - AddOutputMember(writer, "UIViewVerticalHuggingPriority", new XIBObjectFloat(_verticalHuggingPriority)); - } - - if (_horizontalCompressionResistancePriority >= 0.0) { - AddOutputMember(writer, - "UIViewHorizontalCompressionResistancePriority", - new XIBObjectFloat(_horizontalCompressionResistancePriority)); + if (_horizontalHuggingPriority != NSContentHugginPriorityDefault || _verticalHuggingPriority != NSContentHugginPriorityDefault) { + char buf[128]; + snprintf(buf, 128, "{%d, %d}", _horizontalHuggingPriority, _verticalHuggingPriority); + obj->AddString(writer, "UIViewContentHuggingPriority", strdup(buf)); } - if (_verticalCompressionResistancePriority >= 0.0) { - AddOutputMember(writer, "UIViewVerticalCompressionResistancePriority", new XIBObjectFloat(_verticalCompressionResistancePriority)); + if (_horizontalCompressionResistancePriority != NSContentCompressionResistancePriorityDefault || + _verticalCompressionResistancePriority != NSContentCompressionResistancePriorityDefault) { + char buf[128]; + snprintf(buf, 128, "{%d, %d}", _horizontalCompressionResistancePriority, _verticalCompressionResistancePriority); + obj->AddString(writer, "UIViewContentCompressionResistancePriority", strdup(buf)); } ObjectConverterSwapper::ConvertStaticMappings(writer, obj); diff --git a/tools/vsimporter/xib2nib/src/UIView.h b/tools/vsimporter/xib2nib/src/UIView.h index 69afb5f044..097cec05c8 100644 --- a/tools/vsimporter/xib2nib/src/UIView.h +++ b/tools/vsimporter/xib2nib/src/UIView.h @@ -65,10 +65,10 @@ class UIView : public ObjectConverterSwapper { bool _userInteractionDisabled; bool _clearsContextBeforeDrawing; int _tag; - float _horizontalHuggingPriority; - float _verticalHuggingPriority; - float _horizontalCompressionResistancePriority; - float _verticalCompressionResistancePriority; + int _horizontalHuggingPriority; + int _verticalHuggingPriority; + int _horizontalCompressionResistancePriority; + int _verticalCompressionResistancePriority; public: UIView(); From 53562afc75348f4139185079fa95edcc6cab8c16 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Thu, 8 Feb 2018 10:41:19 +0200 Subject: [PATCH 23/34] NSLayoutConstraint: fixed multiplier parsing if it present in form of relation e.g. "100:200" --- tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp index 41b70c3618..6551a511ee 100644 --- a/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp +++ b/tools/vsimporter/xib2nib/src/NSLayoutConstraint.cpp @@ -125,7 +125,13 @@ void NSLayoutConstraint::InitFromStory(XIBObject* obj) { } if ((attr = obj->getAttrAndHandle("multiplier"))) { - _multiplier = strtod(attr, NULL); + char *separator; + _multiplier = strtod(attr, &separator); + if (*separator == ':') { + // it is multiplier in form of "100:200" + double div = strtod(separator + 1, NULL); + _multiplier /= div; + } } if ((attr = getAttrAndHandle("secondItem"))) { From 80f31040bb07bd36816d134ebce6856df88c3e41 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Thu, 8 Feb 2018 11:30:38 +0200 Subject: [PATCH 24/34] UIButton: added support for Tint color --- tools/vsimporter/xib2nib/src/UIButton.cpp | 18 ++++++++++++------ tools/vsimporter/xib2nib/src/UIButton.h | 1 + 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/UIButton.cpp b/tools/vsimporter/xib2nib/src/UIButton.cpp index 69f1bd7040..56ca820669 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.cpp +++ b/tools/vsimporter/xib2nib/src/UIButton.cpp @@ -195,6 +195,7 @@ UIButton::UIButton() { _buttonType = 0; _statefulContent = NULL; _font = NULL; + _tintColor = NULL; // default line break mode is middleTrucation _lineBreakMode = UILineBreakModeMiddleTruncation; @@ -242,6 +243,7 @@ void UIButton::InitFromStory(XIBObject* obj) { } _font = (UIFont*)obj->FindMemberAndHandle("fontDescription"); + _tintColor = (UIColor*)FindMemberAndHandle("tintColor"); const char* lineBreakModeAttributeValue = getAttrib("lineBreakMode"); if (lineBreakModeAttributeValue) { @@ -282,18 +284,22 @@ void UIButton::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { obj->AddOutputMember(writer, "UIFont", _font); } + if (_tintColor) { + AddOutputMember(writer, "UITintColor", _tintColor); + } + if (_lineBreakMode != UILineBreakModeMiddleTruncation) { AddInt(writer, "UILineBreakMode", _lineBreakMode); } - // Default is true, so no need to write to nib if that's the case - if (!_adjustsImageWhenHighlighted) { - AddBool(writer, "UIAdjustsImageWhenHighlighted", false); + // Default in NIB is false, so no need to write to nib if that's the case + if (_adjustsImageWhenHighlighted) { + AddBool(writer, "UIAdjustsImageWhenHighlighted", true); } - // Default is true, so no need to write to nib if that's the case - if (!_adjustsImageWhenDisabled) { - AddBool(writer, "UIAdjustsImageWhenDisabled", false); + // Default in NIB is false, so no need to write to nib if that's the case + if (_adjustsImageWhenDisabled) { + AddBool(writer, "UIAdjustsImageWhenDisabled", true); } // Insets diff --git a/tools/vsimporter/xib2nib/src/UIButton.h b/tools/vsimporter/xib2nib/src/UIButton.h index 8b794c12f0..ad541335c1 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.h +++ b/tools/vsimporter/xib2nib/src/UIButton.h @@ -37,6 +37,7 @@ class UIButton : public UIControl { public: int _buttonType; UIFont* _font; + UIColor* _tintColor; XIBObject* _statefulContent; bool _adjustsImageWhenHighlighted; bool _adjustsImageWhenDisabled; From b1fabf694ef8a77d3196b9c92bcc4c6ebff47146 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Thu, 8 Feb 2018 13:53:01 +0200 Subject: [PATCH 25/34] added support for UITextInputTraits which enables lot of configuration of UITextField (like content type, keyboard type etc) but important one is secure content -- for passwords --- .../xib2nib/src/ObjectConverter.cpp | 2 + tools/vsimporter/xib2nib/src/UITextField.cpp | 20 +- tools/vsimporter/xib2nib/src/UITextField.h | 4 +- .../xib2nib/src/UITextInputTraits.cpp | 192 ++++++++++++++++++ .../xib2nib/src/UITextInputTraits.h | 81 ++++++++ 5 files changed, 282 insertions(+), 17 deletions(-) create mode 100644 tools/vsimporter/xib2nib/src/UITextInputTraits.cpp create mode 100644 tools/vsimporter/xib2nib/src/UITextInputTraits.h diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp index 86a82343f3..5684119921 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp @@ -21,6 +21,7 @@ #include "UIColor.h" #include "UIButton.h" #include "UIFont.h" +#include "UITextInputTraits.h" #include "UIRuntimeEventConnection.h" #include "UIRuntimeOutletConnection.h" #include "UIRuntimeOutletCollectionConnection.h" @@ -171,6 +172,7 @@ XIBObject* ObjectConverter::ConverterForStoryObject(const char* className, pugi: IS_CONVERTER(ret, className, "outletCollection", UIRuntimeOutletCollectionConnection) IS_CONVERTER(ret, className, "segue", UIStoryboardSegue) IS_CONVERTER(ret, className, "fontDescription", UIFont) + IS_CONVERTER(ret, className, "textInputTraits", UITextInputTraits) IS_CONVERTER(ret, className, "tableViewController", UITableViewController) IS_CONVERTER(ret, className, "tableView", UITableView) IS_CONVERTER(ret, className, "tableViewCell", UITableViewCell) diff --git a/tools/vsimporter/xib2nib/src/UITextField.cpp b/tools/vsimporter/xib2nib/src/UITextField.cpp index 6d6a7d4264..1ac05b086b 100644 --- a/tools/vsimporter/xib2nib/src/UITextField.cpp +++ b/tools/vsimporter/xib2nib/src/UITextField.cpp @@ -17,6 +17,7 @@ #include "UITextField.h" #include "UIColor.h" #include "UIFont.h" +#include "UITextInputTraits.h" static void MakeMutable(struct _PropertyMapper* prop, NIBWriter* writer, XIBObject* propObj, XIBObject* obj) { propObj->_className = "NSMutableString"; @@ -52,8 +53,7 @@ UITextField::UITextField() { _placeholder = NULL; _borderStyle = 0; _font = NULL; - _autoCorrectionType = 0; - _returnKeyType = 0; + _textInputTraits = NULL; _clearsOnBeginEditing = false; _clearButtonOffset.width = 0.0f; _clearButtonOffset.height = 0.0f; @@ -72,12 +72,6 @@ void UITextField::InitFromXIB(XIBObject* obj) { _font = (UIFont*)obj->FindMember("IBUIFont"); } - XIBObject* inputTraits = obj->FindMember("IBUITextInputTraits"); - if (inputTraits) { - _autoCorrectionType = inputTraits->GetInt("IBUIAutocorrectionType", 0); - _returnKeyType = inputTraits->GetInt("IBUIReturnKeyType", 0); - } - _clearsOnBeginEditing = obj->GetBool("IBUIClearsOnBeginEditing", false); if (_clearsOnBeginEditing) { _clearButtonOffset.width = 3.0f; @@ -90,7 +84,7 @@ void UITextField::InitFromStory(XIBObject* obj) { UIControl::InitFromStory(obj); _font = (UIFont*)obj->FindMemberAndHandle("fontDescription"); - + _textInputTraits = (UITextInputTraits*)obj->FindMemberAndHandle("textInputTraits"); // This is default if borderStyle isn't present _borderStyle = 0; const char* borderStyle = obj->getAttrAndHandle("borderStyle"); @@ -140,12 +134,8 @@ void UITextField::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { obj->AddOutputMember(writer, "UITextColor", color->CreateObject(writer)); } - if (_autoCorrectionType) { - AddInt(writer, "UIAutocorrectionType", _autoCorrectionType); - } - - if (_returnKeyType) { - AddInt(writer, "UIReturnKeyType", _returnKeyType); + if (_textInputTraits) { + _textInputTraits->ConvertStaticMappings(writer, this); } if (_clearsOnBeginEditing) { diff --git a/tools/vsimporter/xib2nib/src/UITextField.h b/tools/vsimporter/xib2nib/src/UITextField.h index 81940fd986..3ce917f355 100644 --- a/tools/vsimporter/xib2nib/src/UITextField.h +++ b/tools/vsimporter/xib2nib/src/UITextField.h @@ -18,6 +18,7 @@ #include "UIControl.h" class UIFont; +class UITextInputTraits; class UITextField : public UIControl { private: @@ -27,8 +28,7 @@ class UITextField : public UIControl { int _borderStyle; XIBObject* _textColor; UIFont* _font; - int _autoCorrectionType; - int _returnKeyType; + UITextInputTraits* _textInputTraits; bool _clearsOnBeginEditing; CGSize _clearButtonOffset; diff --git a/tools/vsimporter/xib2nib/src/UITextInputTraits.cpp b/tools/vsimporter/xib2nib/src/UITextInputTraits.cpp new file mode 100644 index 0000000000..2bd8caca8d --- /dev/null +++ b/tools/vsimporter/xib2nib/src/UITextInputTraits.cpp @@ -0,0 +1,192 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#include "UITextInputTraits.h" +#include +#include + +static std::map storyToReturnType = { + { "go", UIReturnKeyTypeGo }, + { "google", UIReturnKeyTypeGoogle }, + { "join", UIReturnKeyTypeJoin }, + { "next", UIReturnKeyTypeNext }, + { "route", UIReturnKeyTypeRoute }, + { "search", UIReturnKeyTypeSearch }, + { "send", UIReturnKeyTypeSend }, + { "yahoo", UIReturnKeyTypeYahoo }, + { "done", UIReturnKeyTypeDone }, + { "emergencyCall", UIReturnKeyTypeEmergencyCall }, + { "continue", UIReturnKeyTypeContinue } +}; + +static std::map storyToAutocapitalizationType = { + { "words", UIAutocapitalizationTypeWords }, + { "sentences", UIAutocapitalizationTypeSentences }, + { "allCharacters", UIAutocapitalizationTypeAllCharacters } +}; + +typedef enum { + GenericBooleanOptionDefault = 0, + GenericBooleanOptionNo = 1, + GenericBooleanOptionYes = 2 +} GenericBooleanOption; + +static std::map storyToGenericBooleanOption = { + { "no", GenericBooleanOptionNo }, + { "yes", GenericBooleanOptionYes }, + // just in case also capitalized + { "NO", GenericBooleanOptionNo }, + { "YES", GenericBooleanOptionYes }, +}; + +static std::map storyToKeyboardAppearance = { + { "alert", UIKeyboardAppearanceAlert }, + { "light", UIKeyboardAppearanceLight } +}; + +static std::map storyToKeyboardType = { + { "alphabet", UIKeyboardTypeAlphabet }, + { "numbersAndPunctuation", UIKeyboardTypeNumbersAndPunctuation }, + { "URL", UIKeyboardTypeURL }, + { "numberPad", UIKeyboardTypeNumberPad }, + { "phonePad", UIKeyboardTypePhonePad }, + { "namePhonePad", UIKeyboardTypeNamePhonePad }, + { "emailAddress", UIKeyboardTypeEmailAddress }, + { "decimalPad", UIKeyboardTypeDecimalPad }, + { "twitter", UIKeyboardTypeTwitter }, + { "webSearch", UIKeyboardTypeWebSearch }, + { "ASCIICapableNumberPad", UIKeyboardTypeASCIICapableNumberPad } +}; + + +UITextInputTraits::UITextInputTraits() { + _returnKeyType = UIReturnKeyTypeDefault; + _textContentType = NULL; + _autocapitalizationType = UIAutocapitalizationTypeNone; + _autocorrectionType = GenericBooleanOptionDefault; + _smartDashesType = GenericBooleanOptionDefault; + _smartInsertDeleteType = GenericBooleanOptionDefault; + _smartQuotesType = GenericBooleanOptionDefault; + _spellCheckingType = GenericBooleanOptionDefault; + _keyboardType = UIKeyboardTypeDefault; + _keyboardAppearance = UIKeyboardAppearanceDefault; + _secureTextEntry = false; +} + +void UITextInputTraits::InitFromXIB(XIBObject* obj) { + // Outdated code do nothing +} + +void UITextInputTraits::InitFromStory(XIBObject* obj) { + const char *attr; + if ((attr = obj->getAttrAndHandle("returnKeyType"))) { + if (storyToReturnType.find(attr) != storyToReturnType.end()) { + _returnKeyType = storyToReturnType[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("autocapitalizationType"))) { + if (storyToAutocapitalizationType.find(attr) != storyToAutocapitalizationType.end()) { + _autocapitalizationType = storyToAutocapitalizationType[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("autocorrectionType"))) { + if (storyToGenericBooleanOption.find(attr) != storyToGenericBooleanOption.end()) { + _autocorrectionType = storyToGenericBooleanOption[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("smartDashesType"))) { + if (storyToGenericBooleanOption.find(attr) != storyToGenericBooleanOption.end()) { + _smartDashesType = storyToGenericBooleanOption[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("smartInsertDeleteType"))) { + if (storyToGenericBooleanOption.find(attr) != storyToGenericBooleanOption.end()) { + _smartInsertDeleteType = storyToGenericBooleanOption[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("smartQuotesType"))) { + if (storyToGenericBooleanOption.find(attr) != storyToGenericBooleanOption.end()) { + _smartQuotesType = storyToGenericBooleanOption[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("spellCheckingType"))) { + if (storyToGenericBooleanOption.find(attr) != storyToGenericBooleanOption.end()) { + _spellCheckingType = storyToGenericBooleanOption[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("keyboardType"))) { + if (storyToKeyboardType.find(attr) != storyToKeyboardType.end()) { + _keyboardType = storyToKeyboardType[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("keyboardAppearance"))) { + if (storyToKeyboardAppearance.find(attr) != storyToKeyboardAppearance.end()) { + _keyboardAppearance = storyToKeyboardAppearance[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("secureTextEntry"))) { + if (strcmp(attr, "YES") == 0) { + _secureTextEntry = true; + } + } + + _textContentType = obj->getAttrAndHandle("textContentType"); +} + +void UITextInputTraits::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { + if (_returnKeyType != UIReturnKeyTypeDefault) + obj->AddInt(writer, "UIReturnKeyType", _returnKeyType); + + if (_autocapitalizationType != UIAutocapitalizationTypeNone) + obj->AddInt(writer, "UIAutocapitalizationType", _autocapitalizationType); + + if (_autocorrectionType != GenericBooleanOptionDefault) + obj->AddInt(writer, "UIAutocorrectionType", _autocorrectionType); + + if (_smartDashesType != GenericBooleanOptionDefault) + obj->AddInt(writer, "UITextSmartDashesType", _smartDashesType); + + if (_smartInsertDeleteType != GenericBooleanOptionDefault) + obj->AddInt(writer, "UITextSmartInsertDeleteType", _smartInsertDeleteType); + + if (_smartQuotesType != GenericBooleanOptionDefault) + obj->AddInt(writer, "UITextSmartQuotesType", _smartQuotesType); + + // TODO: seems as spellCheckingType is not get out for iOS nib + // if (_spellCheckingType != GenericBooleanOptionDefault) + // obj->AddInt(writer, "UI????Type", _spellCheckingType); + + if (_keyboardType != UIKeyboardTypeDefault) + obj->AddInt(writer, "UIKeyboardType", _keyboardType); + + if (_keyboardAppearance != UIKeyboardAppearanceDefault) + obj->AddInt(writer, "UIKeyboardAppearance", _keyboardAppearance); + + if (_secureTextEntry) + obj->AddBool(writer, "UISecureTextEntry", _secureTextEntry); + + if (_textContentType) + obj->AddString(writer, "UITextContentType", _textContentType); +} diff --git a/tools/vsimporter/xib2nib/src/UITextInputTraits.h b/tools/vsimporter/xib2nib/src/UITextInputTraits.h new file mode 100644 index 0000000000..9060aa1d92 --- /dev/null +++ b/tools/vsimporter/xib2nib/src/UITextInputTraits.h @@ -0,0 +1,81 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#pragma once +#include "ObjectConverter.h" + +typedef enum { + UIReturnKeyTypeDefault = 0, + UIReturnKeyTypeGo, + UIReturnKeyTypeGoogle, + UIReturnKeyTypeJoin, + UIReturnKeyTypeNext, + UIReturnKeyTypeRoute, + UIReturnKeyTypeSearch, + UIReturnKeyTypeSend, + UIReturnKeyTypeYahoo, + UIReturnKeyTypeDone, + UIReturnKeyTypeEmergencyCall, + UIReturnKeyTypeContinue +} UIReturnKeyType; + +typedef enum { + UIAutocapitalizationTypeNone = 0, + UIAutocapitalizationTypeWords, + UIAutocapitalizationTypeSentences, + UIAutocapitalizationTypeAllCharacters, +} UIAutocapitalizationType; + +typedef enum { + UIKeyboardTypeDefault = 0, + UIKeyboardTypeAlphabet, + UIKeyboardTypeNumbersAndPunctuation, + UIKeyboardTypeURL, + UIKeyboardTypeNumberPad, + UIKeyboardTypePhonePad, + UIKeyboardTypeNamePhonePad, + UIKeyboardTypeEmailAddress, + UIKeyboardTypeDecimalPad, + UIKeyboardTypeTwitter, + UIKeyboardTypeWebSearch, + UIKeyboardTypeASCIICapableNumberPad +} UIKeyboardType; + +typedef enum { + UIKeyboardAppearanceDefault = 0, + UIKeyboardAppearanceAlert, + UIKeyboardAppearanceLight +} UIKeyboardAppearance; + +class UITextInputTraits : public ObjectConverter { +public: + int _returnKeyType; + const char *_textContentType; + int _autocapitalizationType; + int _autocorrectionType; + int _smartDashesType; + int _smartInsertDeleteType; + int _smartQuotesType; + int _spellCheckingType; + int _keyboardType; + int _keyboardAppearance; + bool _secureTextEntry; + + UITextInputTraits(); + virtual void InitFromXIB(XIBObject* obj); + virtual void InitFromStory(XIBObject* obj); + virtual void ConvertStaticMappings(NIBWriter* writer, XIBObject* obj); +}; From e66e96ab9e2d154887fd0a9778b2be6cc2a5890d Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Thu, 8 Feb 2018 16:19:58 +0200 Subject: [PATCH 26/34] optimized structures (UIRect etc), UIEdgeInsets moved to common location --- tools/vsimporter/xib2nib/src/UIButton.cpp | 18 ++------ tools/vsimporter/xib2nib/src/UIButton.h | 19 ++------ .../xib2nib/src/UINibKeyValuePair.cpp | 4 +- tools/vsimporter/xib2nib/src/XIBObject.cpp | 19 ++++++++ tools/vsimporter/xib2nib/src/XIBObject.h | 44 +++++++++++++++++-- 5 files changed, 69 insertions(+), 35 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/UIButton.cpp b/tools/vsimporter/xib2nib/src/UIButton.cpp index 56ca820669..15e32bc5ab 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.cpp +++ b/tools/vsimporter/xib2nib/src/UIButton.cpp @@ -24,7 +24,7 @@ #include void ConvertInsets(struct _PropertyMapper* prop, NIBWriter* writer, XIBObject* propObj, XIBObject* obj) { - EdgeInsets edgeInsets; + UIEdgeInsets edgeInsets; char szName[255]; sprintf(szName, "IBUI%sEdgeInsets.top", prop->nibName); @@ -217,16 +217,6 @@ void UIButton::InitFromXIB(XIBObject* obj) { obj->_outputClassName = "UIButton"; } -void PopulateInsetsFromStoryboard(XIBObject* obj, const char* insetType, EdgeInsets& insets) { - XIBObject* insetNode = obj->FindMemberAndHandle(const_cast(insetType)); - if (insetNode) { - insets.top = strtof(insetNode->getAttrAndHandle("minY"), NULL); - insets.left = strtof(insetNode->getAttrAndHandle("minX"), NULL); - insets.bottom = strtof(insetNode->getAttrAndHandle("maxY"), NULL); - insets.right = strtof(insetNode->getAttrAndHandle("maxX"), NULL); - } -} - void UIButton::InitFromStory(XIBObject* obj) { UIControl::InitFromStory(obj); @@ -267,9 +257,9 @@ void UIButton::InitFromStory(XIBObject* obj) { } // Insets - PopulateInsetsFromStoryboard(obj, "imageEdgeInsets", _imageEdgeInsets); - PopulateInsetsFromStoryboard(obj, "contentEdgeInsets", _contentEdgeInsets); - PopulateInsetsFromStoryboard(obj, "titleEdgeInsets", _titleEdgeInsets); + PopulateInsetsFromStoryboard("imageEdgeInsets", _imageEdgeInsets); + PopulateInsetsFromStoryboard("contentEdgeInsets", _contentEdgeInsets); + PopulateInsetsFromStoryboard("titleEdgeInsets", _titleEdgeInsets); obj->_outputClassName = "UIButton"; } diff --git a/tools/vsimporter/xib2nib/src/UIButton.h b/tools/vsimporter/xib2nib/src/UIButton.h index ad541335c1..03f9ab3e47 100644 --- a/tools/vsimporter/xib2nib/src/UIButton.h +++ b/tools/vsimporter/xib2nib/src/UIButton.h @@ -18,19 +18,6 @@ #include "UIControl.h" #include -struct EdgeInsets { - double top; - double left; - double bottom; - double right; - - EdgeInsets() : top(INFINITY), left(INFINITY), bottom(INFINITY), right(INFINITY) { - } - - bool IsValid() { - return top != INFINITY && left != INFINITY && bottom != INFINITY && right != INFINITY; - } -}; class UIFont; class UIButton : public UIControl { @@ -41,9 +28,9 @@ class UIButton : public UIControl { XIBObject* _statefulContent; bool _adjustsImageWhenHighlighted; bool _adjustsImageWhenDisabled; - EdgeInsets _imageEdgeInsets; - EdgeInsets _contentEdgeInsets; - EdgeInsets _titleEdgeInsets; + UIEdgeInsets _imageEdgeInsets; + UIEdgeInsets _contentEdgeInsets; + UIEdgeInsets _titleEdgeInsets; int _lineBreakMode; UIButton(); diff --git a/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp b/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp index 7ab1491997..947833ed8c 100644 --- a/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp +++ b/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp @@ -70,7 +70,7 @@ void UINibKeyValuePair::InitFromStory(XIBObject* obj) { } else if (strcmp(type , "size") == 0) { XIBObject *obj= FindMemberAndHandle("value"); if (obj) { - CGSize size = {0}; + CGSize size; size.width = static_cast(strtod(obj->getAttrAndHandle("width"), NULL)); size.height = static_cast(strtod(obj->getAttrAndHandle("height"), NULL)); _value = new XIBObjectValue(size); @@ -78,7 +78,7 @@ void UINibKeyValuePair::InitFromStory(XIBObject* obj) { } else if (strcmp(type , "rect") == 0) { XIBObject *obj= FindMemberAndHandle("value"); if (obj) { - UIRect rect = {0}; + UIRect rect; rect.x = static_cast(strtod(obj->getAttrAndHandle("x"), NULL)); rect.y = static_cast(strtod(obj->getAttrAndHandle("y"), NULL)); rect.width = static_cast(strtod(obj->getAttrAndHandle("width"), NULL)); diff --git a/tools/vsimporter/xib2nib/src/XIBObject.cpp b/tools/vsimporter/xib2nib/src/XIBObject.cpp index 34b7460287..df9625e239 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.cpp +++ b/tools/vsimporter/xib2nib/src/XIBObject.cpp @@ -486,6 +486,25 @@ bool XIBObject::GetBool(char* pPropName, bool defaultValue) { return defaultValue; } + +void XIBObject::PopulateInsetsFromStoryboard(const char* insetType, UIEdgeInsets& insets) { + XIBObject* insetNode = FindMemberAndHandle(const_cast(insetType)); + if (insetNode) { + insets.top = strtof(insetNode->getAttrAndHandle("minY"), NULL); + insets.left = strtof(insetNode->getAttrAndHandle("minX"), NULL); + insets.bottom = strtof(insetNode->getAttrAndHandle("maxY"), NULL); + insets.right = strtof(insetNode->getAttrAndHandle("maxX"), NULL); + } +} + +void XIBObject::PopulateSizeFromStoryboard(const char* sizeType, CGSize& size) { + XIBObject* sizeNode = FindMemberAndHandle(const_cast(sizeType)); + if (sizeNode) { + size.width = strtof(sizeNode->getAttrAndHandle("width"), NULL); + size.height = strtof(sizeNode->getAttrAndHandle("height"), NULL); + } +} + void XIBObject::AddSize(NIBWriter* writer, char* pPropName, CGSize size) { AddData(writer, pPropName, size); } diff --git a/tools/vsimporter/xib2nib/src/XIBObject.h b/tools/vsimporter/xib2nib/src/XIBObject.h index 91fc52c8db..74197a1edf 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.h +++ b/tools/vsimporter/xib2nib/src/XIBObject.h @@ -46,18 +46,53 @@ class XIBArray; #include "NIBWriter.h" -typedef struct { - double width, height; } CGSize; +typedef struct CGSize{ + double width, height; + + CGSize() : width(INFINITY), height(INFINITY) { + } + + CGSize(double width, double height) : width(width), height(height) { + } -typedef struct { + bool IsValid() { + return width != INFINITY && height != INFINITY; + } +} CGSize; + +typedef struct UIRect { double x, y; double width, height; + + UIRect() : x(INFINITY), y(INFINITY), width(INFINITY), height(INFINITY) { + } + + UIRect(double x, double y, double width, double height) : x(x), y(y), width(width), height(height) { + } + + bool IsValid() { + return x != INFINITY && y != INFINITY && width != INFINITY && height != INFINITY; + } } UIRect; typedef struct { double x, y; } UIPoint; typedef struct { long long location, length; } NSRange; +typedef struct UIEdgeInsets { + double top; + double left; + double bottom; + double right; + + UIEdgeInsets() : top(INFINITY), left(INFINITY), bottom(INFINITY), right(INFINITY) { + } + + bool IsValid() { + return top != INFINITY && left != INFINITY && bottom != INFINITY && right != INFINITY; + } +} UIEdgeInsets; + const char* getNodeAttrib(pugi::xml_node node, const char* name); class XIBObject { @@ -126,6 +161,9 @@ class XIBObject { const char* GetString(char* pPropName, char* defaultValue); int GetInt(char* pPropName, int defaultValue); bool GetBool(char* pPropName, bool defaultValue); + + void PopulateInsetsFromStoryboard(const char* insetType, UIEdgeInsets& insets); + void PopulateSizeFromStoryboard(const char* sizeType, CGSize& size); template void AddData(NIBWriter* writer, char* pPropName, const TData& data) { From 075905b440023d384f04c3ffcf2202bcc66c80e5 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Thu, 8 Feb 2018 16:20:40 +0200 Subject: [PATCH 27/34] UITableView: rowHeight is now being read out --- tools/vsimporter/xib2nib/src/UITableView.cpp | 9 +++++++++ tools/vsimporter/xib2nib/src/UITableView.h | 1 + 2 files changed, 10 insertions(+) diff --git a/tools/vsimporter/xib2nib/src/UITableView.cpp b/tools/vsimporter/xib2nib/src/UITableView.cpp index 87e6fe25e7..3a01805f13 100644 --- a/tools/vsimporter/xib2nib/src/UITableView.cpp +++ b/tools/vsimporter/xib2nib/src/UITableView.cpp @@ -43,6 +43,7 @@ UITableView::UITableView() { _allowsSelectionDuringEditing = false; _separatorStyle = 0; _style = 0; + _rowHeight = -1; } void UITableView::InitFromXIB(XIBObject* obj) { @@ -71,6 +72,12 @@ void UITableView::InitFromStory(XIBObject* obj) { if (_footerView) { _subviews->AddMember(NULL, _footerView); } + + const char *attr; + if ((attr = obj->getAttrAndHandle("rowHeight"))) { + _rowHeight = strtof(attr, NULL); + } + obj->_outputClassName = "UITableView"; } @@ -92,4 +99,6 @@ void UITableView::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { AddOutputMember(writer, "UITableHeaderView", _headerView); if (_footerView) AddOutputMember(writer, "UITableFooterView", _footerView); + if (_rowHeight >= 0) + AddOutputMember(writer, "UIRowHeight", new XIBObjectFloat(_rowHeight)); } diff --git a/tools/vsimporter/xib2nib/src/UITableView.h b/tools/vsimporter/xib2nib/src/UITableView.h index aaee6666b7..7f4c7b7d2f 100644 --- a/tools/vsimporter/xib2nib/src/UITableView.h +++ b/tools/vsimporter/xib2nib/src/UITableView.h @@ -22,6 +22,7 @@ class UITableView : public UIScrollView { bool _allowsSelectionDuringEditing; int _style; int _separatorStyle; + float _rowHeight; UITableView(); virtual void Awaken(); virtual void InitFromXIB(XIBObject* obj); From 09691b7d75ace79dc4308796de56d3fbd50baf80 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Thu, 8 Feb 2018 16:21:31 +0200 Subject: [PATCH 28/34] added UICollectionViewFlowLayout which is required for UICollectionView even basic operations --- .../xib2nib/src/ObjectConverter.cpp | 2 + .../xib2nib/src/UICollectionView.cpp | 13 +- .../vsimporter/xib2nib/src/UICollectionView.h | 9 +- .../src/UICollectionViewFlowLayout.cpp | 127 ++++++++++++++++++ .../xib2nib/src/UICollectionViewFlowLayout.h | 40 ++++++ 5 files changed, 186 insertions(+), 5 deletions(-) create mode 100644 tools/vsimporter/xib2nib/src/UICollectionViewFlowLayout.cpp create mode 100644 tools/vsimporter/xib2nib/src/UICollectionViewFlowLayout.h diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp index 5684119921..a0598c52b0 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp @@ -60,6 +60,7 @@ #include "NSLayoutConstraint.h" #include "UICollectionViewCell.h" #include "UICollectionView.h" +#include "UICollectionViewFlowLayout.h" #include "UICollectionViewController.h" #include "UIStepper.h" #include "_UILayoutGuide.h" @@ -196,6 +197,7 @@ XIBObject* ObjectConverter::ConverterForStoryObject(const char* className, pugi: IS_CONVERTER(ret, className, "collectionReusableView", UICollectionReusableView) IS_CONVERTER(ret, className, "collectionViewCell", UICollectionViewCell) IS_CONVERTER(ret, className, "collectionView", UICollectionView) + IS_CONVERTER(ret, className, "collectionViewFlowLayout", UICollectionViewFlowLayout) IS_CONVERTER(ret, className, "collectionViewController", UICollectionViewController) IS_CONVERTER(ret, className, "pickerView", UIPickerView) IS_CONVERTER(ret, className, "segmentedControl", UISegmentedControl) diff --git a/tools/vsimporter/xib2nib/src/UICollectionView.cpp b/tools/vsimporter/xib2nib/src/UICollectionView.cpp index 9d760906ec..df9f599576 100644 --- a/tools/vsimporter/xib2nib/src/UICollectionView.cpp +++ b/tools/vsimporter/xib2nib/src/UICollectionView.cpp @@ -15,25 +15,32 @@ //****************************************************************************** #include "UICollectionView.h" +#include "UICollectionViewFlowLayout.h" UICollectionView::UICollectionView() { + _collectionViewLayout = NULL; } void UICollectionView::InitFromXIB(XIBObject* obj) { - UIView::InitFromXIB(obj); + UIScrollView::InitFromXIB(obj); obj->_outputClassName = "UICollectionView"; } void UICollectionView::InitFromStory(XIBObject* obj) { - UIView::InitFromStory(obj); + UIScrollView::InitFromStory(obj); + _collectionViewLayout = (UICollectionViewFlowLayout*)obj->FindMember("collectionViewLayout"); obj->_outputClassName = "UICollectionView"; } void UICollectionView::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { writer->_allUIObjects->AddMember(NULL, this); - UIView::ConvertStaticMappings(writer, obj); + + if (_collectionViewLayout) + AddOutputMember(writer , "UICollectionLayout", _collectionViewLayout); + + UIScrollView::ConvertStaticMappings(writer, obj); } ObjectConverter* UICollectionView::Clone() { diff --git a/tools/vsimporter/xib2nib/src/UICollectionView.h b/tools/vsimporter/xib2nib/src/UICollectionView.h index 2f10a0e2c2..6bf09b0b91 100644 --- a/tools/vsimporter/xib2nib/src/UICollectionView.h +++ b/tools/vsimporter/xib2nib/src/UICollectionView.h @@ -1,8 +1,13 @@ #pragma once -#include "UIView.h" -class UICollectionView : public UIView { +#include "UIScrollView.h" + +class UICollectionViewFlowLayout; + +class UICollectionView : public UIScrollView { private: public: + UICollectionViewFlowLayout *_collectionViewLayout; + UICollectionView(); virtual void InitFromXIB(XIBObject* obj); virtual void InitFromStory(XIBObject* obj); diff --git a/tools/vsimporter/xib2nib/src/UICollectionViewFlowLayout.cpp b/tools/vsimporter/xib2nib/src/UICollectionViewFlowLayout.cpp new file mode 100644 index 0000000000..9afb1d61ab --- /dev/null +++ b/tools/vsimporter/xib2nib/src/UICollectionViewFlowLayout.cpp @@ -0,0 +1,127 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#include "UICollectionViewFlowLayout.h" +#include + +typedef enum { + UISectionInsetReferenceContent = 0, + UISectionInsetReferenceSafeArea, + UISectionInsetReferenceLayoutMargins +} UISectionInsetReference; + +static std::map storyToInsetReference = { + { "safeArea", UISectionInsetReferenceSafeArea }, + { "layoutMargins", UISectionInsetReferenceLayoutMargins } +}; + +typedef enum { + UIScrollDirectionVertical = 0, + UIScrollDirectionHorizontal, +} UIScrollDirection; + +static std::map storyToScrollDirrection = { + { "vertical", UIScrollDirectionVertical }, + { "horizontal", UIScrollDirectionHorizontal } +}; + + +UICollectionViewFlowLayout::UICollectionViewFlowLayout() { + _scrollDirection = UIScrollDirectionVertical; + _minimumLineSpacing = -1; + _minimumInteritemSpacing = -1; + _customClass = NULL; + _customModule = NULL; + _sectionInsetReference = UISectionInsetReferenceContent; +} + +void UICollectionViewFlowLayout::InitFromXIB(XIBObject* obj) { + // Outdated code do nothing +} + +void UICollectionViewFlowLayout::InitFromStory(XIBObject* obj) { + obj->PopulateSizeFromStoryboard("itemSize", _itemSize); + obj->PopulateSizeFromStoryboard("headerReferenceSize", _headerReferenceSize); + obj->PopulateSizeFromStoryboard("footerReferenceSize", _footerReferenceSize); + obj->PopulateInsetsFromStoryboard("sectionInset", _sectionInset); + + _customClass = obj->getAttrAndHandle("customClass"); + if (_customClass) { + const char* module = obj->getAttrAndHandle("customModule");; + if (module) { + // its swift, mange class name with module + char buf[128]; // should be big enough + snprintf(buf, 128, "_TtC%zu%s%zu%s", strlen(module), module, strlen(_customClass), _customClass); + _customClass = strdup(buf); + } + } + + const char* attr; + if ((attr = obj->getAttrAndHandle("minimumLineSpacing"))) { + _minimumLineSpacing = strtof(attr, NULL); + } + + if ((attr = obj->getAttrAndHandle("minimumInteritemSpacing"))) { + _minimumInteritemSpacing = strtof(attr, NULL); + } + + if ((attr = obj->getAttrAndHandle("sectionInsetReference"))) { + if (storyToInsetReference.find(attr) != storyToInsetReference.end()) { + _sectionInsetReference = storyToInsetReference[attr]; + } + } + + if ((attr = obj->getAttrAndHandle("scrollDirection"))) { + if (storyToScrollDirrection.find(attr) != storyToScrollDirrection.end()) { + _scrollDirection = storyToScrollDirrection[attr]; + } + } +} + +void UICollectionViewFlowLayout::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { + _outputClassName = "UICollectionViewFlowLayout"; + + if (_itemSize.IsValid()) + obj->AddData(writer, "UIItemSize", _itemSize); + + if (_headerReferenceSize.IsValid()) + obj->AddData(writer, "UIHeaderReferenceSize", _headerReferenceSize); + + if (_footerReferenceSize.IsValid()) + obj->AddData(writer, "UIFooterReferenceSize", _footerReferenceSize); + + if (_sectionInset.IsValid()) + obj->AddData(writer, "UISectionInset", _sectionInset); + + if (_customClass) { + obj->AddString(writer, "UIClassName", _customClass); + obj->AddString(writer, "UIOriginalClassName", "UICollectionViewLayout"); + } + + if (_minimumLineSpacing >= 0) + AddOutputMember(writer, "UILineSpacing", new XIBObjectFloat(_minimumLineSpacing)); + + if (_minimumInteritemSpacing >= 0) + AddOutputMember(writer, "UIInteritemSpacing", new XIBObjectFloat(_minimumInteritemSpacing)); + + if (_scrollDirection != UIScrollDirectionVertical) + AddInt(writer, "UIScrollDirection", _scrollDirection); + + if (_sectionInsetReference != UISectionInsetReferenceContent) + AddInt(writer, "UISectionInsetReference", _sectionInsetReference); + + ObjectConverter::ConvertStaticMappings(writer, obj); +} diff --git a/tools/vsimporter/xib2nib/src/UICollectionViewFlowLayout.h b/tools/vsimporter/xib2nib/src/UICollectionViewFlowLayout.h new file mode 100644 index 0000000000..c0857c8f05 --- /dev/null +++ b/tools/vsimporter/xib2nib/src/UICollectionViewFlowLayout.h @@ -0,0 +1,40 @@ +//****************************************************************************** +// +// Copyright (c) 2015 Microsoft Corporation. All rights reserved. +// +// This code is licensed under the MIT License (MIT). +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. +// +//****************************************************************************** + +#pragma once +#include "ObjectConverter.h" + + +class UICollectionViewFlowLayout : public ObjectConverter { +public: + int _scrollDirection; + float _minimumLineSpacing; + float _minimumInteritemSpacing; + + const char *_customClass; + const char *_customModule; + + int _sectionInsetReference; + CGSize _itemSize; + CGSize _headerReferenceSize; + CGSize _footerReferenceSize; + UIEdgeInsets _sectionInset; + + UICollectionViewFlowLayout(); + virtual void InitFromXIB(XIBObject* obj); + virtual void InitFromStory(XIBObject* obj); + virtual void ConvertStaticMappings(NIBWriter* writer, XIBObject* obj); +}; From 5c1cf8b173fe7447ec53f41dac0fda92745ef464 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Fri, 9 Feb 2018 12:19:04 +0200 Subject: [PATCH 29/34] UIPoint is updated with isValid method, also UIView changed to process only valid rects which removes dummy frame(0,0,0,0) outputs --- .../xib2nib/src/UINibKeyValuePair.cpp | 2 +- tools/vsimporter/xib2nib/src/UIView.cpp | 26 +++++++------------ tools/vsimporter/xib2nib/src/XIBObject.cpp | 10 +++++++ tools/vsimporter/xib2nib/src/XIBObject.h | 15 ++++++++++- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp b/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp index 947833ed8c..e3c21007ad 100644 --- a/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp +++ b/tools/vsimporter/xib2nib/src/UINibKeyValuePair.cpp @@ -62,7 +62,7 @@ void UINibKeyValuePair::InitFromStory(XIBObject* obj) { } else if (strcmp(type , "point") == 0) { XIBObject *obj= FindMemberAndHandle("value"); if (obj) { - UIPoint pt = {0}; + UIPoint pt; pt.x = static_cast(strtod(obj->getAttrAndHandle("x"), NULL)); pt.y = static_cast(strtod(obj->getAttrAndHandle("y"), NULL)); _value = new XIBObjectValue(pt); diff --git a/tools/vsimporter/xib2nib/src/UIView.cpp b/tools/vsimporter/xib2nib/src/UIView.cpp index 0f9997bfcf..46552093c9 100644 --- a/tools/vsimporter/xib2nib/src/UIView.cpp +++ b/tools/vsimporter/xib2nib/src/UIView.cpp @@ -45,9 +45,6 @@ enum { }; UIView::UIView() { - memset(&_bounds, 0, sizeof(_bounds)); - memset(&_center, 0, sizeof(_center)); - memset(&_contentStretch, 0, sizeof(_contentStretch)); _subviews = new XIBArray(); _constraints = new XIBArray(); _layoutGuides = new XIBArray(); @@ -228,19 +225,14 @@ void UIView::InitFromStory(XIBObject* obj) { _hidden = true; } } - XIBObject* frameRect = FindMemberAndHandle("frame"); - if (frameRect) { + PopulateRectFromStoryboard("frame", _bounds); + if (_bounds.IsValid()) { + _center.x = _bounds.x + _bounds.width / 2.0f; + _center.y = _bounds.y + _bounds.height / 2.0f; + _bounds.x = 0; _bounds.y = 0; - _bounds.width = static_cast(strtod(frameRect->getAttrAndHandle("width"), NULL)); - _bounds.height = static_cast(strtod(frameRect->getAttrAndHandle("height"), NULL)); - - _center.x = static_cast(strtod(frameRect->getAttrAndHandle("x"), NULL)); - _center.y = static_cast(strtod(frameRect->getAttrAndHandle("y"), NULL)); - - _center.x += _bounds.width / 2.0f; - _center.y += _bounds.height / 2.0f; } XIBObject* resizeMask = FindMemberAndHandle("autoresizingMask"); @@ -311,9 +303,11 @@ void UIView::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { } } - AddRect(writer, "UIBounds", _bounds); - AddPoint(writer, "UICenter", _center); - if (_contentStretch.x != 0.0f || _contentStretch.y != 0.0f || _contentStretch.width != 0.0f || _contentStretch.height != 0.0f) { + if (_bounds.IsValid()) + AddRect(writer, "UIBounds", _bounds); + if (_center.IsValid()) + AddPoint(writer, "UICenter", _center); + if (_contentStretch.IsValid()) { AddRect(writer, "UIContentStretch", _contentStretch); } diff --git a/tools/vsimporter/xib2nib/src/XIBObject.cpp b/tools/vsimporter/xib2nib/src/XIBObject.cpp index df9625e239..1932554f9f 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.cpp +++ b/tools/vsimporter/xib2nib/src/XIBObject.cpp @@ -497,6 +497,16 @@ void XIBObject::PopulateInsetsFromStoryboard(const char* insetType, UIEdgeInsets } } +void XIBObject::PopulateRectFromStoryboard(const char* rectType, UIRect& rect) { + XIBObject* rectNode = FindMemberAndHandle(const_cast(rectType)); + if (rectNode) { + rect.x = strtof(rectNode->getAttrAndHandle("x"), NULL); + rect.y = strtof(rectNode->getAttrAndHandle("y"), NULL); + rect.width = strtof(rectNode->getAttrAndHandle("width"), NULL); + rect.height = strtof(rectNode->getAttrAndHandle("height"), NULL); + } +} + void XIBObject::PopulateSizeFromStoryboard(const char* sizeType, CGSize& size) { XIBObject* sizeNode = FindMemberAndHandle(const_cast(sizeType)); if (sizeNode) { diff --git a/tools/vsimporter/xib2nib/src/XIBObject.h b/tools/vsimporter/xib2nib/src/XIBObject.h index 74197a1edf..49dd4c0a52 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.h +++ b/tools/vsimporter/xib2nib/src/XIBObject.h @@ -75,7 +75,19 @@ typedef struct UIRect { } } UIRect; -typedef struct { double x, y; } UIPoint; +typedef struct UIPoint{ + double x, y; + + UIPoint() : x(INFINITY), y(INFINITY) { + } + + UIPoint(double x, double y) : x(x), y(y) { + } + + bool IsValid() { + return x != INFINITY && y != INFINITY; + } +} UIPoint; typedef struct { long long location, length; } NSRange; @@ -163,6 +175,7 @@ class XIBObject { bool GetBool(char* pPropName, bool defaultValue); void PopulateInsetsFromStoryboard(const char* insetType, UIEdgeInsets& insets); + void PopulateRectFromStoryboard(const char* rectType, UIRect& rect); void PopulateSizeFromStoryboard(const char* sizeType, CGSize& size); template From fca4ea4f1ccbfd2906ea450914eb0b0df559949b Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Fri, 9 Feb 2018 12:52:02 +0200 Subject: [PATCH 30/34] UISegmentedControl fixed --- .../xib2nib/src/ObjectConverter.cpp | 3 + tools/vsimporter/xib2nib/src/UISegment.cpp | 46 ++++++++---- tools/vsimporter/xib2nib/src/UISegment.h | 13 ++-- .../xib2nib/src/UISegmentedControl.cpp | 72 +++++++++---------- .../xib2nib/src/UISegmentedControl.h | 6 +- 5 files changed, 80 insertions(+), 60 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp index a0598c52b0..3ba8ac5588 100644 --- a/tools/vsimporter/xib2nib/src/ObjectConverter.cpp +++ b/tools/vsimporter/xib2nib/src/ObjectConverter.cpp @@ -54,6 +54,7 @@ #include "UIPageControl.h" #include "UISwitch.h" #include "UISegmentedControl.h" +#include "UISegment.h" #include "UIDatePicker.h" #include "MKMapView.h" #include "UISlider.h" @@ -153,6 +154,7 @@ XIBObject* ObjectConverter::ConverterForStoryObject(const char* className, pugi: IS_CONVERTER(ret, className, "variation", XIBVariation) IS_CONVERTER(ret, className, "items", XIBArray) IS_CONVERTER(ret, className, "connections", XIBArray) + IS_CONVERTER(ret, className, "segments", XIBArray) IS_CONVERTER(ret, className, "string", XIBObjectString) IS_CONVERTER(ret, className, "viewController", UIViewController) IS_CONVERTER(ret, className, "splitViewController", UIViewController) @@ -201,6 +203,7 @@ XIBObject* ObjectConverter::ConverterForStoryObject(const char* className, pugi: IS_CONVERTER(ret, className, "collectionViewController", UICollectionViewController) IS_CONVERTER(ret, className, "pickerView", UIPickerView) IS_CONVERTER(ret, className, "segmentedControl", UISegmentedControl) + IS_CONVERTER(ret, className, "segment", UISegment); IS_CONVERTER(ret, className, "stepper", UIStepper) IS_CONVERTER(ret, className, "panGestureRecognizer", UIPanGestureRecognizer) IS_CONVERTER(ret, className, "swipeGestureRecognizer", UISwipeGestureRecognizer) diff --git a/tools/vsimporter/xib2nib/src/UISegment.cpp b/tools/vsimporter/xib2nib/src/UISegment.cpp index b5c64b9d0d..284a52374d 100644 --- a/tools/vsimporter/xib2nib/src/UISegment.cpp +++ b/tools/vsimporter/xib2nib/src/UISegment.cpp @@ -15,16 +15,15 @@ //****************************************************************************** #include "UISegment.h" -#include "UIColor.h" +#include "UICustomResource.h" +#include -UISegment::UISegment(XIBObject* info, int style, int position, UIColor* tintColor) { - _info = info; - _style = style; - _position = position; - _tintColor = tintColor; +UISegment::UISegment() { _outputClassName = "UISegment"; - _connectedObjects = nullptr; - _connections = nullptr; + _title = NULL; + _image = NULL; + _enabled = true; + _position = 0; } void UISegment::InitFromXIB(XIBObject* obj) { @@ -36,17 +35,36 @@ void UISegment::InitFromXIB(XIBObject* obj) { void UISegment::InitFromStory(XIBObject* obj) { UIView::InitFromStory(obj); + _title = obj->getAttrAndHandle("title"); + _image = obj->getAttrAndHandle("image"); + const char* attr; + if ((attr = obj->getAttrAndHandle("enabled"))) { + if (strcmp(attr, "NO") == 0) + _enabled = false; + } + + PopulateSizeFromStoryboard("contentOffset", _contentOffset); + obj->_outputClassName = "UISegment"; } void UISegment::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { UIView::ConvertStaticMappings(writer, obj); - if (_info) - AddOutputMember(writer, "UISegmentInfo", _info); - if (_style) - AddInt(writer, "UISegmentStyle", _style); + if (_image) { + // add placeholder + UICustomResource *placeholder = new UICustomResource(); + placeholder->_imageName = strdup(_image); + AddOutputMember(writer, "UISegmentInfo", placeholder); + } else if (_title) { + AddString(writer, "UISegmentInfo", _title); + } + + if (!_enabled) + AddBool(writer, "UIUserInteractionDisabled", _enabled); + if (_position) AddInt(writer, "UISegmentPosition", _position); - if (_tintColor) - AddOutputMember(writer, "UISegmentTintColor", _tintColor); + + if (_contentOffset.IsValid()) + AddSize(writer, "UISegmentContentOffset", _contentOffset); } diff --git a/tools/vsimporter/xib2nib/src/UISegment.h b/tools/vsimporter/xib2nib/src/UISegment.h index 42692e54f3..daeface32e 100644 --- a/tools/vsimporter/xib2nib/src/UISegment.h +++ b/tools/vsimporter/xib2nib/src/UISegment.h @@ -17,15 +17,18 @@ #pragma once #include "UIView.h" -class UIColor; class UISegment : public UIView { public: - XIBObject* _info; - int _style; + const char* _title; + const char* _image; + CGSize _contentOffset; + bool _enabled; + + // is not parsed but to be set externaly int _position; - UIColor* _tintColor; - UISegment(XIBObject* info, int style, int position, UIColor* tintColor); + + UISegment(); virtual void InitFromXIB(XIBObject* obj); virtual void InitFromStory(XIBObject* obj); virtual void ConvertStaticMappings(NIBWriter* writer, XIBObject* obj); diff --git a/tools/vsimporter/xib2nib/src/UISegmentedControl.cpp b/tools/vsimporter/xib2nib/src/UISegmentedControl.cpp index 79cd6e63ee..0bfc5b52a5 100644 --- a/tools/vsimporter/xib2nib/src/UISegmentedControl.cpp +++ b/tools/vsimporter/xib2nib/src/UISegmentedControl.cpp @@ -21,52 +21,46 @@ UISegmentedControl::UISegmentedControl() { _segments = NULL; _momentary = false; + _springLoaded = false; _tintColor = NULL; - _style = 0; - _selected = -1; + _segmentControlStyle = 0; + _selectedSegmentIndex = -1; } void UISegmentedControl::InitFromXIB(XIBObject* obj) { UIControl::InitFromXIB(obj); + // removed outdated code +} - _momentary = obj->GetBool("IBMomentary", false); - - XIBArray* titles = (XIBArray*)obj->FindMember("IBSegmentTitles"); - XIBArray* widths = (XIBArray*)obj->FindMember("IBSegmentWidths"); - XIBArray* enabled = (XIBArray*)obj->FindMember("IBSegmentEnabledStates"); - XIBArray* images = (XIBArray*)obj->FindMember("IBSegmentImages"); - _tintColor = (UIColor*)obj->FindMember("IBTintColor"); - _style = obj->GetInt("IBSegmentControlStyle", 0); - _selected = obj->GetInt("IBSelectedSegmentIndex", -1); - - if (enabled) { - _segments = new XIBArray(); - UIRect curFrame = getFrame(); - float curX = 0.0f; - float frameWidth = curFrame.width - 5.0f; - float segWidth = frameWidth / (float)enabled->count(); - - for (int i = 0; i < enabled->count(); i++) { - bool segEnabled = enabled->objectAtIndex(i)->intValue(); - - XIBObject* title = titles->objectAtIndex(i); - UISegment* newSeg = new UISegment(title, _style, i == 0 ? 0 : i == enabled->count() - 1 ? 2 : 1, _tintColor); - newSeg->_ignoreUIObject = true; - - UIRect segFrame = curFrame; - segFrame.x = (float)i * segWidth; - // segFrame.width = +void UISegmentedControl::InitFromStory(XIBObject* obj) { + UIControl::InitFromStory(obj); - _segments->AddMember(NULL, newSeg); - _subviews->AddMember(NULL, newSeg); + _tintColor = (UIColor*)FindMemberAndHandle("tintColor"); + _segments = (XIBArray*)obj->FindMemberClass("segments"); + if (_segments) { + // add them to subviews also set proper index + for (int idx = 0; idx < _segments->count(); idx++) { + UISegment *segment = (UISegment*)_segments->objectAtIndex(idx); + segment->_position = idx; + + _subviews->AddMember(NULL, segment); } } - obj->_outputClassName = "UISegmentedControl"; -} + const char* attr; + if ((attr = obj->getAttrAndHandle("momentary"))) { + if (strcmp(attr, "YES") == 0) + _momentary = true; + } -void UISegmentedControl::InitFromStory(XIBObject* obj) { - UIControl::InitFromStory(obj); + if ((attr = obj->getAttrAndHandle("springLoaded"))) { + if (strcmp(attr, "YES") == 0) + _springLoaded = true; + } + + if ((attr = obj->getAttrAndHandle("selectedSegmentIndex"))) { + _selectedSegmentIndex = std::stoi(attr, NULL); + } obj->_outputClassName = "UISegmentedControl"; } @@ -77,10 +71,10 @@ void UISegmentedControl::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj AddOutputMember(writer, "UISegments", _segments); if (_momentary) AddBool(writer, "UIMomentary", _momentary); - if (_style) - AddInt(writer, "UISegmentedControlStyle", _style); - if (_selected != -1) - AddInt(writer, "UISelectedSegmentIndex", _selected); + if (_springLoaded) + AddBool(writer, "UISpringLoaded", _springLoaded); if (_tintColor) AddOutputMember(writer, "UISegmentedControlTintColor", _tintColor); + if (_selectedSegmentIndex != -1) + AddInt(writer, "UISelectedSegmentIndex", _selectedSegmentIndex); } diff --git a/tools/vsimporter/xib2nib/src/UISegmentedControl.h b/tools/vsimporter/xib2nib/src/UISegmentedControl.h index b14137538c..560ad627b4 100644 --- a/tools/vsimporter/xib2nib/src/UISegmentedControl.h +++ b/tools/vsimporter/xib2nib/src/UISegmentedControl.h @@ -21,9 +21,11 @@ class UISegmentedControl : public UIControl { public: XIBArray* _segments; bool _momentary; + bool _springLoaded; + UIColor* _tintColor; - int _style; - int _selected; + int _segmentControlStyle; + int _selectedSegmentIndex; UISegmentedControl(); virtual void InitFromXIB(XIBObject* obj); From 533e2e3fcf24046ce635a21267c0113e127703d1 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Fri, 9 Feb 2018 13:05:19 +0200 Subject: [PATCH 31/34] Fixed UIView.contentStretch was not parsed from xib --- tools/vsimporter/xib2nib/src/UIView.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/vsimporter/xib2nib/src/UIView.cpp b/tools/vsimporter/xib2nib/src/UIView.cpp index 46552093c9..9b4f3426cd 100644 --- a/tools/vsimporter/xib2nib/src/UIView.cpp +++ b/tools/vsimporter/xib2nib/src/UIView.cpp @@ -227,6 +227,7 @@ void UIView::InitFromStory(XIBObject* obj) { } PopulateRectFromStoryboard("frame", _bounds); + PopulateRectFromStoryboard("contentStretch", _contentStretch); if (_bounds.IsValid()) { _center.x = _bounds.x + _bounds.width / 2.0f; _center.y = _bounds.y + _bounds.height / 2.0f; From d96c7ce61ad0986708dcb35b04f23eee328c5975 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Tue, 13 Feb 2018 10:36:12 +0200 Subject: [PATCH 32/34] UIControl fixed to parse enabled/selected/highlighted attributes UISwitch outputs enabled/selected/highlighted attributes --- tools/vsimporter/xib2nib/src/UIControl.cpp | 19 +++++++++++++++++++ tools/vsimporter/xib2nib/src/UIControl.h | 3 +++ tools/vsimporter/xib2nib/src/UISwitch.cpp | 11 +++++++++++ 3 files changed, 33 insertions(+) diff --git a/tools/vsimporter/xib2nib/src/UIControl.cpp b/tools/vsimporter/xib2nib/src/UIControl.cpp index 6606499112..212dc3b998 100644 --- a/tools/vsimporter/xib2nib/src/UIControl.cpp +++ b/tools/vsimporter/xib2nib/src/UIControl.cpp @@ -19,6 +19,9 @@ UIControl::UIControl() { _contentVerticalAlignment = UIControlContentVerticalAlignmentTop; _contentHorizontalAlignment = UIControlContentHorizontalAlignmentLeft; + _enabled = true; + _selected = false; + _highlighted = false; } void UIControl::InitFromXIB(XIBObject* obj) { @@ -63,6 +66,22 @@ void UIControl::InitFromStory(XIBObject* obj) { } } + const char* attr; + if ((attr = obj->getAttrAndHandle("enabled"))) { + if (strcmp(attr, "NO") == 0) + _enabled = false; + } + + if ((attr = obj->getAttrAndHandle("selected"))) { + if (strcmp(attr, "YES") == 0) + _selected = true; + } + + if ((attr = obj->getAttrAndHandle("highlighted"))) { + if (strcmp(attr, "YES") == 0) + _highlighted = true; + } + _outputClassName = "UIControl"; } diff --git a/tools/vsimporter/xib2nib/src/UIControl.h b/tools/vsimporter/xib2nib/src/UIControl.h index 35bed0e000..7c0d3833ec 100644 --- a/tools/vsimporter/xib2nib/src/UIControl.h +++ b/tools/vsimporter/xib2nib/src/UIControl.h @@ -59,6 +59,9 @@ typedef enum { class UIControl : public UIView { public: int _contentVerticalAlignment, _contentHorizontalAlignment; + bool _enabled; + bool _selected; + bool _highlighted; UIControl(); virtual void InitFromXIB(XIBObject* obj); diff --git a/tools/vsimporter/xib2nib/src/UISwitch.cpp b/tools/vsimporter/xib2nib/src/UISwitch.cpp index e31bb8b1d6..dadbf09577 100644 --- a/tools/vsimporter/xib2nib/src/UISwitch.cpp +++ b/tools/vsimporter/xib2nib/src/UISwitch.cpp @@ -33,5 +33,16 @@ void UISwitch::InitFromStory(XIBObject* obj) { } void UISwitch::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { + if (_enabled) + AddBool(writer, "UISwitchEnabled", true); + else + AddBool(writer, "UIDisabled", true); + + if (_selected) + AddBool(writer, "UISelected", true); + + if (_highlighted) + AddBool(writer, "UIHighlighted", true); + UIControl::ConvertStaticMappings(writer, obj); } From 32aea2cd7f2a96acefa2af150accd08feb975a53 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Tue, 13 Feb 2018 10:44:59 +0200 Subject: [PATCH 33/34] UISwitch: added parsing of on/off state --- tools/vsimporter/xib2nib/src/UISwitch.cpp | 17 ++++++++++++++--- tools/vsimporter/xib2nib/src/UISwitch.h | 2 ++ 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/tools/vsimporter/xib2nib/src/UISwitch.cpp b/tools/vsimporter/xib2nib/src/UISwitch.cpp index dadbf09577..21d6cc16f0 100644 --- a/tools/vsimporter/xib2nib/src/UISwitch.cpp +++ b/tools/vsimporter/xib2nib/src/UISwitch.cpp @@ -18,6 +18,7 @@ #include UISwitch::UISwitch() { + _on = false; } void UISwitch::InitFromXIB(XIBObject* obj) { @@ -29,20 +30,30 @@ void UISwitch::InitFromXIB(XIBObject* obj) { void UISwitch::InitFromStory(XIBObject* obj) { UIControl::InitFromStory(obj); + const char* attr; + if ((attr = obj->getAttrAndHandle("on"))) { + if (strcmp(attr, "YES") == 0) + _on = true; + } + _outputClassName = "UISwitch"; } void UISwitch::ConvertStaticMappings(NIBWriter* writer, XIBObject* obj) { + if (_on) + AddBool(writer, "UISwitchOn", _on); + if (_enabled) - AddBool(writer, "UISwitchEnabled", true); + AddBool(writer, "UISwitchEnabled", _enabled); else AddBool(writer, "UIDisabled", true); if (_selected) - AddBool(writer, "UISelected", true); + AddBool(writer, "UISelected", _selected); if (_highlighted) - AddBool(writer, "UIHighlighted", true); + AddBool(writer, "UIHighlighted", _selected); UIControl::ConvertStaticMappings(writer, obj); } + diff --git a/tools/vsimporter/xib2nib/src/UISwitch.h b/tools/vsimporter/xib2nib/src/UISwitch.h index 02de2674f2..e80238bb6a 100644 --- a/tools/vsimporter/xib2nib/src/UISwitch.h +++ b/tools/vsimporter/xib2nib/src/UISwitch.h @@ -18,6 +18,8 @@ #include "UIControl.h" class UISwitch : public UIControl { public: + bool _on; + UISwitch(); virtual void InitFromXIB(XIBObject* obj); virtual void InitFromStory(XIBObject* obj); From c0996e745fcb4a32e39f9ffccf82018ca11278b8 Mon Sep 17 00:00:00 2001 From: Demyan Kimitsa Date: Tue, 27 Feb 2018 13:06:53 +0200 Subject: [PATCH 34/34] included math.h to fix INFINITY was not declared on Linux --- tools/vsimporter/xib2nib/src/XIBObject.h | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/vsimporter/xib2nib/src/XIBObject.h b/tools/vsimporter/xib2nib/src/XIBObject.h index 49dd4c0a52..750c64a0c6 100644 --- a/tools/vsimporter/xib2nib/src/XIBObject.h +++ b/tools/vsimporter/xib2nib/src/XIBObject.h @@ -21,6 +21,7 @@ #include #include #include +#include class XIBObject;