ShaderEditorDlg.cpp

00001 // ShaderEditorDlg.cpp : implementation file
00002 //
00003 
00004 #include "stdafx.h"
00005 #include "mplayerc.h"
00006 #include "PixelShaderCompiler.h"
00007 #include "ShaderEditorDlg.h"
00008 
00009 #undef SubclassWindow
00010 
00011 
00012 // CShaderLabelComboBox
00013 
00014 BEGIN_MESSAGE_MAP(CShaderLabelComboBox, CComboBox)
00015         ON_WM_CTLCOLOR()
00016         ON_WM_DESTROY()
00017 END_MESSAGE_MAP()
00018 
00019 HBRUSH CShaderLabelComboBox::OnCtlColor(CDC* pDC, CWnd* pWnd, UINT nCtlColor)
00020 {
00021         if(nCtlColor == CTLCOLOR_EDIT)
00022         {
00023                 if(m_edit.GetSafeHwnd() == NULL)
00024             m_edit.SubclassWindow(pWnd->GetSafeHwnd());
00025         }
00026 
00027         return __super::OnCtlColor(pDC, pWnd, nCtlColor);
00028 }
00029 
00030 void CShaderLabelComboBox::OnDestroy()
00031 {
00032         if(m_edit.GetSafeHwnd() != NULL)
00033                 m_edit.UnsubclassWindow();
00034 
00035         __super::OnDestroy();
00036 }
00037 
00038 // CShaderEdit
00039 
00040 CShaderEdit::CShaderEdit()
00041 {
00042         m_acdlg.Create(CShaderAutoCompleteDlg::IDD, NULL);
00043 
00044         m_nEndChar = -1;
00045         m_nIDEvent = -1;
00046 }
00047 
00048 CShaderEdit::~CShaderEdit()
00049 {
00050         m_acdlg.DestroyWindow();
00051 }
00052 
00053 BOOL CShaderEdit::PreTranslateMessage(MSG* pMsg)
00054 {
00055         if(m_acdlg.IsWindowVisible() 
00056                 && pMsg->message == WM_KEYDOWN 
00057                 && (pMsg->wParam == VK_UP || pMsg->wParam == VK_DOWN
00058                 || pMsg->wParam == VK_PRIOR || pMsg->wParam == VK_NEXT
00059                 || pMsg->wParam == VK_RETURN || pMsg->wParam == VK_ESCAPE))
00060         {
00061                 int i = m_acdlg.m_list.GetCurSel();
00062 
00063                 if(pMsg->wParam == VK_RETURN && i >= 0)
00064                 {
00065                         CString str;
00066                         m_acdlg.m_list.GetText(i, str);
00067                         i = str.Find('(')+1;
00068                         if(i > 0) str = str.Left(i);
00069                         
00070                         int nStartChar = 0, nEndChar = -1;
00071                         GetSel(nStartChar, nEndChar);
00072 
00073                         CString text;
00074                         GetWindowText(text);
00075                         while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
00076                                 nStartChar--;
00077 
00078                         SetSel(nStartChar, nEndChar);
00079                         ReplaceSel(str, TRUE);
00080                 }
00081                 else if(pMsg->wParam == VK_ESCAPE)
00082                 {
00083                         m_acdlg.ShowWindow(SW_HIDE);
00084                 }
00085                 else
00086                 {
00087                         m_acdlg.m_list.SendMessage(pMsg->message, pMsg->wParam, pMsg->lParam);
00088                 }
00089 
00090                 return TRUE;
00091         }
00092 
00093         return __super::PreTranslateMessage(pMsg);
00094 }
00095 
00096 BEGIN_MESSAGE_MAP(CShaderEdit, CLineNumberEdit)
00097         ON_CONTROL_REFLECT(EN_UPDATE, OnUpdate)
00098         ON_WM_KILLFOCUS()
00099         ON_WM_TIMER()
00100 END_MESSAGE_MAP()
00101 
00102 void CShaderEdit::OnUpdate()
00103 {
00104         if(m_nIDEvent == -1)
00105         {
00106                 m_nIDEvent = SetTimer(1, 100, NULL); 
00107         }
00108 
00109         CString text;
00110         int nStartChar = 0, nEndChar = -1;
00111         GetSel(nStartChar, nEndChar);
00112 
00113         if(nStartChar == nEndChar)
00114         {
00115                 GetWindowText(text);
00116                 while(nStartChar > 0 && _istalnum(text.GetAt(nStartChar-1)))
00117                         nStartChar--;
00118         }
00119 
00120         if(nStartChar < nEndChar)
00121         {
00122                 text = text.Mid(nStartChar, nEndChar - nStartChar);
00123                 text.TrimRight('(');
00124                 text.MakeLower();
00125 
00126                 m_acdlg.m_list.ResetContent();
00127 
00128                 CString key, value;
00129                 POSITION pos = m_acdlg.m_inst.GetStartPosition();
00130                 while(pos)
00131                 {
00132                         POSITION cur = pos;
00133                         m_acdlg.m_inst.GetNextAssoc(pos, key, value);
00134 
00135                         if(key.Find(text) == 0)
00136                         {
00137                                 CList<CString> sl;
00138                                 Explode(value, sl, '|', 2);
00139                                 if(sl.GetCount() != 2) continue;
00140                                 CString name = sl.RemoveHead();
00141                                 CString description = sl.RemoveHead();
00142                                 int i = m_acdlg.m_list.AddString(name);
00143                                 m_acdlg.m_list.SetItemDataPtr(i, cur);
00144                         }
00145                 }
00146 
00147                 if(m_acdlg.m_list.GetCount() > 0)
00148                 {
00149                         int lineheight = GetLineHeight();
00150 
00151                         CPoint p = PosFromChar(nStartChar);
00152                         p.y += lineheight;
00153                         ClientToScreen(&p);
00154                         CRect r(p, CSize(100, 100));
00155 
00156                         m_acdlg.MoveWindow(r);
00157                         m_acdlg.SetWindowPos(&wndTopMost, 0, 0, 0, 0, SWP_NOMOVE|SWP_NOSIZE|SWP_NOACTIVATE);
00158                         m_acdlg.ShowWindow(SW_SHOWNOACTIVATE);
00159 
00160                         m_nEndChar = nEndChar;
00161 
00162                         return;
00163                 }
00164         }
00165 
00166         m_acdlg.ShowWindow(SW_HIDE);
00167 }
00168 
00169 void CShaderEdit::OnKillFocus(CWnd* pNewWnd)
00170 {
00171         CString text;
00172         GetWindowText(text);
00173         __super::OnKillFocus(pNewWnd);
00174         GetWindowText(text);
00175 
00176         m_acdlg.ShowWindow(SW_HIDE);
00177 }
00178 
00179 void CShaderEdit::OnTimer(UINT nIDEvent)
00180 {
00181         if(m_nIDEvent == nIDEvent)
00182         {
00183                 int nStartChar = 0, nEndChar = -1;
00184                 GetSel(nStartChar, nEndChar);
00185                 if(nStartChar != nEndChar || m_nEndChar != nEndChar)
00186                         m_acdlg.ShowWindow(SW_HIDE);
00187         }
00188 
00189         __super::OnTimer(nIDEvent);
00190 }
00191 
00192 // CShaderEditorDlg dialog
00193 
00194 CShaderEditorDlg::CShaderEditorDlg(CString label, ISubPicAllocatorPresenter* pCAP, CWnd* pParent /*=NULL*/)
00195         : CResizableDialog(CShaderEditorDlg::IDD, pParent)
00196         , m_label(label)
00197         , m_pCAP(pCAP)
00198         , m_fSplitterGrabbed(false)
00199 {
00200         m_pPSC = new CPixelShaderCompiler(NULL);
00201 }
00202 
00203 CShaderEditorDlg::~CShaderEditorDlg()
00204 {
00205         delete m_pPSC;
00206 }
00207 
00208 void CShaderEditorDlg::DoDataExchange(CDataExchange* pDX)
00209 {
00210         __super::DoDataExchange(pDX);
00211         DDX_Control(pDX, IDC_COMBO1, m_labels);
00212         DDX_Control(pDX, IDC_COMBO2, m_targets);
00213         DDX_Control(pDX, IDC_EDIT1, m_srcdata);
00214         DDX_Control(pDX, IDC_EDIT2, m_output);
00215 }
00216 
00217 bool CShaderEditorDlg::HitTestSplitter(CPoint p)
00218 {
00219         CRect r, rs, ro;
00220         m_srcdata.GetWindowRect(&rs);
00221         m_output.GetWindowRect(&ro);
00222         ScreenToClient(&rs);
00223         ScreenToClient(&ro);
00224         GetClientRect(&r);
00225         r.left = ro.left;
00226         r.right = ro.right;
00227         r.top = rs.bottom;
00228         r.bottom = ro.top;
00229         return !!r.PtInRect(p);
00230 }
00231 
00232 BEGIN_MESSAGE_MAP(CShaderEditorDlg, CResizableDialog)
00233         ON_CBN_SELCHANGE(IDC_COMBO1, OnCbnSelchangeCombo1)
00234         ON_BN_CLICKED(IDC_BUTTON1, OnBnClickedButton1)
00235         ON_BN_CLICKED(IDC_BUTTON2, OnBnClickedButton2)
00236         ON_WM_TIMER()
00237         ON_WM_CLOSE()
00238         ON_WM_LBUTTONDOWN()
00239         ON_WM_LBUTTONUP()
00240         ON_WM_MOUSEMOVE()
00241         ON_WM_SETCURSOR()
00242 END_MESSAGE_MAP()
00243 
00244 
00245 // CShaderEditorDlg message handlers
00246 
00247 BOOL CShaderEditorDlg::OnInitDialog()
00248 {
00249         __super::OnInitDialog();
00250 
00251         AddAnchor(IDC_COMBO1, TOP_LEFT, TOP_RIGHT);
00252         AddAnchor(IDC_COMBO2, TOP_RIGHT);
00253         AddAnchor(IDC_BUTTON1, TOP_RIGHT);
00254         AddAnchor(IDC_BUTTON2, TOP_RIGHT);
00255         AddAnchor(IDC_EDIT1, TOP_LEFT, BOTTOM_RIGHT);
00256         AddAnchor(IDC_EDIT2, BOTTOM_LEFT, BOTTOM_RIGHT);
00257 
00258         m_srcdata.SetTabStops(16);
00259 
00260         CRect r;
00261         GetWindowRect(r);
00262         CSize s = r.Size();
00263         s.cx = 400;
00264         s.cy = 150;
00265         SetMinTrackSize(s);
00266 
00267         CMap<CString, LPCTSTR, bool, bool> targetmap;
00268         targetmap[_T("ps_1_1")] = true;
00269         targetmap[_T("ps_1_2")] = true;
00270         targetmap[_T("ps_1_3")] = true;
00271         targetmap[_T("ps_1_4")] = true;
00272         targetmap[_T("ps_2_0")] = true;
00273         targetmap[_T("ps_2_a")] = true;
00274         targetmap[_T("ps_2_sw")] = true;
00275         targetmap[_T("ps_3_0")] = true;
00276         targetmap[_T("ps_3_sw")] = true;
00277 
00278         int nSelIndex = -1;
00279 
00280         for(int i = 0; ; i++)
00281         {
00282                 CString str;
00283                 str.Format(_T("%d"), i);
00284                 str = AfxGetApp()->GetProfileString(_T("Shaders"), str);
00285 
00286                 CList<CString> sl;
00287                 Explode(str, sl, '|', 3);
00288                 if(sl.GetCount() != 3) break;
00289 
00290                 CString label = sl.RemoveHead();
00291                 CString target = sl.RemoveHead();
00292                 CString srcdata = sl.RemoveHead();
00293                 srcdata.Replace(_T("\\n"), _T("\r\n"));
00294                 srcdata.Replace(_T("\\t"), _T("\t"));
00295 
00296                 targetmap[target] = false;
00297 
00298                 shader_t s = {target, srcdata};
00299                 m_shaders[label] = s;
00300 
00301                 int nIndex = m_labels.AddString(label);
00302 
00303                 if(m_label == label) 
00304                         nSelIndex = nIndex;
00305         }
00306 
00307         m_labels.SetCurSel(nSelIndex);
00308 
00309         POSITION pos = targetmap.GetStartPosition();
00310         while(pos) 
00311         {
00312                 CString target;
00313                 bool b;
00314                 targetmap.GetNextAssoc(pos, target, b);
00315                 m_targets.AddString(target);
00316         }
00317 
00318         OnCbnSelchangeCombo1();
00319 
00320         m_nIDEventShader = SetTimer(1, 1000, NULL);
00321 
00322         return TRUE;  // return TRUE unless you set the focus to a control
00323         // EXCEPTION: OCX Property Pages should return FALSE
00324 }
00325 
00326 BOOL CShaderEditorDlg::PreTranslateMessage(MSG* pMsg)
00327 {
00328         if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_RETURN
00329                 && pMsg->hwnd == m_labels.m_edit.GetSafeHwnd())
00330         {
00331                 CString label;
00332                 m_labels.GetWindowText(label);
00333 
00334                 shader_t s;
00335                 m_labels.SetCurSel(!m_shaders.Lookup(label, s) 
00336                         ? m_labels.AddString(label) 
00337                         : m_labels.FindStringExact(0, label));
00338 
00339                 OnCbnSelchangeCombo1();
00340         
00341                 return TRUE;
00342         }
00343         else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_TAB
00344                 && pMsg->hwnd == m_srcdata.GetSafeHwnd())
00345         {
00346                 int nStartChar, nEndChar;
00347                 m_srcdata.GetSel(nStartChar, nEndChar);
00348 
00349                 if(nStartChar == nEndChar)
00350             m_srcdata.ReplaceSel(_T("\t"));
00351 
00352                 return TRUE;
00353         }
00354         else if(pMsg->message == WM_KEYDOWN && pMsg->wParam == VK_ESCAPE)
00355         {
00356                 return TRUE;
00357         }
00358 
00359         return __super::PreTranslateMessage(pMsg);
00360 }
00361 
00362 void CShaderEditorDlg::OnCbnSelchangeCombo1()
00363 {
00364         int i = m_labels.GetCurSel();
00365         if(i < 0) return;
00366         CString label;
00367         m_labels.GetLBText(i, label);
00368         if(label.IsEmpty()) return;
00369 
00370         shader_t s;
00371 
00372         if(!m_shaders.Lookup(label, s))
00373         {
00374                 s.target = _T("ps_2_0");
00375                 s.srcdata = 
00376             "sampler s0 : register(s0);\r\n"
00377                         "float4 p0 : register(c0);\r\n"
00378             "\r\n"
00379                         "#define width (p0[0])\r\n"
00380                         "#define height (p0[1])\r\n"
00381                         "#define counter (p0[2])\r\n"
00382             "#define clock (p0[3])\r\n"
00383                         "\r\n"
00384                         "float4 main(float2 tex : TEXCOORD0) : COLOR\r\n"
00385                         "{\r\n"
00386                         "\tfloat4 c0 = tex2D(s0, tex);\r\n"
00387                         "\t// TODO\r\n"
00388                         "\treturn c0;\r\n"
00389                         "}\r\n";
00390                 m_shaders[label] = s;
00391         }
00392 
00393         if(m_shaders.Lookup(label, s))
00394         {
00395                 m_targets.SetWindowText(s.target);
00396                 m_srcdata.SetWindowText(s.srcdata);
00397         }
00398 }
00399 
00400 void CShaderEditorDlg::OnBnClickedButton1()
00401 {
00402         CString label;
00403         m_labels.GetWindowText(label);
00404         int nIndex = m_labels.FindStringExact(0, label);
00405         if(nIndex >= 0) m_labels.DeleteString(nIndex);
00406         m_labels.SetWindowText(_T(""));
00407         m_targets.SetWindowText(_T(""));
00408         m_srcdata.SetWindowText(_T(""));
00409         m_shaders.RemoveKey(label);
00410 }
00411 
00412 void CShaderEditorDlg::OnBnClickedButton2()
00413 {
00414         CString label;
00415         m_labels.GetWindowText(label);
00416         m_targets.GetWindowText(m_shaders[label].target);
00417         m_srcdata.GetWindowText(m_shaders[label].srcdata);
00418         if(m_labels.FindStringExact(0, label) < 0)
00419                 m_labels.SetCurSel(m_labels.AddString(label));
00420 }
00421 
00422 void CShaderEditorDlg::OnTimer(UINT nIDEvent)
00423 {
00424         if(nIDEvent == m_nIDEventShader)
00425         {
00426                 static CString s_srcdata, s_target;
00427                 
00428                 CString srcdata;
00429                 m_srcdata.GetWindowText(srcdata);
00430                 srcdata.Trim();
00431 
00432                 CString target;
00433                 m_targets.GetWindowText(target);
00434                 target.Trim();
00435 
00436                 if(!srcdata.IsEmpty() && !target.IsEmpty() && (s_srcdata != srcdata || s_target != target))
00437                 {
00438                         CString disasm, errmsg(_T("Unknown Error"));
00439 
00440                         HRESULT hr = m_pPSC->CompileShader(CStringA(srcdata), "main", CStringA(target), D3DXSHADER_DEBUG, NULL, &disasm, &errmsg); 
00441 
00442                         if(SUCCEEDED(hr))
00443                         {
00444                                 errmsg = _T("D3DXCompileShader succeeded\n");
00445                                 if(m_pCAP && FAILED(m_pCAP->SetPixelShader(CStringA(srcdata), CStringA(target))))
00446                                         errmsg += _T("SetPixelShader failed\n");
00447                                 errmsg += _T("\n");
00448                                 errmsg += disasm;
00449                         }
00450 
00451                         errmsg.Replace(_T("\n"), _T("\r\n"));
00452 
00453                         m_output.SetWindowText(errmsg);
00454                 }
00455 
00456                 s_srcdata = srcdata;
00457                 s_target = target;
00458         }
00459 
00460         __super::OnTimer(nIDEvent);
00461 }
00462 
00463 void CShaderEditorDlg::OnClose()
00464 {
00465         if(IDYES == AfxMessageBox(_T("Save changes?"), MB_YESNO))
00466         {
00467                 OnBnClickedButton2();
00468 
00469                 CWinApp* pApp = AfxGetApp();
00470 
00471                 pApp->WriteProfileString(_T("Shaders"), NULL, NULL);
00472                 pApp->WriteProfileInt(_T("Shaders"), _T("Initialized"), 1);
00473 
00474                 for(int i = 0, id = 0; i < m_labels.GetCount(); i++)
00475                 {
00476                         CString label;
00477                         m_labels.GetLBText(i, label);
00478 
00479                         shader_t s;
00480                         if(!label.IsEmpty() && m_shaders.Lookup(label, s))
00481                         {
00482                                 CString str;
00483                                 str.Format(_T("%d"), id++);
00484                                 s.srcdata.Replace(_T("\r"), _T(""));
00485                                 s.srcdata.Replace(_T("\n"), _T("\\n"));
00486                                 s.srcdata.Replace(_T("\t"), _T("\\t"));
00487                                 AfxGetApp()->WriteProfileString(_T("Shaders"), str, label + _T("|") + s.target + _T("|") + s.srcdata);
00488                         }
00489                 }
00490         }
00491 
00492         __super::OnClose();
00493 }
00494 
00495 void CShaderEditorDlg::OnLButtonDown(UINT nFlags, CPoint point)
00496 {
00497         if(HitTestSplitter(point))
00498         {
00499                 m_fSplitterGrabbed = true;
00500                 SetCapture();
00501         }
00502         
00503         __super::OnLButtonDown(nFlags, point);
00504 }
00505 
00506 void CShaderEditorDlg::OnLButtonUp(UINT nFlags, CPoint point)
00507 {
00508         if(m_fSplitterGrabbed)
00509         {
00510                 ReleaseCapture();
00511                 m_fSplitterGrabbed = false;
00512         }
00513 
00514         __super::OnLButtonUp(nFlags, point);
00515 }
00516 
00517 void CShaderEditorDlg::OnMouseMove(UINT nFlags, CPoint point)
00518 {
00519         if(m_fSplitterGrabbed)
00520         {
00521                 CRect r, rs, ro;
00522                 GetClientRect(&r);
00523                 m_srcdata.GetWindowRect(&rs);
00524                 m_output.GetWindowRect(&ro);
00525                 ScreenToClient(&rs);
00526                 ScreenToClient(&ro);
00527 
00528                 int dist = ro.top - rs.bottom;
00529                 int avgdist = dist / 2;
00530 
00531                 rs.bottom = min(max(point.y, rs.top + 40), ro.bottom - 40) - avgdist;
00532                 ro.top = rs.bottom + dist;
00533                 m_srcdata.MoveWindow(&rs);
00534                 m_output.MoveWindow(&ro);
00535 
00536                 int div = 100 * ((rs.bottom + ro.top) / 2) / (ro.bottom - rs.top);
00537 
00538                 RemoveAnchor(IDC_EDIT1);
00539                 RemoveAnchor(IDC_EDIT2);
00540                 AddAnchor(IDC_EDIT1, TOP_LEFT, CSize(100, div)/*BOTTOM_RIGHT*/);
00541                 AddAnchor(IDC_EDIT2, CSize(0, div)/*BOTTOM_LEFT*/, BOTTOM_RIGHT);
00542         }
00543 
00544         __super::OnMouseMove(nFlags, point);
00545 }
00546 
00547 BOOL CShaderEditorDlg::OnSetCursor(CWnd* pWnd, UINT nHitTest, UINT message)
00548 {
00549         CPoint p;
00550         GetCursorPos(&p);
00551         ScreenToClient(&p);
00552         if(HitTestSplitter(p))
00553         {
00554                 ::SetCursor(AfxGetApp()->LoadStandardCursor(IDC_SIZENS));
00555                 return TRUE;
00556         }
00557 
00558         return __super::OnSetCursor(pWnd, nHitTest, message);
00559 }
00560 

Generated on Tue Dec 13 14:47:04 2005 for guliverkli by  doxygen 1.4.5