home *** CD-ROM | disk | FTP | other *** search
/ Computer Shopper 275 / DPCS0111DVD.ISO / Toolkit / Audio-Visual / VirtualDub / Source / VirtualDub-1.9.10-src.7z / src / Dita / source / interface.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2009-09-14  |  12.2 KB  |  468 lines

  1. //    VirtualDub - Video processing and capture application
  2. //    Copyright (C) 1998-2004 Avery Lee
  3. //
  4. //    This program is free software; you can redistribute it and/or modify
  5. //    it under the terms of the GNU General Public License as published by
  6. //    the Free Software Foundation; either version 2 of the License, or
  7. //    (at your option) any later version.
  8. //
  9. //    This program is distributed in the hope that it will be useful,
  10. //    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11. //    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12. //    GNU General Public License for more details.
  13. //
  14. //    You should have received a copy of the GNU General Public License
  15. //    along with this program; if not, write to the Free Software
  16. //    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  17.  
  18. #include <stdafx.h>
  19. #include <vd2/system/vdtypes.h>
  20. #include <vd2/Dita/interface.h>
  21. #include <vd2/Dita/basetypes.h>
  22. #include <vd2/Dita/bytecode.h>
  23. #include <vd2/Dita/resources.h>
  24. #include <vd2/Dita/controls.h>
  25.  
  26. #include <vector>
  27.  
  28. using namespace nsVDDitaBytecode;
  29.  
  30. namespace {
  31.     class VDUICreator {
  32.     public:
  33.         VDUICreator(IVDUIWindow *pParent);
  34.  
  35.         IVDUIWindow *Execute(const unsigned char *resdata);
  36.  
  37.     protected:
  38.         void AddLastWindow();
  39.  
  40.         union Value {
  41.             sint32 i;
  42.             float f;
  43.             const wchar_t *s;
  44.  
  45.             Value(sint32 _i) : i(_i) {}
  46.             Value(float _f) : f(_f) {}
  47.             Value(const wchar_t *_s) : s(_s) {}
  48.         };
  49.  
  50.         std::vector<IVDUIWindow *>    mWinStack;
  51.         std::vector<Value>            mValueStack;
  52.         std::list<VDUIParameters>    mParameters;
  53.  
  54.         typedef std::list<std::vector<unsigned char> > tLinkExprs;
  55.         tLinkExprs    mLinkExprs;
  56.  
  57.         IVDUIWindow *mpFirstWindow;
  58.         IVDUIWindow *mpLastWindow;
  59.     };
  60. }
  61.  
  62. VDUICreator::VDUICreator(IVDUIWindow *pParent)
  63.     : mpFirstWindow(NULL)
  64. {
  65.     mParameters.push_back(VDUIParameters());
  66.  
  67.     if (pParent)
  68.         mWinStack.push_back(pParent);
  69. }
  70.  
  71. IVDUIWindow *VDUICreator::Execute(const unsigned char *resdata) {
  72.     while(const unsigned char c = *resdata++) {
  73.         switch(c) {
  74.         case kBC_Zero:
  75.             mValueStack.push_back(0);
  76.             break;
  77.         case kBC_One:
  78.             mValueStack.push_back(1);
  79.             break;
  80.         case kBC_Int8:
  81.             mValueStack.push_back((sint8)*resdata++);
  82.             break;
  83.         case kBC_Int32:
  84.         case kBC_Float32:
  85.             mValueStack.push_back((sint32)(resdata[0] + (resdata[1]<<8) + (resdata[2]<<16) + (resdata[3]<<24)));
  86.             resdata += 4;
  87.             break;
  88.         case kBC_String:
  89.             mValueStack.push_back(VDLoadString(0, resdata[0] + (resdata[1]<<8), resdata[2] + (resdata[3]<<8)));
  90.             resdata += 4;
  91.             break;
  92.  
  93.         case kBC_StringShort:
  94.             mValueStack.push_back(VDLoadString(0, 0xFFFF, resdata[0] + (resdata[1]<<8)));
  95.             resdata += 2;
  96.             break;
  97.  
  98.         case kBC_StringNull:
  99.             mValueStack.push_back(L"");
  100.             break;
  101.  
  102.         case kBC_InvokeTemplate:
  103.             if (const unsigned char *tmp = VDLoadTemplate(0, resdata[0] + (resdata[1]<<8)))
  104.                 Execute(tmp);
  105.             resdata += 2;
  106.             break;
  107.  
  108.         case kBC_BeginChildren:
  109.             mWinStack.push_back(mpLastWindow);
  110.             break;
  111.  
  112.         case kBC_EndChildren:
  113.             mWinStack.pop_back();
  114.             break;
  115.  
  116.         case kBC_SetParameterB:
  117.             {
  118.                 sint32 val = mValueStack.back().i;
  119.                 mValueStack.pop_back();
  120.                 uint32 id = mValueStack.back().i;
  121.                 mValueStack.pop_back();
  122.                 mParameters.back().SetB(id, val != 0);
  123.             }
  124.             break;
  125.  
  126.         case kBC_SetParameterI:
  127.             {
  128.                 sint32 val = mValueStack.back().i;
  129.                 mValueStack.pop_back();
  130.                 uint32 id = mValueStack.back().i;
  131.                 mValueStack.pop_back();
  132.                 mParameters.back().SetI(id, val);
  133.             }
  134.             break;
  135.  
  136.         case kBC_SetParameterF:
  137.             {
  138.                 float val = mValueStack.back().f;
  139.                 mValueStack.pop_back();
  140.                 uint32 id = mValueStack.back().i;
  141.                 mValueStack.pop_back();
  142.                 mParameters.back().SetF(id, val);
  143.             }
  144.             break;
  145.  
  146.         case kBC_PushParameters:
  147.             mParameters.push_back(mParameters.back());
  148.             break;
  149.  
  150.         case kBC_PopParameters:
  151.             mParameters.pop_back();
  152.             break;
  153.  
  154.         case kBC_SetLinkExpr:
  155.             {
  156.                 const int len = resdata[0] + (resdata[1] << 8);
  157.                 resdata += 2;
  158.                 mLinkExprs.push_back(std::vector<unsigned char>());
  159.                 mLinkExprs.back().assign(resdata, resdata+len);
  160.                 resdata += len;
  161.             }
  162.             break;
  163.  
  164.         case kBC_AddListItem:
  165.             vdpoly_cast<IVDUIList *>(mWinStack.back())->AddItem(mValueStack.back().s);
  166.             mValueStack.pop_back();
  167.             break;
  168.  
  169.         case kBC_AddPage:
  170.             vdpoly_cast<IVDUIPageSet *>(mWinStack.back())->AddPage(mValueStack.back().i);
  171.             mValueStack.pop_back();
  172.             break;
  173.  
  174.         case kBC_SetColumn:{
  175.             IVDUIGrid *const pGrid = vdpoly_cast<IVDUIGrid *>(mWinStack.back());
  176.             if(VDINLINEASSERT(pGrid)){
  177.                 VDUIParameters& parms = mParameters.back();
  178.                 const int col = mValueStack.back().i;
  179.                 mValueStack.pop_back();
  180.  
  181.                 const int minsize = parms.GetI(nsVDUI::kUIParam_MinW, -1);
  182.                 const int maxsize = parms.GetI(nsVDUI::kUIParam_MaxW, -1);
  183.                 const int affinity = parms.GetI(nsVDUI::kUIParam_Affinity, -1);
  184.                 pGrid->SetColumn(col, minsize, maxsize, affinity);
  185.             }
  186.             break;
  187.         }
  188.  
  189.         case kBC_SetRow:{
  190.             IVDUIGrid *const pGrid = vdpoly_cast<IVDUIGrid *>(mWinStack.back());
  191.             if(VDINLINEASSERT(pGrid)){
  192.                 VDUIParameters& parms = mParameters.back();
  193.                 const int row = mValueStack.back().i;
  194.                 mValueStack.pop_back();
  195.  
  196.                 const int minsize = parms.GetI(nsVDUI::kUIParam_MinH, -1);
  197.                 const int maxsize = parms.GetI(nsVDUI::kUIParam_MaxH, -1);
  198.                 const int affinity = parms.GetI(nsVDUI::kUIParam_Affinity, -1);
  199.                 pGrid->SetRow(row, minsize, maxsize, affinity);
  200.             }
  201.             break;
  202.         }
  203.  
  204.         case kBC_NextRow:
  205.             vdpoly_cast<IVDUIGrid *>(mWinStack.back())->NextRow();
  206.             break;
  207.  
  208.         case kBC_CreateChildDialog:
  209.             mpLastWindow = VDCreateDialogFromResource(mValueStack.back().i, mWinStack.empty() ? NULL : mWinStack.back());
  210.             mValueStack.pop_back();
  211.             mpLastWindow->SetID(mValueStack.back().i);
  212.             mValueStack.pop_back();
  213.             if (!mpFirstWindow)
  214.                 mpFirstWindow = mpLastWindow;
  215.             break;
  216.  
  217.         case kBC_CreateCustom:
  218.             {
  219.                 const wchar_t *caption = mValueStack.back().s;
  220.                 mValueStack.pop_back();
  221.                 const uint32 clsid = mValueStack.back().i;
  222.                 mValueStack.pop_back();
  223.                 const uint32 id = mValueStack.back().i;
  224.                 mValueStack.pop_back();
  225.  
  226.                 IVDUIWindow *pWin = VDUICreateWindowClass(clsid);
  227.                 if (pWin) {
  228.                     mpLastWindow = pWin;
  229.                     mpLastWindow->SetCaption(caption);
  230.                     mpLastWindow->SetID(id);
  231.  
  232.                     AddLastWindow();
  233.                 }
  234.             }
  235.             break;
  236.  
  237.         default:
  238.             if (c >= 0x80) {
  239.                 switch(c) {
  240.                 case kBC_CreateLabel:        mpLastWindow = VDCreateUILabel(); break;
  241.                 case kBC_CreateButton:        mpLastWindow = VDCreateUIButton(); break;
  242.                 case kBC_CreateCheckBox:    mpLastWindow = VDCreateUICheckbox(); break;
  243.                 case kBC_CreateDialog:        mpLastWindow = VDCreateUIBaseWindow(); break;
  244.                 case kBC_CreateSplitter:    mpLastWindow = VDCreateUISplitter(); break;
  245.                 case kBC_CreateSet:            mpLastWindow = VDCreateUISet(); break;
  246.                 case kBC_CreatePageSet:        mpLastWindow = VDCreateUIPageSet(); break;
  247.                 case kBC_CreateGrid:        mpLastWindow = VDCreateUIGrid(); break;
  248.                 case kBC_CreateComboBox:    mpLastWindow = VDCreateUIComboBox(); break;
  249.                 case kBC_CreateListBox:        mpLastWindow = VDCreateUIListBox(); break;
  250.                 case kBC_CreateListView:    mpLastWindow = VDCreateUIListView(); break;
  251.                 case kBC_CreateTextEdit:    mpLastWindow = VDCreateUITextEdit(); break;
  252.                 case kBC_CreateTextArea:    mpLastWindow = VDCreateUITextArea(); break;
  253.                 case kBC_CreateGroup:        mpLastWindow = VDCreateUIGroup(); break;
  254.                 case kBC_CreateOption:        mpLastWindow = VDCreateUIOption(); break;
  255.                 case kBC_CreateTrackbar:    mpLastWindow = VDCreateUITrackbar(); break;
  256.                 case kBC_CreateHotkey:        mpLastWindow = VDCreateUIHotkey(); break;
  257.                 default:    VDNEVERHERE;
  258.                 }
  259.  
  260.                 mpLastWindow->SetCaption(mValueStack.back().s);
  261.                 mValueStack.pop_back();
  262.                 const uint32 id = mValueStack.back().i;
  263.                 mpLastWindow->SetID(id);
  264.                 mValueStack.pop_back();
  265.  
  266.                 AddLastWindow();
  267.             } else {
  268.                 VDNEVERHERE;
  269.             }
  270.             break;
  271.         }
  272.     }
  273.  
  274.     vdpoly_cast<IVDUIBase *>(mpFirstWindow)->FinalizeDialog();
  275.  
  276.     return mpFirstWindow;
  277. }
  278.  
  279. void VDUICreator::AddLastWindow() {
  280.     IVDUIParameters& parms = mParameters.back();
  281.  
  282.     if (!mWinStack.empty()) {
  283.         IVDUIWindow *pWin = mWinStack.back();
  284.  
  285.         if (IVDUIGrid *pGrid = vdpoly_cast<IVDUIGrid *>(pWin))
  286.             pGrid->AddChild(mpLastWindow,
  287.                 parms.GetI(nsVDUI::kUIParam_Col, -1),
  288.                 parms.GetI(nsVDUI::kUIParam_Row, -1),
  289.                 parms.GetI(nsVDUI::kUIParam_ColSpan, 1),
  290.                 parms.GetI(nsVDUI::kUIParam_RowSpan, 1));
  291.         else
  292.             pWin->AddChild(mpLastWindow);
  293.     }
  294.  
  295.     mpLastWindow->Create(&parms);
  296.  
  297.     IVDUIBase *pBase = mpLastWindow->GetBase();
  298.     uint32 id = mpLastWindow->GetID();
  299.     if (pBase && id) {
  300.         int expr = parms.GetI(nsVDUI::kUIParam_EnableLinkExpr, -1);
  301.         if (expr >= 0) {
  302.             tLinkExprs::const_iterator it(mLinkExprs.begin());
  303.  
  304.             std::advance(it, expr);
  305.             pBase->Link(id, nsVDUI::kLinkTarget_Enable, &(*it).front(), (*it).size());
  306.         }
  307.  
  308.         expr = parms.GetI(nsVDUI::kUIParam_ValueLinkExpr, -1);
  309.         if (expr >= 0) {
  310.             tLinkExprs::const_iterator it(mLinkExprs.begin());
  311.  
  312.             std::advance(it, expr);
  313.             pBase->Link(id, nsVDUI::kLinkTarget_Value, &(*it).front(), (*it).size());
  314.         }
  315.     }
  316.  
  317.     if (!mpFirstWindow)
  318.         mpFirstWindow = mpLastWindow;
  319. }
  320.  
  321.  
  322. IVDUIWindow *VDCreateDialogFromResource(int dialogID, IVDUIWindow *pParent) {
  323.     VDUICreator ctx(pParent);
  324.  
  325.     const unsigned char *p = VDLoadDialog(0, dialogID);
  326.  
  327.     if (p)
  328.         return ctx.Execute(p);
  329.  
  330.     return NULL;
  331. }
  332.  
  333.  
  334.  
  335.  
  336. uint32 VDUIExecuteRuntimeExpression(const uint8 *expr, IVDUIWindow *const *pSrcWindows) {
  337.     std::vector<sint32> stack;
  338.  
  339.     while(uint8 c = *expr++) {
  340.         switch(c) {
  341.         case kBCE_Zero:
  342.             stack.push_back(0);
  343.             break;
  344.         case kBCE_One:
  345.             stack.push_back(1);
  346.             break;
  347.         case kBCE_Int8:
  348.             stack.push_back((sint8)*expr++);
  349.             break;
  350.         case kBCE_Int32:
  351.             stack.push_back(expr[0] + ((sint32)expr[1] << 8) + ((sint32)expr[2] << 16) + ((sint32)expr[3] << 24));
  352.             expr += 4;
  353.             break;
  354.  
  355.         case kBCE_OpNegate:
  356.             stack.back() = -stack.back();
  357.             break;
  358.  
  359.         case kBCE_OpNot:
  360.             stack.back() = !stack.back();
  361.             break;
  362.  
  363.         case kBCE_OpMul:
  364.             *(stack.end() - 2) *= stack.back();
  365.             stack.pop_back();
  366.             break;
  367.  
  368.         case kBCE_OpDiv:
  369.             *(stack.end() - 2) /= stack.back();
  370.             stack.pop_back();
  371.             break;
  372.  
  373.         case kBCE_OpAdd:
  374.             *(stack.end() - 2) += stack.back();
  375.             stack.pop_back();
  376.             break;
  377.  
  378.         case kBCE_OpSub:
  379.             *(stack.end() - 2) -= stack.back();
  380.             stack.pop_back();
  381.             break;
  382.  
  383.         case kBCE_OpEQ:
  384.             *(stack.end() - 2) = *(stack.end() - 2) == stack.back();
  385.             stack.pop_back();
  386.             break;
  387.  
  388.         case kBCE_OpNE:
  389.             *(stack.end() - 2) = *(stack.end() - 2) != stack.back();
  390.             stack.pop_back();
  391.             break;
  392.  
  393.         case kBCE_OpLT:
  394.             *(stack.end() - 2) = *(stack.end() - 2) < stack.back();
  395.             stack.pop_back();
  396.             break;
  397.  
  398.         case kBCE_OpLE:
  399.             *(stack.end() - 2) = *(stack.end() - 2) <= stack.back();
  400.             stack.pop_back();
  401.             break;
  402.  
  403.         case kBCE_OpGT:
  404.             *(stack.end() - 2) = *(stack.end() - 2) > stack.back();
  405.             stack.pop_back();
  406.             break;
  407.  
  408.         case kBCE_OpGE:
  409.             *(stack.end() - 2) = *(stack.end() - 2) >= stack.back();
  410.             stack.pop_back();
  411.             break;
  412.  
  413.         case kBCE_OpLogicalAnd:
  414.             *(stack.end() - 2) = *(stack.end() - 2) && stack.back();
  415.             stack.pop_back();
  416.             break;
  417.  
  418.         case kBCE_OpLogicalOr:
  419.             *(stack.end() - 2) = *(stack.end() - 2) || stack.back();
  420.             stack.pop_back();
  421.             break;
  422.  
  423.         case kBCE_GetValue:
  424.             {
  425.                 IVDUIWindow *pWin = pSrcWindows[*expr++];
  426.  
  427.                 stack.push_back(pWin ? pWin->GetValue() : 0);
  428.             }
  429.             break;
  430.         }
  431.     }
  432.  
  433.     VDASSERT(stack.size() == 1);
  434.  
  435.     return stack.back();
  436. }
  437.  
  438. ////////////////////////////////////////////////////////////////////////////////////////////////////
  439.  
  440. namespace {
  441.     struct VDUIWindowClassNode {
  442.         uint32 mClassID;
  443.         IVDUIWindow *(*mpCreator)();
  444.     };
  445.  
  446.     std::vector<VDUIWindowClassNode> g_VDUIWindowClassList;
  447. }
  448.  
  449. void VDUIRegisterWindowClass(uint32 classID, IVDUIWindow *(*pCreator)()) {
  450.     VDUIWindowClassNode node;
  451.     node.mClassID = classID;
  452.     node.mpCreator = pCreator;
  453.     g_VDUIWindowClassList.push_back(node);
  454. }
  455.  
  456. IVDUIWindow *VDUICreateWindowClass(uint32 classID) {
  457.     std::vector<VDUIWindowClassNode>::const_iterator it(g_VDUIWindowClassList.begin()), itEnd(g_VDUIWindowClassList.end());
  458.  
  459.     for(; it!=itEnd; ++it) {
  460.         const VDUIWindowClassNode& node = *it;
  461.  
  462.         if (node.mClassID == classID)
  463.             return node.mpCreator();
  464.     }
  465.  
  466.     return NULL;
  467. }
  468.