Пример #1
0
void IURLControl::OnMouseDown(int x, int y, IMouseMod* pMod) 
{
  bool opened = false;
  if (CSTR_NOT_EMPTY(mURL)) {
    opened = mPlug->GetGUI()->OpenURL(mURL, mErrMsg); 
  }
  if (!opened && CSTR_NOT_EMPTY(mBackupURL)) {
    opened = mPlug->GetGUI()->OpenURL(mBackupURL, mErrMsg);
  }
}
Пример #2
0
EHost IPlugVST::GetHost()
{
  EHost host = IPlugBase::GetHost();

  if (host == kHostUninit)
  {
    char productStr[256];
    productStr[0] = '\0';
    int version = 0;
    mHostCallback(&mAEffect, audioMasterGetProductString, 0, 0, productStr, 0.0f);

    if (CSTR_NOT_EMPTY(productStr))
    {
      int decVer = mHostCallback(&mAEffect, audioMasterGetVendorVersion, 0, 0, 0, 0.0f);
      int ver = decVer / 10000;
      int rmaj = (decVer - 10000 * ver) / 100;
      int rmin = (decVer - 10000 * ver - 100 * rmaj);
      version = (ver << 16) + (rmaj << 8) + rmin;
    }

    SetHost(productStr, version);
    host = IPlugBase::GetHost();
  }

  return host;
}
Пример #3
0
void IParam::GetDisplayForHost(double value, bool normalized, char* rDisplay, bool withDisplayText)
{
  if (normalized) value = FromNormalizedParam(value, mMin, mMax, mShape);

  if (withDisplayText)
  {
    const char* displayText = GetDisplayText( (int) value);

    if (CSTR_NOT_EMPTY(displayText))
    {
      strcpy(rDisplay, displayText);
      return;
    }
  }

  double displayValue = value;

  if (mNegateDisplay) displayValue = -displayValue;

  if (mDisplayPrecision == 0)
  {
    sprintf(rDisplay, "%d", int(displayValue));
  }
//   else if(mSignDisplay)
//   {
//     char fmt[16];
//     sprintf(fmt, "%%+.%df", mDisplayPrecision);
//     sprintf(rDisplay, fmt, displayValue);
//   }
  else
  {
    sprintf(rDisplay, "%.*f", mDisplayPrecision, displayValue);
  }
}
Пример #4
0
void IParam::GetDisplayForHost(double value, bool normalized, char* rDisplay)
{
  if (normalized) {
    value = FromNormalizedParam(value, mMin, mMax, mShape);
  }

  const char* displayText = GetDisplayText((int) value);
  if (CSTR_NOT_EMPTY(displayText)) {
    strcpy(rDisplay, displayText);
    return;
  }

	double displayValue = value;
	if (mNegateDisplay) {
		displayValue = -displayValue;
	}

	if (displayValue == 0.0) {
		strcpy(rDisplay, "0");
	}
	else
	if (mDisplayPrecision == 0) {
		sprintf(rDisplay, "%d", int(displayValue));
	} 
	else {
		sprintf(rDisplay, "%.*f", mDisplayPrecision, displayValue);
	}
}
Пример #5
0
IURLControl::IURLControl(IPlugBase* pPlug, IRECT pR, const char* url, const char* backupURL, const char* errMsgOnFailure)
: IControl(pPlug, pR)
{
  memset(mURL, 0, MAX_URL_LEN);
  memset(mBackupURL, 0, MAX_URL_LEN);
  memset(mErrMsg, 0, MAX_NET_ERR_MSG_LEN);
  if (CSTR_NOT_EMPTY(url)) {
    strcpy(mURL, url);
  }
  if (CSTR_NOT_EMPTY(backupURL)) {
    strcpy(mBackupURL, backupURL);
  }
  if (CSTR_NOT_EMPTY(errMsgOnFailure)) {
    strcpy(mErrMsg, errMsgOnFailure);
  }
}
Пример #6
0
bool ITextControl::Draw(IGraphics* pGraphics)
{
  char* cStr = mStr.Get();
	if (CSTR_NOT_EMPTY(cStr)) {
  	return pGraphics->DrawIText(&mText, cStr, &mRECT);
  }
  return true;
}
Пример #7
0
bool IBitmapTextControl::Draw(IGraphics* pGraphics)
{
  char* cStr = mStr.Get();
  if (CSTR_NOT_EMPTY(cStr))
  {
    DrawBitmapedText(pGraphics, &mTextBitmap, &mRECT, &mText, &mBlend, cStr, true, false, mCharWidth, mCharHeight, mCharOffset);
  }
  return true;
}
Пример #8
0
HWND IGraphicsWin::GetMainWnd()
{
    if (!mMainWnd) {
        if (mParentWnd) {
            HWND parentWnd = mParentWnd;
            while (parentWnd) {
                mMainWnd = parentWnd;
                parentWnd = GetParent(mMainWnd);
            }
            GetWndClassName(mMainWnd, &mMainWndClassName);
        }
        else
        if (CSTR_NOT_EMPTY(mMainWndClassName.Get())) {
            mPID = GetCurrentProcessId();
            EnumWindows(FindMainWindow, (LPARAM) this);
        }
    }
    return mMainWnd;
}
Пример #9
0
VstIntPtr VSTCALLBACK IPlugVST::VSTDispatcher(AEffect *pEffect, VstInt32 opCode, VstInt32 idx, VstIntPtr value, void *ptr, float opt)
{
  // VSTDispatcher is an IPlugVST class member, we can access anything in IPlugVST from here.
  IPlugVST* _this = (IPlugVST*) pEffect->object;
  if (!_this)
  {
    return 0;
  }
  IPlugBase::IMutexLock lock(_this);

  // Handle a couple of opcodes here to make debugging easier.
  switch (opCode)
  {
    case effEditIdle:
    case __effIdleDeprecated:
    #ifdef USE_IDLE_CALLS
    _this->OnIdle();
    #endif
    return 0;
  }

  Trace(TRACELOC, "%d(%s):%d:%d", opCode, VSTOpcodeStr(opCode), idx, (int) value);

  switch (opCode)
  {
    case effOpen:
    {
      _this->HostSpecificInit();
      _this->OnParamReset();
      return 0;
    }
    case effClose:
    {
      lock.Destroy();
      DELETE_NULL(_this);
      return 0;
    }
    case effGetParamLabel:
    {
      if (idx >= 0 && idx < _this->NParams())
      {
        strcpy((char*) ptr, _this->GetParam(idx)->GetLabelForHost());
      }
      return 0;
    }
    case effGetParamDisplay:
    {
      if (idx >= 0 && idx < _this->NParams())
      {
        _this->GetParam(idx)->GetDisplayForHost((char*) ptr);
      }
      return 0;
    }
    case effGetParamName:
    {
      if (idx >= 0 && idx < _this->NParams())
      {
        strcpy((char*) ptr, _this->GetParam(idx)->GetNameForHost());
      }
      return 0;
    }
      //could implement effGetParameterProperties to group parameters, but can't find a host that supports it
//    case effGetParameterProperties:
//    {
//      if (idx >= 0 && idx < _this->NParams())
//      {
//        VstParameterProperties* props = (VstParameterProperties*) ptr;
//        
//        props->flags = kVstParameterSupportsDisplayCategory;
//        props->category = idx+1;
//        props->numParametersInCategory = 1;
//        strcpy(props->categoryLabel, "test");
//      }
//      return 1;
//    }
    case effGetParameterProperties:
    {
      if (idx >= 0 && idx < _this->NParams())
      {
        VstParameterProperties* props = (VstParameterProperties*) ptr;
        props->flags = 0;
        IParam* pParam = _this->GetParam(idx);
        if (pParam->Type() == IParam::kTypeBool) {
          props->flags |= kVstParameterIsSwitch;
        }
        if (pParam->Type() == IParam::kTypeEnum || pParam->Type() == IParam::kTypeInt) {
          props->flags |= kVstParameterUsesFloatStep;
          int possibleValuesCount = (int) (pParam->GetMax() - pParam->GetMin());
          props->stepFloat = 1.0 / possibleValuesCount;
          props->smallStepFloat = props->stepFloat;
          props->largeStepFloat = props->stepFloat;
        }
      }
      return 1;
    }
    case effString2Parameter:
    {
      if (idx >= 0 && idx < _this->NParams())
      {
        if (ptr)
        {
          double v;
          IParam* pParam = _this->GetParam(idx);
          if (pParam->GetNDisplayTexts())
          {
            int vi;
            if (!pParam->MapDisplayText((char*)ptr, &vi)) return 0;
            v = (double)vi;
          }
          else
          {
            v = atof((char*)ptr);
            if (pParam->DisplayIsNegated()) v = -v;
          }
          if (_this->GetGUI()) _this->GetGUI()->SetParameterFromPlug(idx, v, false);
          pParam->Set(v);
          _this->OnParamChange(idx);
        }
        return 1;
      }
      return 0;
    }
    case effSetSampleRate:
    {
      _this->SetSampleRate(opt);
      _this->Reset();
      return 0;
    }
    case effSetBlockSize:
    {
      _this->SetBlockSize(value);
      _this->Reset();
      return 0;
    }
    case effMainsChanged:
    {
      if (!value)
      {
        _this->OnActivate(false);
        _this->Reset();
      }
      else
      {
        _this->OnActivate(true);
      }
      return 0;
    }
    case effEditGetRect:
    {
      if (ptr && _this->GetGUI())
      {
        *(ERect**) ptr = &(_this->mEditRect);
        return 1;
      }
      ptr = 0;
      return 0;
    }
    case effEditOpen:
    {
      IGraphics* pGraphics = _this->GetGUI();
      
      if (pGraphics)
      {
        #ifdef _WIN32
          if (!pGraphics->OpenWindow(ptr)) pGraphics=0;
        #else   // OSX, check if we are in a Cocoa VST host
          #if defined(__LP64__)
          if (!pGraphics->OpenWindow(ptr)) pGraphics=0;
          #else
          bool iscocoa = (_this->mHasVSTExtensions&VSTEXT_COCOA);
          if (iscocoa && !pGraphics->OpenWindow(ptr)) pGraphics=0;
          if (!iscocoa && !pGraphics->OpenWindow(ptr, 0)) pGraphics=0;
          #endif
        #endif
        if (pGraphics)
        {
          _this->OnGUIOpen();
          return 1;
        }
      }
      return 0;
    }
    case effEditClose:
    {
      if (_this->GetGUI())
      {
        _this->OnGUIClose();
        _this->GetGUI()->CloseWindow();
        return 1;
      }
      return 0;
    }
    case __effIdentifyDeprecated:
    {
      return 'NvEf';  // Random deprecated magic.
    }
    case effGetChunk:
    {
      BYTE** ppData = (BYTE**) ptr;
      if (ppData)
      {
        bool isBank = (!idx);
        ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState));
        _this->InitChunkWithIPlugVer(pChunk);
        bool savedOK = true;
        
        if (isBank)
        {
          _this->ModifyCurrentPreset();
          savedOK = _this->SerializePresets(pChunk);
        }
        else
        {
          savedOK = _this->SerializeState(pChunk);
        }
        
        if (savedOK && pChunk->Size())
        {
          *ppData = pChunk->GetBytes();
          return pChunk->Size();
        }
      }
      return 0;
    }
    case effSetChunk:
    {
      if (ptr)
      {
        bool isBank = (!idx);
        ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState));
        pChunk->Resize(value);
        memcpy(pChunk->GetBytes(), ptr, value);
        int pos = 0;
        int iplugVer = _this->GetIPlugVerFromChunk(pChunk, &pos);
        isBank &= (iplugVer >= 0x010000);
        
        if (isBank)
        {
          pos = _this->UnserializePresets(pChunk, pos);
        }
        else
        {
          pos = _this->UnserializeState(pChunk, pos);
          _this->ModifyCurrentPreset();
        }
        
        if (pos >= 0)
        {
          _this->RedrawParamControls();
          return 1;
        }
      }
      return 0;
    }
    case effProcessEvents:
    {
      VstEvents* pEvents = (VstEvents*) ptr;
      if (pEvents && pEvents->events)
      {
        for (int i = 0; i < pEvents->numEvents; ++i)
        {
          VstEvent* pEvent = pEvents->events[i];
          if (pEvent)
          {
            if (pEvent->type == kVstMidiType)
            {
              VstMidiEvent* pME = (VstMidiEvent*) pEvent;
              IMidiMsg msg(pME->deltaFrames, pME->midiData[0], pME->midiData[1], pME->midiData[2]);
              _this->ProcessMidiMsg(&msg);
              //#ifdef TRACER_BUILD
              //  msg.LogMsg();
              //#endif
            }
            else if (pEvent->type == kVstSysExType) 
            {
              VstMidiSysexEvent* pSE = (VstMidiSysexEvent*) pEvent;
              ISysEx sysex(pSE->deltaFrames, (const BYTE*)pSE->sysexDump, pSE->dumpBytes);
              _this->ProcessSysEx(&sysex);
            }
          }
        }
        return 1;
      }
      return 0;
    }
    case effCanBeAutomated:
    {
      return 1;
    }
    case effGetInputProperties:
    {
      if (ptr && idx >= 0 && idx < _this->NInChannels())
      {
        VstPinProperties* pp = (VstPinProperties*) ptr;
        pp->flags = kVstPinIsActive;
        if (!(idx%2) && idx < _this->NInChannels()-1)
        {
          pp->flags |= kVstPinIsStereo;
        }

        if (_this->GetInputLabel(idx)->GetLength())
        {
          sprintf(pp->label, "%s", _this->GetInputLabel(idx)->Get());
        }
        else
        {
          sprintf(pp->label, "Input %d", idx + 1);
        }

        return 1;
      }
      return 0;
    }
    case effGetOutputProperties:
    {
      if (ptr && idx >= 0 && idx < _this->NOutChannels())
      {
        VstPinProperties* pp = (VstPinProperties*) ptr;
        pp->flags = kVstPinIsActive;
        if (!(idx%2) && idx < _this->NOutChannels()-1)
        {
          pp->flags |= kVstPinIsStereo;
        }

        if (_this->GetOutputLabel(idx)->GetLength())
        {
          sprintf(pp->label, "%s", _this->GetOutputLabel(idx)->Get());
        }
        else
        {
          sprintf(pp->label, "Output %d", idx + 1);
        }

        return 1;
      }
      return 0;
    }
    case effGetPlugCategory:
    {
      if (_this->IsInst()) return kPlugCategSynth;
      return kPlugCategEffect;
    }
    case effProcessVarIo:
    {
      // VstVariableIo* pIO = (VstVariableIo*) ptr; // For offline processing (of audio files?)
      return 0;
    }
    case effSetSpeakerArrangement:
    {
      VstSpeakerArrangement* pInputArr = (VstSpeakerArrangement*) value;
      VstSpeakerArrangement* pOutputArr = (VstSpeakerArrangement*) ptr;
      if (pInputArr)
      {
        int n = pInputArr->numChannels;
        _this->SetInputChannelConnections(0, n, true);
        _this->SetInputChannelConnections(n, _this->NInChannels() - n, false);
      }
      if (pOutputArr)
      {
        int n = pOutputArr->numChannels;
        _this->SetOutputChannelConnections(0, n, true);
        _this->SetOutputChannelConnections(n, _this->NOutChannels() - n, false);
      }
      return 1;
    }
    case effGetSpeakerArrangement:
    {
      VstSpeakerArrangement** ppInputArr = (VstSpeakerArrangement**) value;
      VstSpeakerArrangement** ppOutputArr = (VstSpeakerArrangement**) ptr;
      if (ppInputArr)
      {
        *ppInputArr = &(_this->mInputSpkrArr);
      }
      if (ppOutputArr)
      {
        *ppOutputArr = &(_this->mOutputSpkrArr);
      }
      return 1;
    }
    case effGetEffectName:
    {
      if (ptr)
      {
        strcpy((char*) ptr, _this->GetEffectName());
        return 1;
      }
      return 0;
    }
    case effGetProductString:
    {
      if (ptr)
      {
        strcpy((char*) ptr, _this->GetProductName());
        return 1;
      }
      return 0;
    }
    case effGetVendorString:
    {
      if (ptr)
      {
        strcpy((char*) ptr, _this->GetMfrName());
        return 1;
      }
      return 0;
    }
    case effCanDo:
    {
      if (ptr)
      {
        Trace(TRACELOC, "VSTCanDo(%s)", (char*) ptr);
        if (!strcmp((char*) ptr, "receiveVstTimeInfo"))
        {
          return 1;
        }
        if (_this->DoesMIDI())
        {
          if (!strcmp((char*) ptr, "sendVstEvents") ||
              !strcmp((char*) ptr, "sendVstMidiEvent") ||
              !strcmp((char*) ptr, "receiveVstEvents") ||
              !strcmp((char*) ptr, "receiveVstMidiEvent"))   // ||
          {
            //!strcmp((char*) ptr, "midiProgramNames")) {
            return 1;
          }
        }
        // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/
        if (!strcmp((char*) ptr, "hasCockosExtensions"))
        {
          _this->mHasVSTExtensions |= VSTEXT_COCKOS;
          return 0xbeef0000;
        }
        else if (!strcmp((char*) ptr, "hasCockosViewAsConfig"))
        {
          _this->mHasVSTExtensions |= VSTEXT_COCOA;
          return 0xbeef0000;
        }
      }
      return 0;
    }
    case effGetTailSize:
    {
      return _this->GetTailSize();
    }
    case effVendorSpecific:
    {
      // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/
      if (idx == effGetParamDisplay && ptr)
      {
        if (value >= 0 && value < _this->NParams())
        {
          _this->GetParam(value)->GetDisplayForHost((double) opt, true, (char*) ptr);
        }
        return 0xbeef;
      }

      if (idx == kVstParameterUsesIntStep)
      {
        if (value >= 0 && value < _this->NParams())
        {
          if (_this->GetParam(value)->Type() != IParam::kTypeDouble)
          {
            return 0xbeef;
          }
        }
      }

      return 0;
    }
    case effGetProgram:
    {
      return _this->GetCurrentPresetIdx();
    }
    case effSetProgram:
    {
      if (_this->DoesStateChunks() == false)
      {
        _this->ModifyCurrentPreset(); // TODO: test, something is funny about this http://forum.cockos.com/showpost.php?p=485113&postcount=22
      }
      _this->RestorePreset((int) value);
      return 0;
    }
    case effGetProgramNameIndexed:
    {
      strcpy((char*) ptr, _this->GetPresetName(idx));
      return (CSTR_NOT_EMPTY((char*) ptr) ? 1 : 0);
    }
    case effSetProgramName:
    {
      if (ptr)
      {
        _this->ModifyCurrentPreset((char*) ptr);
        _this->PresetsChangedByHost();
      }
      return 0;
    }
    case effGetProgramName:
    {
      if (ptr)
      {
        int idx = _this->GetCurrentPresetIdx();
        strcpy((char*) ptr, _this->GetPresetName(idx));
      }
      return 0;
    }
    case effGetMidiKeyName:
    {
      if (ptr)
      {
        MidiKeyName* pMKN = (MidiKeyName*) ptr;
        pMKN->keyName[0] = '\0';
        if (_this->MidiNoteName(pMKN->thisKeyNumber, pMKN->keyName))
        {
          return 1;
        }
      }
      return 0;
    }
    case effGetVstVersion:
    {
      return VST_VERSION;
    }
    case effEndSetProgram:
    case effBeginSetProgram:
    case effGetMidiProgramName:
    case effHasMidiProgramsChanged:
    case effGetMidiProgramCategory:
    case effGetCurrentMidiProgram:
    case effSetBypass:
    default:
    {
      return 0;
    }
  }
}
Пример #10
0
const char* IParam::GetLabelForHost()
{
  const char* displayText = GetDisplayText((int) mValue);
  return (CSTR_NOT_EMPTY(displayText)) ? "" : mLabel;
}
tresult PLUGIN_API IPlugVST3Plugin::initialize (FUnknown* context)
{
  TRACE;

  tresult result = SingleComponentEffect::initialize(context);

  String128 tmpStringBuf;
  char hostNameCString[128];
  FUnknownPtr<IHostApplication>app(context);

  if (app)
  {
    app->getName(tmpStringBuf);
    Steinberg::UString(tmpStringBuf, 128).toAscii(hostNameCString, 128);
    SetHost(hostNameCString, 0); // Can't get version in VST3
  }

  if (result == kResultOk)
  {
    int maxInputs = getSpeakerArrForChans(NInChannels()-mScChans);
    if(maxInputs < 0) maxInputs = 0;

    // add io buses with the maximum i/o to start with

    if (maxInputs)
    {
      Steinberg::UString(tmpStringBuf, 128).fromAscii(GetInputBusLabel(0)->Get(), 128);
      addAudioInput(tmpStringBuf, maxInputs);
    }

    if(!mIsInst) // if effect, just add one output bus with max chan count
    {
      Steinberg::UString(tmpStringBuf, 128).fromAscii(GetOutputBusLabel(0)->Get(), 128);
      addAudioOutput(tmpStringBuf, getSpeakerArrForChans(NOutChannels()) );
    }
    else
    {
      for (int i = 0, busIdx = 0; i < NOutChannels(); i+=2, busIdx++)
      {
        Steinberg::UString(tmpStringBuf, 128).fromAscii(GetOutputBusLabel(busIdx)->Get(), 128);
        addAudioOutput(tmpStringBuf, SpeakerArr::kStereo );
      }
    }

    if (mScChans)
    {
      if (mScChans > 2) mScChans = 2;
      Steinberg::UString(tmpStringBuf, 128).fromAscii(GetInputBusLabel(1)->Get(), 128);
      addAudioInput(tmpStringBuf, getSpeakerArrForChans(mScChans), kAux, 0);
    }

    if(DoesMIDI())
    {
      addEventInput (STR16("MIDI Input"), 1);
      //addEventOutput(STR16("MIDI Output"), 1);
    }

    if (NPresets())
    {
      parameters.addParameter(new Parameter(STR16("Preset"),
                                            kPresetParam,
                                            STR16(""),
                                            0,
                                            NPresets(),
                                            ParameterInfo::kIsProgramChange));
    }

    if(!mIsInst)
    {
      StringListParameter * bypass = new StringListParameter(STR16("Bypass"),
                                                            kBypassParam,
                                                            0,
                                                            ParameterInfo::kCanAutomate | ParameterInfo::kIsBypass | ParameterInfo::kIsList);
      bypass->appendString(STR16("off"));
      bypass->appendString(STR16("on"));
      parameters.addParameter(bypass);
    }

    for (int i=0; i<NParams(); i++)
    {
      IParam *p = GetParam(i);

      int32 flags = 0;
      UnitID unitID = kRootUnitId;
      
      const char* paramGroupName = p->GetParamGroupForHost();

      if (CSTR_NOT_EMPTY(paramGroupName))
      {        
        for(int j = 0; j < mParamGroups.GetSize(); j++)
        {
          if(strcmp(paramGroupName, mParamGroups.Get(j)) == 0)
          {
            unitID = j+1;
          }
        }
        
        if (unitID == kRootUnitId) // new unit, nothing found, so add it
        {
          mParamGroups.Add(paramGroupName);
          unitID = mParamGroups.GetSize();
        }
      }

      if (p->GetCanAutomate())
      {
        flags |= ParameterInfo::kCanAutomate;
      }

      switch (p->Type())
      {
        case IParam::kTypeDouble:
        case IParam::kTypeInt:
        {
          Parameter* param = new RangeParameter( STR16(p->GetNameForHost()),
                                                 i,
                                                 STR16(p->GetLabelForHost()),
                                                 p->GetMin(),
                                                 p->GetMax(),
                                                 p->GetDefault(),
                                                 0, // continuous
                                                 flags,
                                                 unitID);

          param->setPrecision (p->GetPrecision());
          parameters.addParameter(param);

          break;
        }
        case IParam::kTypeEnum:
        case IParam::kTypeBool:
        {
          StringListParameter* param = new StringListParameter (STR16(p->GetNameForHost()),
                                                                i,
                                                                STR16(p->GetLabelForHost()),
                                                                flags | ParameterInfo::kIsList,
                                                                unitID);

          int nDisplayTexts = p->GetNDisplayTexts();

          assert(nDisplayTexts);

          for (int j=0; j<nDisplayTexts; j++)
          {
            param->appendString(STR16(p->GetDisplayText(j)));
          }

          parameters.addParameter(param);
          break;
        }
        default:
          break;
      }
    }
  }

  OnHostIdentified();
  RestorePreset(0);
  
  return result;
}
Пример #12
0
void DrawBitmapedText(IGraphics* pGraphics,
                      IBitmap* pTextBitmap,
                      IRECT* controlRect,
                      IText* pItext,
                      IChannelBlend* pBlend,
                      const char* str,
                      bool vCenter,
                      bool multiline,
                      int charWidth,
                      int charHeight,
                      int charOffset)
{
  if (CSTR_NOT_EMPTY(str))
  {
    int len = strlen(str);

    int basicYOffset, basicXOffset;

    if (vCenter)
      basicYOffset = controlRect->T + ((controlRect->H() - charHeight) / 2);
    else
      basicYOffset = controlRect->T;
    
    if (pItext->mAlign == IText::kAlignCenter)
      basicXOffset = controlRect->L + ((controlRect->W() - (len * charWidth)) / 2);
    else
      basicXOffset = controlRect->L + charWidth;

    int widthAsOneLine = charWidth * len;
    int lineWidth = controlRect->W() - (charWidth * 2);

    assert(lineWidth > 0);

    int nLines;
    int stridx = 0;

    int lineCount;

    if(multiline)
    {
      if (widthAsOneLine > lineWidth)
      {
        lineCount = lineWidth / charWidth;
        nLines = widthAsOneLine / lineWidth;
      }
      else// line is shorter than width of rect
      {
        lineCount = len;
        nLines = 1;
      }
    }
    else
    {
      nLines = 1;
      lineCount = lineWidth / charWidth;
    }
    //int newlines = 0;

    for(int line=0; line<=nLines; line++)
    {
      int yOffset = basicYOffset + line * charHeight;

      for(int linepos=0; linepos<lineCount; linepos++)
      {
        if (str[stridx] == '\0') return;
//        else if(str[stridx] == '\n')
//        {
//          yOffset = basicYOffset + line * charHeight;
//        }

        int frameOffset = (int) str[stridx++] - 31; // calculate which frame to look up

        int xOffset = (linepos * (charWidth + charOffset)) + basicXOffset;    // calculate xOffset for character we're drawing
        IRECT charRect = IRECT(xOffset, yOffset, xOffset + charWidth, yOffset + charHeight);
        pGraphics->DrawBitmap(pTextBitmap, &charRect, frameOffset, pBlend);
      }
    }
  }
}
Пример #13
0
VstIntPtr VSTCALLBACK IPlugVST::VSTDispatcher(AEffect *pEffect, VstInt32 opCode, VstInt32 idx, VstIntPtr value, void *ptr, float opt)
{
	// VSTDispatcher is an IPlugVST class member, we can access anything in IPlugVST from here.
	IPlugVST* _this = (IPlugVST*) pEffect->object;
	if (!_this) {
		return 0;
	}
  IPlugBase::IMutexLock lock(_this);

  // Handle a couple of opcodes here to make debugging easier.
  switch (opCode) {
    case effEditIdle:
    case __effIdleDeprecated:
      #ifdef USE_IDLE_CALLS
        _this->OnIdle();
      #endif
    	return 0;
  }

  Trace(TRACELOC, "%d(%s):%d:%d", opCode, VSTOpcodeStr(opCode), idx, (int) value);

  switch (opCode) {

    case effOpen: {
      _this->HostSpecificInit();
	    _this->OnParamReset();
	    return 0;
    }
    case effClose: {
      lock.Destroy();
	    DELETE_NULL(_this);
	    return 0;
    }
    case effGetParamLabel: {
      if (idx >= 0 && idx < _this->NParams())
      {
	      strcpy((char*) ptr, _this->GetParam(idx)->GetLabelForHost());
      }
      return 0;
    }
    case effGetParamDisplay: {
      if (idx >= 0 && idx < _this->NParams())
      {
	      _this->GetParam(idx)->GetDisplayForHost((char*) ptr);
      }
	    return 0;
    }
    case effGetParamName: {
      if (idx >= 0 && idx < _this->NParams())
      {
	      strcpy((char*) ptr, _this->GetParam(idx)->GetNameForHost());      
      }
	    return 0;
    }
    case effString2Parameter:
    {
      if (idx >= 0 && idx < _this->NParams())
      {
        if (ptr)
        {
          IParam* pParam = _this->GetParam(idx);
          double v = VSTString2Parameter(pParam, (char*)ptr);
          if (_this->GetGUI()) _this->GetGUI()->SetParameterFromPlug(idx, v, false);
          pParam->Set(v);
          _this->OnParamChange(idx);
        }
        return 1;
      }
      return 0;
    }
    case effSetSampleRate: {
	    _this->SetSampleRate(opt);
	    _this->Reset();
	    return 0;
    }
    case effSetBlockSize: {
	    _this->SetBlockSize(value);
	    _this->Reset();
	    return 0;
    }
    case effMainsChanged: {
      if (!value) {
        _this->OnActivate(false);
		    _this->Reset();
	    }
      else {
        _this->OnActivate(true);
      }
	    return 0;
    }
    case effEditGetRect: {
	    if (ptr && _this->GetGUI()) {
		    *(ERect**) ptr = &(_this->mEditRect);
		    return 1;
	    }
	    ptr = 0;
	    return 0;
    }
    case effEditOpen:
    {
      IGraphics* pGraphics = _this->GetGUI();
	    if (pGraphics)
      {
#if defined(_WIN32) || defined(IPLUG_NO_CARBON_SUPPORT)
        if (!pGraphics->OpenWindow(ptr)) pGraphics=0;
#else   // OSX, check if we are in a Cocoa VST host
        bool iscocoa = (_this->mHasVSTExtensions&VSTEXT_COCOA);
        if (iscocoa && !pGraphics->OpenWindow(ptr)) pGraphics=0;
        if (!iscocoa && !pGraphics->OpenWindow(ptr, 0)) pGraphics=0;
#endif
        if (pGraphics)
        {
          _this->OnGUIOpen();
          return 1;
        }
	    }
	    return 0;
    }
    case effEditClose: {
	    if (_this->GetGUI()) {
		    _this->OnGUIClose();
        _this->GetGUI()->CloseWindow();  
		    return 1;
	    }
	    return 0;
    }
    case __effIdentifyDeprecated: {
      return 'NvEf';  // Random deprecated magic.
    }
    case effGetChunk: {
	    BYTE** ppData = (BYTE**) ptr;
      if (ppData) {
        bool isBank = (!idx);
        ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState));
        InitializeVSTChunk(pChunk);
        bool savedOK = true;
        if (isBank) {
          _this->ModifyCurrentPreset();
          savedOK = _this->SerializePresets(pChunk);
          //savedOK = _this->SerializeState(pChunk);
        }
        else {
          savedOK = _this->SerializeState(pChunk);
        }
        if (savedOK && pChunk->Size()) {
          *ppData = pChunk->GetBytes();
          return pChunk->Size();
        }
      }
      return 0;
    }
    case effSetChunk: {
      if (ptr) {
        bool isBank = (!idx);
        ByteChunk* pChunk = (isBank ? &(_this->mBankState) : &(_this->mState));
        pChunk->Resize(value);
        memcpy(pChunk->GetBytes(), ptr, value);
        int pos = 0;
        int iplugVer = GetIPlugVerFromChunk(pChunk, &pos);
        isBank &= (iplugVer >= 0x010000);
        if (isBank) {
          pos = _this->UnserializePresets(pChunk, pos);
          //pos = _this->UnserializeState(pChunk, pos);
        }
        else {
          pos = _this->UnserializeState(pChunk, pos);
          _this->ModifyCurrentPreset();
        }
        if (pos >= 0) {
          _this->RedrawParamControls();
		      return 1;
	      }
      }
	    return 0;
    }
    case effProcessEvents: {
	    VstEvents* pEvents = (VstEvents*) ptr;
	    if (pEvents && pEvents->events) {
		    for (int i = 0; i < pEvents->numEvents; ++i) {
          VstEvent* pEvent = pEvents->events[i];
			    if (pEvent) {
				    if (pEvent->type == kVstMidiType) {
					    VstMidiEvent* pME = (VstMidiEvent*) pEvent;
              IMidiMsg msg(pME->deltaFrames, pME->midiData[0], pME->midiData[1], pME->midiData[2]);
              _this->ProcessMidiMsg(&msg);
              //#ifdef TRACER_BUILD
              //  msg.LogMsg();
              //#endif
				    }
				    else if (pEvent->type == kVstSysExType) {
				        VstMidiSysexEvent* pSE = (VstMidiSysexEvent*) pEvent;
				        ISysEx sysex(pSE->deltaFrames, (const BYTE*)pSE->sysexDump, pSE->dumpBytes);
				        _this->ProcessSysEx(&sysex);
				    }
			    }
		    }
		    return 1;
	    }
	    return 0;
    }
	  case effCanBeAutomated: {
	  	return 1;
    }
	  case effGetInputProperties: {
      if (ptr && idx >= 0 && idx < _this->NInChannels()) {
        VstPinProperties* pp = (VstPinProperties*) ptr;
        pp->flags = kVstPinIsActive;
        if (!(idx%2) && idx < _this->NInChannels()-1)
        {
          pp->flags |= kVstPinIsStereo;
        }
        sprintf(pp->label, "Input %d", idx + 1);
        return 1;
      }
      return 0;
    }
    case effGetOutputProperties: {
	    if (ptr && idx >= 0 && idx < _this->NOutChannels()) {
		    VstPinProperties* pp = (VstPinProperties*) ptr;
			  pp->flags = kVstPinIsActive;
        if (!(idx%2) && idx < _this->NOutChannels()-1)
        {
			  	pp->flags |= kVstPinIsStereo;
			  }
		    sprintf(pp->label, "Output %d", idx + 1);
		    return 1;
	    }
	    return 0;
    }
    case effGetPlugCategory: {
      if (_this->IsInst()) return kPlugCategSynth;
	    return kPlugCategEffect;
    }
    case effProcessVarIo: {
	    // VstVariableIo* pIO = (VstVariableIo*) ptr;		// For offline processing (of audio files?)
	    return 0;
    }
    case effSetSpeakerArrangement: {
	    VstSpeakerArrangement* pInputArr = (VstSpeakerArrangement*) value;
	    VstSpeakerArrangement* pOutputArr = (VstSpeakerArrangement*) ptr;
	    if (pInputArr) {
        int n = pInputArr->numChannels;
        _this->SetInputChannelConnections(0, n, true);
        _this->SetInputChannelConnections(n, _this->NInChannels() - n, false);
      }
	    if (pOutputArr) {
        int n = pOutputArr->numChannels;
        _this->SetOutputChannelConnections(0, n, true);
        _this->SetOutputChannelConnections(n, _this->NOutChannels() - n, false);
	    }
	    return 1;
    }
    case effGetSpeakerArrangement: {
	    VstSpeakerArrangement** ppInputArr = (VstSpeakerArrangement**) value;
	    VstSpeakerArrangement** ppOutputArr = (VstSpeakerArrangement**) ptr;
      if (ppInputArr) {
        *ppInputArr = &(_this->mInputSpkrArr);
      }
      if (ppOutputArr) {
        *ppOutputArr = &(_this->mOutputSpkrArr);
      }
      return 1;
    }
    case effGetEffectName: {
	    if (ptr) {
		    strcpy((char*) ptr, _this->GetEffectName());
 		    return 1;
	    }
	    return 0;
    }
    case effGetProductString: {
	    if (ptr) {
		    strcpy((char*) ptr, _this->GetProductName());
		    return 1;
	    }
	    return 0;
    }
    case effGetVendorString: {
	    if (ptr) {
		    strcpy((char*) ptr, _this->GetMfrName());
		    return 1;
	    }
	    return 0;
    }
    case effGetVendorVersion: {
      return _this->GetEffectVersion(true);
    }
    case effCanDo: {
	    if (ptr) {
        Trace(TRACELOC, "VSTCanDo(%s)", (char*) ptr);
        if (!strcmp((char*) ptr, "receiveVstTimeInfo")) {
          return 1;
        }
        if (_this->DoesMIDI()) {
          if (_this->DoesMIDI() & 1) {
            if (!strcmp((char*) ptr, "sendVstEvents") ||
                !strcmp((char*) ptr, "sendVstMidiEvent")) {
              return 1;
            }
          }
          if (_this->DoesMIDI() <= 2) {
            if (!strcmp((char*) ptr, "receiveVstEvents") ||
                !strcmp((char*) ptr, "receiveVstMidiEvent")) {
              return 1;
            }
          }
          //if (!strcmp((char*) ptr, "midiProgramNames")) {
          //  return 1;
          //}
        }
        // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/
        if (!strcmp((char*) ptr, "hasCockosExtensions"))
        {
          _this->mHasVSTExtensions |= VSTEXT_COCKOS;
          return 0xbeef0000;
        }
        else if (!strcmp((char*) ptr, "hasCockosViewAsConfig")) 
        {
          _this->mHasVSTExtensions |= VSTEXT_COCOA;
          return 0xbeef0000; 
        }
      }
	    return 0;
    }
    case effVendorSpecific: {
      switch (idx) {
        // Mouse wheel
        case 0x73744341: {
          if (value == 0x57686565) {
            IGraphics* pGraphics = _this->GetGUI();
            if (pGraphics) {
              return pGraphics->ProcessMouseWheel(opt);
            }
          }
          break;
        }
        // Support Reaper VST extensions: http://www.reaper.fm/sdk/vst/
        case effGetParamDisplay: {
          if (ptr) {
            if (value >= 0 && value < _this->NParams()) {
              _this->GetParam(value)->GetDisplayForHost((double) opt, true, (char*) ptr);
            }
            return 0xbeef;
          }
          break;
        }
        case effString2Parameter: {
          if (ptr && value >= 0 && value < _this->NParams()) {
            if (*(char*) ptr != '\0') {
              IParam* pParam = _this->GetParam(value);
              sprintf((char*) ptr, "%.17f", pParam->GetNormalized(VSTString2Parameter(pParam, (char*) ptr)));
            }
            return 0xbeef;
          }
          break;
        }
        case kVstParameterUsesIntStep: {
          if (value >= 0 && value < _this->NParams()) {
            IParam* pParam = _this->GetParam(value);
            switch (pParam->Type()) {
              case IParam::kTypeBool: {
                return 0xbeef;
              }
              case IParam::kTypeInt:
              case IParam::kTypeEnum: {
                double min, max;
                pParam->GetBounds(&min, &max);
                if (fabs(max - min) < 1.5) {
                  return 0xbeef;
                }
                break;
              }
            }
          }
          break;
        }
      }
      return 0;
    }
    case effGetProgram: {
      return _this->GetCurrentPresetIdx();
    }
    case effSetProgram: {
      //if (!(_this->DoesStateChunks())) {
        _this->ModifyCurrentPreset();
      //}
      _this->RestorePreset((int) value);
      return 0;
    }
    case effGetProgramNameIndexed: {
      strcpy((char*) ptr, _this->GetPresetName(idx));
      return (CSTR_NOT_EMPTY((char*) ptr) ? 1 : 0);
    }
    case effSetProgramName: {
      if (ptr) {
        _this->ModifyCurrentPreset((char*) ptr);
      }
      return 0;
    }
    case effGetProgramName: {
      if (ptr) {
        int idx = _this->GetCurrentPresetIdx();      
        strcpy((char*) ptr, _this->GetPresetName(idx));
      }
      return 0;
    }
    case effGetMidiKeyName: {
	    if (ptr) {
		    MidiKeyName* pMKN = (MidiKeyName*) ptr;
		    pMKN->keyName[0] = '\0';
		    if (_this->MidiNoteName(pMKN->thisKeyNumber, pMKN->keyName)) {
			    return 1;
		    }
	    }
	    return 0;
    }
    case effGetVstVersion: {
	    return VST_VERSION;
    }
    case effBeginSetProgram:
    case effEndSetProgram:
    case effGetMidiProgramName: 
    case effHasMidiProgramsChanged:
    case effGetMidiProgramCategory: 
    case effGetCurrentMidiProgram:
    case effSetBypass:
    default: {
	    return 0;
    }
	}
}
Пример #14
0
// static
pascal OSStatus IGraphicsCarbon::MainEventHandler(EventHandlerCallRef pHandlerCall, EventRef pEvent, void* pGraphicsCarbon)
{
  IGraphicsCarbon* _this = (IGraphicsCarbon*) pGraphicsCarbon;
  IGraphicsMac* pGraphicsMac = _this->mGraphicsMac;
  UInt32 eventClass = GetEventClass(pEvent);
  UInt32 eventKind = GetEventKind(pEvent);

  switch (eventClass)
  {
    case kEventClassKeyboard:
    {
      switch (eventKind)
      {
        case kEventRawKeyDown:
        {
          if (_this->mTextEntryView)
            return eventNotHandledErr;

          bool handle = true;
          int key;
          UInt32 k;
          GetEventParameter(pEvent, kEventParamKeyCode, typeUInt32, NULL, sizeof(UInt32), NULL, &k);

          char c;
          GetEventParameter(pEvent, kEventParamKeyMacCharCodes, typeChar, NULL, sizeof(char), NULL, &c);

          if (k == 49) key = KEY_SPACE;
          else if (k == 125) key = KEY_DOWNARROW;
          else if (k == 126) key = KEY_UPARROW;
          else if (k == 123) key = KEY_LEFTARROW;
          else if (k == 124) key = KEY_RIGHTARROW;
          else if (c >= '0' && c <= '9') key = KEY_DIGIT_0+c-'0';
          else if (c >= 'A' && c <= 'Z') key = KEY_ALPHA_A+c-'A';
          else if (c >= 'a' && c <= 'z') key = KEY_ALPHA_A+c-'a';
          else handle = false;

          if(handle)
            handle = pGraphicsMac->OnKeyDown(_this->mPrevX, _this->mPrevY, key);

          if(handle)
            return noErr;
          else
            return eventNotHandledErr;

        }
      }
    }
    case kEventClassControl:
    {
      switch (eventKind)
      {
        case kEventControlDraw:
        {
          int gfxW = pGraphicsMac->Width(), gfxH = pGraphicsMac->Height();

          IRECT r = GetRegionRect(pEvent, gfxW, gfxH);

          if (_this->mIsComposited)
          {
            GetEventParameter(pEvent, kEventParamCGContextRef, typeCGContextRef, 0, sizeof(CGContextRef), 0, &(_this->mCGC));
            CGContextTranslateCTM(_this->mCGC, 0, gfxH);
            CGContextScaleCTM(_this->mCGC, 1.0, -1.0);
            pGraphicsMac->Draw(&r);
          }
#if __MAC_OS_X_VERSION_MAX_ALLOWED <= 1060
          else
          {
            CGrafPtr port = 0;
            
            GetEventParameter(pEvent, kEventParamGrafPort, typeGrafPtr, 0, sizeof(CGrafPtr), 0, &port);
            QDBeginCGContext(port, &(_this->mCGC));
            
            Rect portBounds;
            GetPortBounds(port, &portBounds);

            int offsetW = 0;
            int offsetH = -portBounds.top;
            
            if ((portBounds.right - portBounds.left) >= gfxW)
            {
              offsetW = 0.5 * ((portBounds.right - portBounds.left) - gfxW);
            }
            
            CGContextTranslateCTM(_this->mCGC, portBounds.left + offsetW, offsetH);
            
            r = IRECT(0, 0, pGraphicsMac->Width(), pGraphicsMac->Height());
            pGraphicsMac->Draw(&r); // Carbon non-composited will redraw everything, the IRECT passed here is the entire plugin-gui
            
            QDEndCGContext(port, &(_this->mCGC));
          }
#endif
          return noErr;
        }
      }
      break;
    }
    case kEventClassMouse:
    {
      HIPoint hp;
      GetEventParameter(pEvent, kEventParamWindowMouseLocation, typeHIPoint, 0, sizeof(HIPoint), 0, &hp);

      #ifdef RTAS_API
      // Header offset
      hp.x -= _this->GetLeftOffset();
      hp.y -= _this->GetTopOffset();

      Rect bounds;
      GetWindowBounds(_this->mWindow, kWindowTitleBarRgn, &bounds);

      // adjust x mouse coord if the gui is less wide than the window
//      int windowWidth = (bounds.right - bounds.left);
//
//      if (windowWidth > pGraphicsMac->Width())
//      {
//        hp.x -= (int) floor((windowWidth - pGraphicsMac->Width()) / 2.);
//      }

      // Title bar Y offset
      hp.y -= bounds.bottom - bounds.top;

      int x = (int) hp.x;
      int y = (int) hp.y;

      #else // NOT RTAS
      HIPointConvert(&hp, kHICoordSpaceWindow, _this->mWindow, kHICoordSpaceView, _this->mView);
      int x = (int) hp.x - 2;
      int y = (int) hp.y - 3;
      #endif

      UInt32 mods;
      GetEventParameter(pEvent, kEventParamKeyModifiers, typeUInt32, 0, sizeof(UInt32), 0, &mods);
      EventMouseButton button;
      GetEventParameter(pEvent, kEventParamMouseButton, typeMouseButton, 0, sizeof(EventMouseButton), 0, &button);
      if (button == kEventMouseButtonPrimary && (mods & cmdKey)) button = kEventMouseButtonSecondary;
      IMouseMod mmod(true, button == kEventMouseButtonSecondary, (mods & shiftKey), (mods & controlKey), (mods & optionKey));

      switch (eventKind)
      {
        case kEventMouseDown:
        {
           _this->HideTooltip();
          
          if (_this->mTextEntryView)
          {
            #if !(USE_MLTE)
            HIViewRef view;
            HIViewGetViewForMouseEvent(_this->mView, pEvent, &view);
            if (view == _this->mTextEntryView) break;
            #endif
            _this->EndUserInput(true);
          }

          #ifdef RTAS_API // RTAS triple click
          if (mmod.L && mmod.R && mmod.C && (pGraphicsMac->GetParamIdxForPTAutomation(x, y) > -1))
          {
            return CallNextEventHandler(pHandlerCall, pEvent);
          }
          #endif

          CallNextEventHandler(pHandlerCall, pEvent);

          UInt32 clickCount = 0;
          GetEventParameter(pEvent, kEventParamClickCount, typeUInt32, 0, sizeof(UInt32), 0, &clickCount);

          if (clickCount > 1)
          {
            pGraphicsMac->OnMouseDblClick(x, y, &mmod);
          }
          else
          {
            pGraphicsMac->OnMouseDown(x, y, &mmod);
          }

          return noErr;
        }

        case kEventMouseUp:
        {
          pGraphicsMac->OnMouseUp(x, y, &mmod);
          return noErr;
        }

        case kEventMouseMoved:
        {
          _this->mPrevX = x;
          _this->mPrevY = y;
          pGraphicsMac->OnMouseOver(x, y, &mmod);
          
          if (pGraphicsMac->TooltipsEnabled()) 
          {
            int c = pGraphicsMac->GetMouseOver();
            if (c != _this->mTooltipIdx) 
            {
              _this->mTooltipIdx = c;
              _this->HideTooltip();
              const char* tooltip = c >= 0 ? pGraphicsMac->GetControl(c)->GetTooltip() : NULL;
              if (CSTR_NOT_EMPTY(tooltip)) 
              {
                _this->mTooltip = tooltip;
                _this->mTooltipTimer = pGraphicsMac->FPS() * 3 / 2;  //TODO: remove FPS link
              }
            }
          }          
          
          return noErr;
        }

        case kEventMouseDragged:
        {
          if (!_this->mTextEntryView)
            pGraphicsMac->OnMouseDrag(x, y, &mmod);
          return noErr;
        }

        case kEventMouseWheelMoved:
        {
          EventMouseWheelAxis axis;
          GetEventParameter(pEvent, kEventParamMouseWheelAxis, typeMouseWheelAxis, 0, sizeof(EventMouseWheelAxis), 0, &axis);

          if (axis == kEventMouseWheelAxisY)
          {
            int d;
            GetEventParameter(pEvent, kEventParamMouseWheelDelta, typeSInt32, 0, sizeof(SInt32), 0, &d);

            if (_this->mTextEntryView) _this->EndUserInput(false);

            pGraphicsMac->OnMouseWheel(x, y, &mmod, d);
            return noErr;
          }
        }
      }

      break;
    }

    case kEventClassWindow:
    {
      WindowRef window;

      if (GetEventParameter(pEvent, kEventParamDirectObject, typeWindowRef, NULL, sizeof (WindowRef), NULL, &window) != noErr)
        break;

      switch (eventKind)
      {
        case kEventWindowDeactivated:
        {
          if (_this->mTextEntryView)
            _this->EndUserInput(false);
          break;
        }
      }
      break;
    }
  }

  return eventNotHandledErr;
}
Пример #15
0
void IGraphicsWin::PromptForFile(WDL_String* pFilename, int action, char* dir, char* extensions)
{
  pFilename->Set("");
	if (!WindowIsOpen()) { 
		return;
	}

  WDL_String pathStr;
	char fnCStr[MAX_PATH_LEN], dirCStr[MAX_PATH_LEN];
	fnCStr[0] = '\0';
	dirCStr[0] = '\0';
	if (CSTR_NOT_EMPTY(dir)) {
  pathStr.Set(dir);
		strcpy(dirCStr, dir);
	}
  else {
    HostPath(&pathStr);
  }
	
	OPENFILENAME ofn;
	memset(&ofn, 0, sizeof(OPENFILENAME));

	ofn.lStructSize = sizeof(OPENFILENAME);
	ofn.hwndOwner = mPlugWnd;
	ofn.lpstrFile = fnCStr;
	ofn.nMaxFile = MAX_PATH_LEN - 1;
	ofn.lpstrInitialDir = dirCStr;
	ofn.Flags = OFN_PATHMUSTEXIST;

    //if (!extensions.empty()) {
        //static char extStr[256];
        //static char defExtStr[16];
        //int i, j, p;

        //for (j = 0, p = 0; j < extensions.size(); ++j) {
        //    extStr[p++] = extensions[j++];
        //}
        //extStr[p++] = '\0';

        //StrVector exts = SplitStr(extensions);
        //for (i = 0, p = 0; i < exts.size(); ++i) {
        //    const std::string& ext = exts[i];
        //    if (i) {
        //        extStr[p++] = ';';
        //    }
        //    extStr[p++] = '*';
        //    extStr[p++] = '.';
        //    for (j = 0; j < ext.size(); ++j) {
        //        extStr[p++] = ext[j];
        //    }
        //}
        //extStr[p++] = '\0';
        //extStr[p++] = '\0';
        //ofn.lpstrFilter = extStr;
        //
        //strcpy(defExtStr, exts.front().c_str());
        //ofn.lpstrDefExt = defExtStr;
    //}

    bool rc = false;
    switch (action) {
        case kFileSave:
            ofn.Flags |= OFN_OVERWRITEPROMPT;
            rc = GetSaveFileName(&ofn);
            break;

        case kFileOpen:     
        default:
            ofn.Flags |= OFN_FILEMUSTEXIST;
    	    rc = GetOpenFileName(&ofn);
            break;
    }

    if (rc) {
        pFilename->Set(ofn.lpstrFile);
    }
}
Пример #16
0
void IGraphicsWin::PromptForFile(WDL_String* pFilename, EFileAction action, WDL_String* pDir, char* extensions)
{
  if (!WindowIsOpen()) { 
    pFilename->Set("");
    return;
  }

  char fnCStr[MAX_PATH_LEN];
  char dirCStr[MAX_PATH_LEN];
  
  if (pFilename->GetLength())
    strcpy(fnCStr, pFilename->Get());
  else
    fnCStr[0] = '\0';

  dirCStr[0] = '\0';
  
  if (!pDir->GetLength()) 
  {
    DesktopPath(pDir);
  }

  strcpy(dirCStr, pDir->Get());
  
  OPENFILENAME ofn;
  memset(&ofn, 0, sizeof(OPENFILENAME));

  ofn.lStructSize = sizeof(OPENFILENAME);
  ofn.hwndOwner = mPlugWnd;
  ofn.lpstrFile = fnCStr;
  ofn.nMaxFile = MAX_PATH_LEN - 1;
  ofn.lpstrInitialDir = dirCStr;
  ofn.Flags = OFN_PATHMUSTEXIST;
  
  if (CSTR_NOT_EMPTY(extensions)) 
  {
      char extStr[256];
      char defExtStr[16];
      int i, p, n = strlen(extensions);
      bool seperator = true;

      for (i = 0, p = 0; i < n; ++i) 
      {
        if (seperator) 
        {
          if (p) 
          {
            extStr[p++] = ';';
          }
          seperator = false;
          extStr[p++] = '*';
          extStr[p++] = '.';
        }
        
        if (extensions[i] == ' ') 
        {
          seperator = true;
        }
        else 
        {
          extStr[p++] = extensions[i];
        }
      }
      extStr[p++] = '\0';

      strcpy(&extStr[p], extStr);
      extStr[p + p] = '\0';
      ofn.lpstrFilter = extStr;

      for (i = 0, p = 0; i < n && extensions[i] != ' '; ++i) 
      {
        defExtStr[p++] = extensions[i];
      }

      defExtStr[p++] = '\0';
      ofn.lpstrDefExt = defExtStr;
    }

    bool rc = false;
    switch (action) 
    {
        case kFileSave:
            ofn.Flags |= OFN_OVERWRITEPROMPT;
            rc = GetSaveFileName(&ofn);
            break;

        case kFileOpen:     
        default:
            ofn.Flags |= OFN_FILEMUSTEXIST;
          rc = GetOpenFileName(&ofn);
            break;
    }

    if (rc) 
    {
      char drive[_MAX_DRIVE];
      if(_splitpath_s(ofn.lpstrFile, drive, sizeof(drive), dirCStr, sizeof(dirCStr), NULL, 0, NULL, 0) == 0)
      {
        pDir->SetFormatted(MAX_PATH_LEN, "%s%s", drive, dirCStr);
      }
   
      pFilename->Set(ofn.lpstrFile);
    }
}