CPlusPlus for Gideros Studio Help

From GiderosMobile
Revision as of 15:26, 13 July 2023 by Hgy29 (talk | contribs) (Text replacement - "<source" to "<syntaxhighlight")

Here you will find various resources to help learn C++ for people who wish to help with Gideros Studio development.

WIN32

KNOWNFOLDERID

platform-win32.cpp

refs:

C:\dev\gideros_hgy29\libgid\src\win32\platform-win32.cpp


Convert wstring <-> string

platform-win32.cpp

refs:

C:\dev\gideros_hgy29\libgid\src\win32\platform-win32.cpp <syntaxhighlight lang="c++">

  1. include <locale> // new 20221014 XXX
  2. include <codecvt> // new 20221014 XXX

...

std::wstring s2ws(const std::string& str) {

   using convert_typeX = std::codecvt_utf8<wchar_t>;
   std::wstring_convert<convert_typeX, wchar_t> converterX;
   return converterX.from_bytes(str);

}

std::string ws2s(const std::wstring& wstr) {

   using convert_typeX = std::codecvt_utf8<wchar_t>;
   std::wstring_convert<convert_typeX, wchar_t> converterX;
   return converterX.to_bytes(wstr);

} </source>


win32 minimum, maximum screen size

platform-win32.cpp

refs:

C:\dev\gideros_hgy29\libgid\src\win32\platform-win32.cpp <syntaxhighlight lang="c++"> </source>


win32 LFS problem with separator

Recent changes to path handling (most likely [0]) caused AssetCatalogTest.create_catalog_after_loading_file to fail on WIN32.

The test relied on the resulting path to be joined with "/" as a path separator. The resulting path used both forward and back-slashes. While these do work for some API's on WIN32, mixing both in a file path isn't expected behavior in most cases, so update the tests to use native slash direction for file-paths.

<syntaxhighlight lang="c++">

* \note If you want a trailing slash, add `SEP_STR` as the last path argument,
* duplicate slashes will be cleaned up.
*/

size_t BLI_path_join(char *__restrict dst, size_t dst_len, const char *path, ...)

  1. define SEP '\\'
  2. define ALTSEP '/'
  3. define SEP_STR "\\"
  4. define ALTSEP_STR "/"
  5. else
  6. define SEP '/'

</source>

<syntaxhighlight lang="c++">

  1. define SEP_CHR '#'
  2. define SEP_STR "#"
  1. define EPS 0.001
  1. define UN_SC_KM 1000.0f
  2. define UN_SC_HM 100.0f
     str_tmp, TEMP_STR_SIZE, "*%.9g" SEP_STR, unit->scalar / scale_pref);
 if (len_num > len_max) {
   len_num = len_max;
 }
 if (found_ofs + len_num + len_move > len_max) {

</source>


openFileDialog

platform-win32.cpp

refs:

<syntaxhighlight lang="c++">

  1. include <wchar.h> // new 20221026 XXX

...

       }else if ((strcmp(what, "openDirectoryDialog") == 0)
               || (strcmp(what, "openFileDialog") == 0)
               || (strcmp(what, "saveFileDialog") == 0))
       {
       	/* TODO parse extension :-( */
           // for win32 args ("title|path|extensions//help") is only 1 arg
           // unlike Qt which seems to cut the | into different args
           if(args.size() == 1){ // do we need to deal with "help" as arg or leave it to Qt?
               // we cut the args
               std::wstring s=ws(args[0].s.c_str()); // "Title|c:\\tmp|Text (*.txt);; Image (*.png)"
               size_t index = s.find(L"|");
               size_t index2 = s.find(L"|", index+1);
               std::wstring title = s.substr(0, index);
               std::wstring place = s.substr(index+1, index2-index-1);
               std::wstring extension = s.substr(index2+1);

// printf("t p e:\n %ls\n %ls\n %ls\n", title.c_str(),place.c_str(),extension.c_str()); // TEST OK

               DWORD dwFlags; // new 20221028 XXX
               HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
               if (SUCCEEDED(hr))
               {
                   if (strcmp(what, "openDirectoryDialog") == 0){
                       /* TO DO */
                       /*--------------------------------------------------*/
                   }else if (strcmp(what, "openFileDialog") == 0){
                       IFileOpenDialog *pFile;
                       COMDLG_FILTERSPEC fileTypes[] = /* TODO parse from wstring extension :-( */
                       {
                           { L"Text Documents", L"*.txt" },
                           { L"All Files", L"*.*" },
                       };
                       // Create the FileOpenDialog object.
                       hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, 
                               IID_IFileOpenDialog, reinterpret_cast<void**>(&pFile));
                       if (SUCCEEDED(hr))
                       {
                           // get/set options
                           pFile->GetOptions(&dwFlags);
                           pFile->SetOptions(dwFlags | FOS_FORCEFILESYSTEM);
                           pFile->SetFileTypes(ARRAYSIZE(fileTypes), fileTypes); // SEE ABOVE fileTypes
                           pFile->SetFileTypeIndex(1); // index starts at 1

// pFile->SetDefaultExtension(L"obj;fbx"); // XXX

                           hr = pFile->SetTitle(title.c_str()); // need more check?
                           // set starting folder
                           IShellItem *pItem = NULL;
                           hr = SHCreateItemFromParsingName(place.c_str(), NULL, IID_IShellItem, (LPVOID *)&pItem);
                           if (SUCCEEDED(hr))
                           {
                               pFile->SetFolder(pItem);
                               pItem->Release();
                               pItem = NULL;
                           }
                           // Show the Open dialog box.
                           hr = pFile->Show(NULL);
                           // Get the file name from the dialog box.
                           if (SUCCEEDED(hr))
                           {
                               IShellItem *pItem;
                               hr = pFile->GetResult(&pItem);
                               if (SUCCEEDED(hr))
                               {
                                   PWSTR pszFilePath;
                                   hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
                                   if (SUCCEEDED(hr))
                                   {
                                       r.type=gapplication_Variant::STRING;
                                       r.s=us(pszFilePath);
                                       rets.push_back(r);
                                       CoTaskMemFree(pszFilePath);
                                   }
                                   pItem->Release();
                               }
                           }
                           pFile->Release();
                       }
                       CoUninitialize();
                       /*--------------------------------------------------*/
                   }else if (strcmp(what, "saveFileDialog") == 0){
                       /* TO DO */
                       /*--------------------------------------------------*/
                   }
               }
           }
           /*------------------------------------------------------------------*/
       }else if (strcmp(what, "temporaryDirectory") == 0)

</source>

openFileDialog Latest

platform-win32.cpp (updated and working piece of code)

Added:

  • append file extension to saved files (1st extension from filters)

<syntaxhighlight lang="c++">

       }else if ((strcmp(what, "openDirectoryDialog") == 0)
               || (strcmp(what, "openFileDialog") == 0)
               || (strcmp(what, "saveFileDialog") == 0))
           {
           if(args.size() <= 2){
               /* INFO SHOWN IN GIDEROS STUDIO DEBUGGER, IMPLEMENTED IN QT, NOT NEEDED HERE? */
           }
           else
           {
               std::wstring title = ws(args[0].s.c_str());
               std::wstring place = ws(args[1].s.c_str());
               std::vector<std::pair<std::wstring,std::wstring>> filters;
               if (args.size()>=3) {
               	std::wstring ext = ws(args[2].s.c_str());
               	while (!ext.empty()) {
                   	std::wstring next;
               		size_t semicolon=ext.find(L";;");
               		if (semicolon!=std::wstring::npos) {
               			next=ext.substr(semicolon+2);
               			ext=ext.substr(0,semicolon);
               		}
               		size_t p1=ext.find_first_of(L'(');
               		size_t p2=ext.find_last_of(L')');
               		if ((p1!=std::wstring::npos)&&(p2!=std::wstring::npos)&&(p2>p1))
               		{
               			//Valid filter, extract label and extensions
               			std::wstring label=ext.substr(0,p1);
               			std::wstring exts=ext.substr(p1+1,p2-p1-1);
               			//QT uses space for extensions separator, while windows expects semicolon. Convert them.
               			std::replace(exts.begin(),exts.end(),L' ',L';');
               			filters.push_back(std::pair<std::wstring,std::wstring>(label,exts));
               		}
               		ext=next;
               	}
               }
               DWORD dwFlags;
               HRESULT hr = CoInitializeEx(NULL, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE);
               if (SUCCEEDED(hr))
               {
                   COMDLG_FILTERSPEC *fileTypes=new COMDLG_FILTERSPEC[filters.size()];
                   for (size_t i=0;i<filters.size();i++) {
                   	fileTypes[i].pszName=filters[i].first.c_str();
                   	fileTypes[i].pszSpec=filters[i].second.c_str();
                   }
                   IFileDialog *pFile;

if (strcmp(what, "saveFileDialog") == 0)

                       hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL,
                               IID_IFileSaveDialog, reinterpret_cast<void**>(&pFile));

else

                       hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL,
                               IID_IFileOpenDialog, reinterpret_cast<void**>(&pFile));

if (SUCCEEDED(hr)) { bool isFolder=(strcmp(what, "openDirectoryDialog") == 0); // get/set options pFile->GetOptions(&dwFlags); pFile->SetOptions(dwFlags | FOS_FORCEFILESYSTEM | (isFolder?FOS_PICKFOLDERS:0)); if (!isFolder) { pFile->SetFileTypes(filters.size(), fileTypes); pFile->SetFileTypeIndex(1); // index starts at 1 //pFile->SetDefaultExtension(L"obj;fbx"); // append default extension

                           //printf("* fileTypes *, set default extension to %ls\n", fileTypes[0].pszSpec); OK

pFile->SetDefaultExtension(fileTypes[0].pszSpec); // append default 1st extension } hr = pFile->SetTitle(title.c_str()); // need more check?

// set starting folder IShellItem *pItem = NULL; hr = SHCreateItemFromParsingName(place.c_str(), NULL, IID_IShellItem, (LPVOID *)&pItem); if (SUCCEEDED(hr)) { pFile->SetFolder(pItem); pItem->Release(); pItem = NULL; }

// Show the Open dialog box. hr = pFile->Show(NULL); // Get the file name from the dialog box. if (SUCCEEDED(hr)) { IShellItem *pItem; hr = pFile->GetResult(&pItem); if (SUCCEEDED(hr)) { PWSTR pszFilePath; hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath); if (SUCCEEDED(hr)) { r.type=gapplication_Variant::STRING; r.s=us(pszFilePath); rets.push_back(r);

CoTaskMemFree(pszFilePath); } pItem->Release(); } } pFile->Release(); } CoUninitialize(); delete[] fileTypes;

               }
           }
           /*------------------------------------------------------------------*/
       }else if (strcmp(what, "temporaryDirectory") == 0)

</source>


Locate first occurrence of character in wide string

platform-win32.cpp

refs:

<syntaxhighlight lang="c++"> std::wstring gs=ws(args[0].s.c_str()); // "Title|C:/tmp/|Text (*.txt);; Image (*.png)" size_t index = gs.find(L"|"); size_t index2 = gs.find(L"|", index+1); printf("args0: %ls\n", gs.c_str()); // output: Title|C:/tmp/|Text (*.txt);; Image (*.png) printf("indices: %d, %d\n", index,index2); // output 5, 13 std::wstring title = gs.substr(0, index); std::wstring path = gs.substr(index+1, index2-index-1); std::wstring exts = gs.substr(index2+1); printf("t p e:\n %ls\n %ls\n %ls\n", title.c_str(),path.c_str(),exts.c_str()); // Title C:/tmp/ Text (*.txt);; Image (*.png) </source>


application:getKeyboardModifiers()

platform-win32.cpp

refs:

<syntaxhighlight lang="c++"> if(GetAsyncKeyState(VK_LSHIFT) & 0x8000)

   ; // left shift is currently down

</source>


mkDir

platform-win32.cpp

Tested and seems ok :-)

refs:

<syntaxhighlight lang="c++">

       }else if (strcmp(what, "mkDir") == 0)
       {
           // new 20221114 XXX
           std::wstring dir = ws(args[0].s.c_str());
           if (_wmkdir(dir.c_str()) == 0)
               printf("mkDir OK: %S\n", dir.c_str()); // can be useful for the w32 console
           else
               printf("mkDir failed or Dir may already exist: %S\n", dir.c_str()); // can be useful for the w32 console
           /*------------------------------------------------------------------*/
       }else if (strcmp(what, "documentDirectory") == 0)

</source>


pathfileexists

platform-win32.cpp

Tested and seems ok but not sure about what the return value should be :-/ and we can also check for access mode!

refs:

<syntaxhighlight lang="c++">

       }else if (strcmp(what, "pathfileexists") == 0) // new 20221116 XXX
       {
           if (args.size() > 0) {
               std::wstring path = ws(args[0].s.c_str());
               int retValue;
               if (_waccess(path.c_str(), 0) == 0) { // modes: 0=Existence only, 2=Write-only, 4=Read-only, 6=Read and write
                   // path exists
                   retValue = 1;
               } else {
                   retValue = 0;
               }
               r.type=gapplication_Variant::DOUBLE;
               r.d=retValue;
               rets.push_back(r);
           }
           /*------------------------------------------------------------------*/
       }else if ((strcmp(what, "openDirectoryDialog") == 0)

</source>

pathfileexists Qt

platform-qt.cpp

QFile Class seems to be "kind of" the equivalent?

refs:

bool QFile::exists(const QString &fileName) Returns true if the file specified by fileName exists; otherwise returns false. Note: If fileName is a symlink that points to a non-existing file, false is returned.

I will need to mix this and _waccess.

WM_GETMINMAXINFO

win32.cpp

WIP

refs:

<syntaxhighlight lang="c++"> </source>


LoadCursorA

platform-win32.cpp

WIP

refs:

<syntaxhighlight lang="c++">

   else { // SET
       if (strcmp(what, "cursor") == 0)
       {
       	/* TODO */
           std::string &shape = args[0].s;

// QStringList acceptedValue; // acceptedValue << "arrow" << "upArrow" << "cross" << "wait" << "IBeam"; // acceptedValue << "sizeVer" << "sizeHor" << "sizeBDiag" << "sizeFDiag" << "sizeAll"; // acceptedValue << "blank" << "splitV" << "splitH" << "pointingHand" << "forbidden"; // acceptedValue << "whatsThis" << "busy" << "openHand" << "closedHand" << "dragCopy"; // acceptedValue << "dragMove" << "dragLink";

           HCURSOR cursor;
           if (shape == "arrow") {
               printf("** cursor arrow\n");
               cursor = LoadCursorA(NULL, (LPCSTR)IDC_ARROW);
               SetCursor(cursor);
           } else if (shape == "upArrow") {
               printf("** cursor uparrow\n"); // LUA DEBUG OK BUT ARROW SHAPE DOESN'T CHANGE :-(
               cursor = LoadCursorA(NULL, (LPCSTR)IDC_UPARROW);
               SetCursor(cursor);
           }
           /*------------------------------------------------------------------*/
       }else if (strcmp(what, "windowPosition") == 0)

</source>

modal windows dialog

Test01

refs:

C:\dev\gideros_dev\libgid\src\win32\platform-win32.cpp <syntaxhighlight lang="c++">

                   COMDLG_FILTERSPEC *fileTypes=new COMDLG_FILTERSPEC[filters.size()];
                   for (size_t i=0;i<filters.size();i++) {
                   	fileTypes[i].pszName=filters[i].first.c_str();
                   	fileTypes[i].pszSpec=filters[i].second.c_str();
                   }
                   IFileDialog *pFile;

if (strcmp(what, "saveFileDialog") == 0) // hr = CoCreateInstance(CLSID_FileSaveDialog, NULL, CLSCTX_ALL, // IID_IFileSaveDialog, reinterpret_cast<void**>(&pFile));

                       hr = CoCreateInstance(CLSID_FileSaveDialog, hwndcopy, CLSCTX_ALL,
                               IID_IFileSaveDialog, reinterpret_cast<void**>(&pFile));

else // hr = CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_ALL, // IID_IFileOpenDialog, reinterpret_cast<void**>(&pFile));

                       hr = CoCreateInstance(CLSID_FileOpenDialog, hwndcopy, CLSCTX_ALL,
                               IID_IFileOpenDialog, reinterpret_cast<void**>(&pFile));

if (SUCCEEDED(hr)) { </source>

CBUMP

the TODOs

bump.cpp

<syntaxhighlight lang="c++"> static bool rect_getSegmentIntersectionIndices(double x, double y, double w, double h, double x1, double y1, double x2, double y2, double &ti1, double &ti2, double &nx1, double &ny1, double &nx2, double &ny2) { //ti1, ti2 = ti1 or 0, ti2 or 1 TODO double dx = x2 - x1; double dy = y2 - y1; ... </source>

<syntaxhighlight lang="c++"> static bool rect_detectCollision(double x1, double y1, double w1, double h1, double x2, double y2, double w2, double h2, double goalX, double goalY, Collision &col) { //goalX = goalX or x1 TODO //goalY = goalY or y1

double dx = goalX - x1, dy = goalY - y1; ... </source> It is time to do the TODOs ;-)