Пример #1
0
void ezQtTestGUI::on_actionRunTests_triggered()
{
  m_pTestFramework->SaveTestOrder();
  m_pModel->InvalidateAll();
  m_bExpandedCurrentTest = false;
  m_bAbort = false;
  m_pMessageLogDock->currentTestResultChanged(nullptr);

  m_pStatusTextWorkState->setText("<p><span style=\"font-weight:600; color:#ff5500;\" >  [Working...]</span></p>");

  // make sure we start with a clean state
  m_pTestFramework->ResetTests();

  while (m_pTestFramework->RunTestExecutionLoop() == ezTestAppRun::Continue)
  {
    UpdateButtonStates();

    if (m_bAbort)
    {
      m_pTestFramework->AbortTests();
    }
  }

  UpdateButtonStates();
  m_pMessageLogDock->currentTestResultChanged(nullptr);

  // MessageBox
  if (m_bAbort)
  {
    m_pStatusTextWorkState->setText("<p><span style=\"font-weight:600; color:#ff0000;\">  [Tests Aborted]</span></p>");

    if (m_pTestFramework->GetSettings().m_bShowMessageBox)
      QMessageBox::information(this, "Tests Aborted", "The tests were aborted by the user.", QMessageBox::Ok, QMessageBox::Ok);

    m_bAbort = false;
  }
  else
  {
    if (m_pTestFramework->GetTotalErrorCount() > 0)
    {
      m_pStatusTextWorkState->setText("<p><span style=\"font-weight:600; color:#ff0000;\">  [Tests Failed]</span></p>");

      if (m_pTestFramework->GetSettings().m_bShowMessageBox)
        QMessageBox::critical(this, "Tests Failed", "Some tests have failed.", QMessageBox::Ok, QMessageBox::Ok);
    }
    else
    {
      m_pStatusTextWorkState->setText("<p><span style=\"font-weight:600; color:#00aa00;\">  [All Tests Passed]</span></p>");

      if (m_pTestFramework->GetSettings().m_bShowMessageBox)
        QMessageBox::information(this, "Tests Succeeded", "All tests succeeded.", QMessageBox::Ok, QMessageBox::Ok);

      if (m_pTestFramework->GetSettings().m_bCloseOnSuccess)
        QTimer::singleShot(100, this, SLOT(on_actionQuit_triggered()));
    }
  }
}
Пример #2
0
// The Play, Stop, Step, Skip, Go to PC and Show PC buttons go here
void CCodeWindow::OnCodeStep(wxCommandEvent& event)
{
	switch (event.GetId())
	{
		case IDM_STEP:
			SingleStep();
			break;

		case IDM_STEPOVER:
			StepOver();
			break;

		case IDM_TOGGLE_BREAKPOINT:
			ToggleBreakpoint();
			break;

		case IDM_SKIP:
			PC += 4;
			Update();
			break;

		case IDM_SETPC:
			PC = codeview->GetSelection();
			Update();
			break;

		case IDM_GOTOPC:
			JumpToAddress(PC);
			break;
	}

	UpdateButtonStates();
	// Update all toolbars in the aui manager
	Parent->UpdateGUI();
}
Пример #3
0
// CPU Mode and JIT Menu
void CCodeWindow::OnCPUMode(wxCommandEvent& event)
{
	switch (event.GetId())
	{
		case IDM_INTERPRETER:
			PowerPC::SetMode(UseInterpreter() ? PowerPC::MODE_INTERPRETER : PowerPC::MODE_JIT);
			break;
		case IDM_BOOTTOPAUSE:
			bBootToPause = !bBootToPause;
			return;
		case IDM_AUTOMATICSTART:
			bAutomaticStart = !bAutomaticStart;
			return;
		case IDM_JITOFF:
			Core::g_CoreStartupParameter.bJITOff = event.IsChecked();
			break;
		case IDM_JITLSOFF:
			Core::g_CoreStartupParameter.bJITLoadStoreOff = event.IsChecked();
			break;
		case IDM_JITLSLXZOFF:
			Core::g_CoreStartupParameter.bJITLoadStorelXzOff = event.IsChecked();
			break;
		case IDM_JITLSLWZOFF:
			Core::g_CoreStartupParameter.bJITLoadStorelwzOff = event.IsChecked();
			break;
		case IDM_JITLSLBZXOFF:
			Core::g_CoreStartupParameter.bJITLoadStorelbzxOff = event.IsChecked();
			break;
		case IDM_JITLSFOFF:
			Core::g_CoreStartupParameter.bJITLoadStoreFloatingOff = event.IsChecked();
			break;
		case IDM_JITLSPOFF:
			Core::g_CoreStartupParameter.bJITLoadStorePairedOff = event.IsChecked();
			break;
		case IDM_JITFPOFF:
			Core::g_CoreStartupParameter.bJITFloatingPointOff = event.IsChecked();
			break;
		case IDM_JITIOFF:
			Core::g_CoreStartupParameter.bJITIntegerOff = event.IsChecked();
			break;
		case IDM_JITPOFF:
			Core::g_CoreStartupParameter.bJITPairedOff = event.IsChecked();
			break;
		case IDM_JITSROFF:
			Core::g_CoreStartupParameter.bJITSystemRegistersOff = event.IsChecked();
			break;
	}

	// Clear the JIT cache to enable these changes
	JitInterface::ClearCache();

	// Update
	UpdateButtonStates();
}
Пример #4
0
// CPU Mode and JIT Menu
void CCodeWindow::OnCPUMode(wxCommandEvent& event)
{
	switch (event.GetId())
	{
		case IDM_INTERPRETER:
			PowerPC::SetMode(UseInterpreter() ? PowerPC::MODE_INTERPRETER : PowerPC::MODE_JIT);
			break;
		case IDM_BOOT_TO_PAUSE:
			bBootToPause = !bBootToPause;
			return;
		case IDM_AUTOMATIC_START:
			bAutomaticStart = !bAutomaticStart;
			return;
		case IDM_JIT_OFF:
			SConfig::GetInstance().bJITOff = event.IsChecked();
			break;
		case IDM_JIT_LS_OFF:
			SConfig::GetInstance().bJITLoadStoreOff = event.IsChecked();
			break;
		case IDM_JIT_LSLXZ_OFF:
			SConfig::GetInstance().bJITLoadStorelXzOff = event.IsChecked();
			break;
		case IDM_JIT_LSLWZ_OFF:
			SConfig::GetInstance().bJITLoadStorelwzOff = event.IsChecked();
			break;
		case IDM_JIT_LSLBZX_OFF:
			SConfig::GetInstance().bJITLoadStorelbzxOff = event.IsChecked();
			break;
		case IDM_JIT_LSF_OFF:
			SConfig::GetInstance().bJITLoadStoreFloatingOff = event.IsChecked();
			break;
		case IDM_JIT_LSP_OFF:
			SConfig::GetInstance().bJITLoadStorePairedOff = event.IsChecked();
			break;
		case IDM_JIT_FP_OFF:
			SConfig::GetInstance().bJITFloatingPointOff = event.IsChecked();
			break;
		case IDM_JIT_I_OFF:
			SConfig::GetInstance().bJITIntegerOff = event.IsChecked();
			break;
		case IDM_JIT_P_OFF:
			SConfig::GetInstance().bJITPairedOff = event.IsChecked();
			break;
		case IDM_JIT_SR_OFF:
			SConfig::GetInstance().bJITSystemRegistersOff = event.IsChecked();
			break;
	}

	// Clear the JIT cache to enable these changes
	JitInterface::ClearCache();

	// Update
	UpdateButtonStates();
}
Пример #5
0
void PlayIndicatorOverlayBase::Draw(OverlayPanel &panel, wxDC &dc)
{
   // Set play/record color
   bool rec = gAudioIO->IsCapturing();
   AColor::IndicatorColor(&dc, !rec);

   if (mIsMaster
       && mLastIsCapturing != mNewIsCapturing) {
      // Detect transition to recording during punch and roll; make ruler
      // change its button color too
      const auto ruler = mProject->GetRulerPanel();
      ruler->UpdateButtonStates();
      ruler->Refresh();
   }
   mLastIsCapturing = mNewIsCapturing;

   mLastIndicatorX = mNewIndicatorX;
   if (!between_incexc(0, mLastIndicatorX, dc.GetSize().GetWidth()))
      return;

   if(auto tp = dynamic_cast<TrackPanel*>(&panel)) {
      wxASSERT(mIsMaster);

      // Draw indicator in all visible tracks
      for ( const auto &data : tp->Cells() )
      {
         Track *const pTrack = dynamic_cast<Track*>(data.first.get());
         if (!pTrack)
            continue;

         // Don't draw the indicator in label tracks
         if (pTrack->GetKind() == Track::Label)
         {
            continue;
         }

         // Draw the NEW indicator in its NEW location
         // AColor::Line includes both endpoints so use GetBottom()
         const wxRect &rect = data.second;
         AColor::Line(dc,
                      mLastIndicatorX,
                      rect.GetTop(),
                      mLastIndicatorX,
                      rect.GetBottom());
      }
   }
   else if(auto ruler = dynamic_cast<AdornedRulerPanel*>(&panel)) {
      wxASSERT(!mIsMaster);

      ruler->DoDrawIndicator(&dc, mLastIndicatorX, !rec, IndicatorMediumWidth, false, false);
   }
   else
      wxASSERT(false);
}
Пример #6
0
// Update GUI
void CCodeWindow::Update()
{
	if (!codeview) return;

	codeview->Refresh();
	UpdateCallstack();
	UpdateButtonStates();

	// Do not automatically show the current PC position when a breakpoint is hit or
	// when we pause since this can be called at other times too.
	//codeview->Center(PC);
}
Пример #7
0
void CCodeWindow::StepOut()
{
	if (CPU::IsStepping())
	{
		PowerPC::breakpoints.ClearAllTemporary();

		// Keep stepping until the next blr or timeout after one second
		u64 timeout = SystemTimers::GetTicksPerSecond();
		u64 steps = 0;
		PowerPC::CoreMode oldMode = PowerPC::GetMode();
		PowerPC::SetMode(PowerPC::MODE_INTERPRETER);
		UGeckoInstruction inst = PowerPC::HostRead_Instruction(PC);
		while (inst.hex != 0x4e800020 && steps < timeout) // check for blr
		{
			if (inst.LK)
			{
				// Step over branches
				u32 next_pc = PC + 4;
				while (PC != next_pc && steps < timeout)
				{
					PowerPC::SingleStep();
					++steps;
				}
			}
			else
			{
				PowerPC::SingleStep();
				++steps;
			}
			inst = PowerPC::HostRead_Instruction(PC);
		}

		PowerPC::SingleStep();
		PowerPC::SetMode(oldMode);

		JumpToAddress(PC);
		Update();

		UpdateButtonStates();
		// Update all toolbars in the aui manager
		Parent->UpdateGUI();
	}
}
Пример #8
0
void CCodeWindow::StepOver()
{
	if (CCPU::IsStepping())
	{
		UGeckoInstruction inst = Memory::Read_Instruction(PC);
		if (inst.LK)
		{
			PowerPC::breakpoints.Add(PC + 4, true);
			CCPU::EnableStepping(false);
			JumpToAddress(PC);
			Update();
		}
		else
			SingleStep();

		UpdateButtonStates();
		// Update all toolbars in the aui manager
		Parent->UpdateGUI();
	}
}
Пример #9
0
ezQtTestGUI::ezQtTestGUI(ezQtTestFramework& testFramework)
  : QMainWindow(), m_pTestFramework(&testFramework), m_pModel(nullptr), m_bExpandedCurrentTest(false), m_bAbort(false)
{
  this->setupUi(this);
  this->setWindowTitle(testFramework.GetTestName());

  QCoreApplication::setOrganizationDomain("www.ezengine.net");
  QCoreApplication::setOrganizationName("ezEngine Project");
  QCoreApplication::setApplicationName("ezTestFramework");
  QCoreApplication::setApplicationVersion("1.0.0");

  // Status Bar
  m_pStatusTextWorkState = new QLabel(this);
  testStatusBar->addWidget(m_pStatusTextWorkState);

  m_pStatusText = new QLabel(this);
  testStatusBar->addWidget(m_pStatusText);


  // Model
  m_pModel = new ezQtTestModel(this, m_pTestFramework);
  testTreeView->setModel(m_pModel);

  // Delegate
  m_pDelegate = new ezQtTestDelegate(this);

  // View
  //testTreeView->expandAll();
  testTreeView->resizeColumnToContents(4);
  testTreeView->resizeColumnToContents(3);
  testTreeView->resizeColumnToContents(2);
  testTreeView->resizeColumnToContents(1);
  testTreeView->resizeColumnToContents(0);
  testTreeView->header()->setStretchLastSection(true);
  testTreeView->setContextMenuPolicy(Qt::CustomContextMenu);
  testTreeView->setUniformRowHeights(true);
  testTreeView->setItemDelegate(m_pDelegate);
  testTreeView->setSelectionMode(QAbstractItemView::SingleSelection);
  testTreeView->setSelectionBehavior(QAbstractItemView::SelectRows);

  // Message Log Dock
  m_pMessageLogDock = new ezQtLogMessageDock(this, &m_pTestFramework->GetTestResult());
  addDockWidget(Qt::RightDockWidgetArea, m_pMessageLogDock);

  // connect custom context menu
  connect(testTreeView, SIGNAL( customContextMenuRequested(const QPoint&) ), this, SLOT( onTestTreeViewCustomContextMenuRequested(const QPoint&) ));

  // connect current row changed signal
  QItemSelectionModel* pSelectionModel = testTreeView->selectionModel();
  connect(pSelectionModel, SIGNAL( currentRowChanged(const QModelIndex&, const QModelIndex&) ), this, SLOT( onSelectionModelCurrentRowChanged(const QModelIndex&) ));

  // Sync actions with test framework settings
  TestSettings settings = m_pTestFramework->GetSettings();
  this->actionAssertOnTestFail->setChecked(settings.m_bAssertOnTestFail);
  this->actionOpenHTMLOutput->setChecked(settings.m_bOpenHtmlOutput);
  this->actionKeepConsoleOpen->setChecked(settings.m_bKeepConsoleOpen);
  this->actionShowMessageBox->setChecked(settings.m_bShowMessageBox);

  // Hide the Windows console
#if EZ_ENABLED(EZ_PLATFORM_WINDOWS)
  if (!settings.m_bKeepConsoleOpen)
    ShowWindow(GetConsoleWindow(), SW_HIDE);
#endif

  connect(m_pTestFramework, SIGNAL( TestResultReceived(qint32, qint32) ), this, SLOT( onTestFrameworkTestResultReceived(qint32, qint32) ) );

  UpdateButtonStates();
  LoadGUILayout();

  if (testFramework.GetSettings().m_bRunTests)
  {
    QTimer::singleShot(10, this, SLOT(on_actionRunTests_triggered()));
  }
}
Пример #10
0
LRESULT MusicBrowserUI::TreeViewWndProc(HWND hwnd, 
                                        UINT msg, 
                                        WPARAM wParam, 
                                        LPARAM lParam)
{
    WNDPROC lpOldProc = (WNDPROC)GetProp(hwnd, "oldproc" );
    static bool dragging = false;
    static RECT dragRect;
    static HTREEITEM dragItem = NULL;
    static bool selectedOnMouseDown = false;

    //return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam );

	switch(msg)
	{
		case WM_DESTROY:   
		{
			//  Put back old window proc and
			SetWindowLong( hwnd, GWL_WNDPROC, (DWORD)lpOldProc );

			// remove window property
			RemoveProp( hwnd, "oldproc" ); 
            RemoveProp( hwnd, "this" ); 

			break;
        }

        case WM_MOUSEMOVE:
        {
            if(dragging)
            {
                if(wParam & MK_LBUTTON)
                {
                    POINT dragPt;

                    dragPt.x = LOWORD(lParam);
                    dragPt.y = HIWORD(lParam);

                    if( !PtInRect(&dragRect, dragPt) )
                    {
                        SetCapture(NULL);
                        dragging = false;

                        NM_TREEVIEW nm_treeview;

                        memset(&nm_treeview, 0x00, sizeof(NM_TREEVIEW));
                        
                        nm_treeview.hdr.code = TVN_BEGINDRAG;
                        nm_treeview.hdr.hwndFrom = hwnd;
                        nm_treeview.hdr.idFrom = GetWindowLong(hwnd, GWL_ID);

                        nm_treeview.itemNew.hItem = dragItem;
                        nm_treeview.itemNew.mask = TVIF_STATE|TVIF_PARAM;
                        nm_treeview.itemNew.stateMask = TVIS_BOLD|TVIS_CUT|TVIS_DROPHILITED|TVIS_EXPANDED|TVIS_SELECTED|TVIS_EXPANDEDONCE;
                        
                        TreeView_GetItem(hwnd, &nm_treeview.itemNew);

                        nm_treeview.ptDrag.x = LOWORD(lParam);
                        nm_treeview.ptDrag.y = HIWORD(lParam);

                        SendMessage(GetParent(hwnd), 
                                    WM_NOTIFY, 
                                    (WPARAM)nm_treeview.hdr.idFrom,
                                    (LPARAM)&nm_treeview);

                        return TRUE;
                    }
                }
            }

            break;
        }

        case WM_RBUTTONDOWN:
        {
            SetFocus(hwnd);

            HTREEITEM item;
            TV_HITTESTINFO hti;

            hti.pt.x = LOWORD(lParam);
            hti.pt.y = HIWORD(lParam);

            item = TreeView_HitTest(hwnd, &hti);  

            if(item && (hti.flags & TVHT_ONITEM))
            {
                HTREEITEM focusItem = TreeView_GetSelection(hwnd);
                TV_ITEM tv_item;

                tv_item.hItem = focusItem;
                tv_item.mask = TVIF_STATE;
                tv_item.stateMask = TVIS_SELECTED;

                TreeView_GetItem(hwnd, &tv_item);

                bool wasFocusSelected = (tv_item.state & TVIS_SELECTED) != 0;

                tv_item.hItem = item;
                tv_item.mask = TVIF_STATE;
                tv_item.stateMask = TVIS_SELECTED;

                TreeView_GetItem(hwnd, &tv_item);

                bool wasFocus = item == focusItem;
                bool wasSelected = (tv_item.state & TVIS_SELECTED) != 0;

                if(!wasSelected)
                {
                    // need to iterate all the items and 
                    // make sure they aren't selected
                    HTREEITEM rootItem = TreeView_GetRoot(hwnd);

                    if(rootItem)
                    {
                        do
                        {
                            tv_item.hItem = rootItem;
                            tv_item.mask = TVIF_STATE;
                            tv_item.stateMask = TVIS_SELECTED;
                            tv_item.state = 0;

                            TreeView_SetBranch(hwnd, &tv_item);
                        
                        }while(rootItem = TreeView_GetNextSibling(hwnd, rootItem));
                    }

                    // need to set this back cause windows won't
                    // set it if it is already the focus item and
                    // we just deselected it
                    if(wasSelected && wasFocus)
                    {
                        tv_item.hItem = focusItem;
                        tv_item.mask = TVIF_STATE;
                        tv_item.stateMask = TVIS_SELECTED;
                        tv_item.state = TVIS_SELECTED;

                        TreeView_SetItem(hwnd, &tv_item);
                    }
                }

                TreeView_Select(hwnd, item, TVGN_CARET);

                if(!wasFocus && wasFocusSelected && wasSelected)
                {
                    tv_item.hItem = focusItem;
                    tv_item.mask = TVIF_STATE;
                    tv_item.stateMask = TVIS_SELECTED;
                    tv_item.state = TVIS_SELECTED;

                    TreeView_SetItem(hwnd, &tv_item);
                }
            }

            //return TRUE;

            break;
        }

        case WM_RBUTTONUP:
        {
            break;
        }

        case WM_LBUTTONDBLCLK:
        {
            TV_ITEM tv_item;
            TV_HITTESTINFO tv_htinfo;

            KillTimer(hwnd, 1);

            //GetCursorPos(&tv_htinfo.pt);
            //ScreenToClient(m_hMusicView, &tv_htinfo.pt);
            tv_htinfo.pt.x =  LOWORD(lParam);
            tv_htinfo.pt.y =  HIWORD(lParam);


            if(TreeView_HitTest(m_hMusicView, &tv_htinfo) && 
			   (tv_htinfo.flags & TVHT_ONITEM))
            {
                tv_item.hItem = TreeView_GetSelection(m_hMusicView); 
                tv_item.mask = TVIF_PARAM | TVIF_HANDLE;
                tv_item.lParam = 0;

                TreeView_GetItem(m_hMusicView, &tv_item);

                TreeData* treedata = (TreeData*)tv_item.lParam;

                bool playNow;

                m_context->prefs->GetPrefBoolean(kPlayImmediatelyPref, &playNow);

                if(treedata && treedata->IsTrack())
                {
                    if(playNow && !m_pParent)
                    {
                        ClearPlaylistEvent();  
                    }

                    PlaylistItem *item;
            
                    item = new PlaylistItem(*treedata->m_pTrack);
                    m_plm->AddItem(item, false);
                } 
                else if(treedata && treedata->IsPlaylist())
                {
                    if(playNow && !m_pParent)
                    {
                        ClearPlaylistEvent();  
                    }

                    m_plm->ReadPlaylist(treedata->m_oPlaylistPath.c_str());
                }
                else if(treedata && treedata->IsPortable())
                {
                    EditPortablePlaylist(treedata->m_pPortable);
                }
                else if(treedata && treedata->IsStream())
                {
                    if(playNow && !m_pParent)
                    {
                        ClearPlaylistEvent();  
                    }

                    PlaylistItem *item;
            
                    item = new PlaylistItem(*treedata->m_pStream);
                    m_plm->AddItem(item, false);
                }
                else if(tv_htinfo.hItem == m_hNewPlaylistItem)
                {
                    NewPlaylist();
                }
                else if(tv_htinfo.hItem == m_hNewPortableItem)
                {
                    m_context->target->AcceptEvent(new ShowPreferencesEvent(3));
                }
                else if(tv_htinfo.hItem == m_hNewFavoritesItem)
                {
                    NewFavoriteEvent();
                }
            }
            break;
        }

        case WM_LBUTTONDOWN:
        {
            bool shiftKeyPressed = IsShiftDown();
            bool ctrlKeyPressed = IsCtrlDown();

            selectedOnMouseDown = false;

            SetFocus(hwnd);

            HTREEITEM item;
            TV_HITTESTINFO hti;

            hti.pt.x = LOWORD(lParam);
            hti.pt.y = HIWORD(lParam);

            int dx = GetSystemMetrics(SM_CXDRAG);
            int dy = GetSystemMetrics(SM_CYDRAG);

            dragRect.top = hti.pt.y - dy;
            dragRect.bottom = hti.pt.y + dy;
            dragRect.left = hti.pt.x - dx;
            dragRect.right = hti.pt.x + dx;
        
            item = TreeView_HitTest(hwnd, &hti);  

            if(item && (hti.flags & TVHT_ONITEM))
            {
                dragItem = item;

                HTREEITEM focusItem = TreeView_GetSelection(hwnd);
                TV_ITEM tv_item;

                tv_item.hItem = focusItem;
                tv_item.mask = TVIF_STATE;
                tv_item.stateMask = TVIS_SELECTED;

                TreeView_GetItem(hwnd, &tv_item);

                bool wasFocusSelected = (tv_item.state & TVIS_SELECTED) != 0;

                tv_item.hItem = item;
                tv_item.mask = TVIF_STATE;
                tv_item.stateMask = TVIS_SELECTED;

                TreeView_GetItem(hwnd, &tv_item);

                bool wasFocus = item == focusItem;
                bool wasSelected = (tv_item.state & TVIS_SELECTED) != 0;

                HTREEITEM rootItem = TreeView_GetRoot(hwnd);
                selectedOnMouseDown = wasSelected && (CountSelectedItems(rootItem) == 1);
                
                if(ctrlKeyPressed)
                {
                    /*TreeView_Select(hwnd, item, TVGN_CARET);

                    if(focusItem)
                    {
                        tv_item.hItem = focusItem;
                        tv_item.mask = TVIF_STATE;
                        tv_item.stateMask = TVIS_SELECTED;
                        tv_item.state = TVIS_SELECTED;

                        TreeView_SetItem(hwnd, &tv_item);
                    }*/

                    return TRUE;
                }
                else if(shiftKeyPressed)
                {
                    // need to iterate all the items and 
                    // make sure they aren't selected
                    HTREEITEM rootItem = TreeView_GetRoot(hwnd);

                    if(rootItem)
                    {
                        do
                        {
                            tv_item.hItem = rootItem;
                            tv_item.mask = TVIF_STATE;
                            tv_item.stateMask = TVIS_SELECTED;
                            tv_item.state = 0;

                            TreeView_SetBranch(hwnd, &tv_item);
                            
                        }while(rootItem = TreeView_GetNextSibling(hwnd, rootItem));
                    }

                    HTREEITEM topItem = NULL;
                    HTREEITEM bottomItem = NULL;
                    HTREEITEM dummyItem = NULL;

                    dummyItem = focusItem;

                    // which item is above the other? search downward first
                    while(dummyItem = TreeView_GetNextSibling(hwnd, dummyItem))
                    {
                        if(dummyItem == item)
                        {
                            topItem = focusItem;
                            bottomItem = item;
                            break;
                        }
                    }
                    
                    // did we find out? no? search upward next
                    if(!topItem)
                    {
                        dummyItem = focusItem;

                        // which item is above the other? search downward first
                        while(dummyItem = TreeView_GetPrevSibling(hwnd, dummyItem))
                        {
                            if(dummyItem == item)
                            {
                                topItem = item;
                                bottomItem = focusItem;
                                break;
                            }
                        }
                    }

                    // if they are not siblings then we do not support shift
                    // selection so just pass it on
                    if(topItem)
                    {
                        // need to iterate all the items and 
                        // select them
                        
                        rootItem = topItem;

                        do
                        {
                            tv_item.hItem = rootItem;
                            tv_item.mask = TVIF_STATE;
                            tv_item.stateMask = TVIS_SELECTED;
                            tv_item.state = TVIS_SELECTED;

                            TreeView_SetBranch(hwnd, &tv_item);
                    
                        }while(rootItem != bottomItem && (rootItem = TreeView_GetNextSibling(hwnd, rootItem)));

                        
                        return TRUE;
                    }
                    
                    break;
                }
                else
                {
                    if(!wasSelected)
                    {
                        // need to iterate all the items and 
                        // make sure they aren't selected
                        HTREEITEM rootItem = TreeView_GetRoot(hwnd);

                        if(rootItem)
                        {
                            do
                            {
                                tv_item.hItem = rootItem;
                                tv_item.mask = TVIF_STATE;
                                tv_item.stateMask = TVIS_SELECTED;
                                tv_item.state = 0;

                                TreeView_SetBranch(hwnd, &tv_item);
                            
                            }while(rootItem = TreeView_GetNextSibling(hwnd, rootItem));
                        }

                        // need to set this back cause windows won't
                        // set it if it is already the focus item and
                        // we just deselected it
                        if(wasSelected && wasFocus)
                        {
                            tv_item.hItem = focusItem;
                            tv_item.mask = TVIF_STATE;
                            tv_item.stateMask = TVIS_SELECTED;
                            tv_item.state = TVIS_SELECTED;

                            TreeView_SetItem(hwnd, &tv_item);
                        }
                    }

                    TreeView_Select(hwnd, item, TVGN_CARET);

                    if(!wasFocus && wasFocusSelected && wasSelected)
                    {
                        tv_item.hItem = focusItem;
                        tv_item.mask = TVIF_STATE;
                        tv_item.stateMask = TVIS_SELECTED;
                        tv_item.state = TVIS_SELECTED;

                        TreeView_SetItem(hwnd, &tv_item);
                    }
                    
                    
                }

                SetCapture(hwnd);
                dragging = true;

                return TRUE;
            }
                    
            break;
        }

        case WM_TIMER:
        {
            KillTimer(hwnd, 1);
            EditItemLabel(hwnd, g_editItem);
            break;
        }

        case WM_LBUTTONUP:
        {
            bool shiftKeyPressed = IsShiftDown();
            bool ctrlKeyPressed = IsCtrlDown();

            SetCapture(NULL);
            dragging = false;

            HTREEITEM item;
            TV_HITTESTINFO hti;

            hti.pt.x = LOWORD(lParam);
            hti.pt.y = HIWORD(lParam);
        
            item = TreeView_HitTest(hwnd, &hti);  

            if(item && (hti.flags & TVHT_ONITEM))
            {
                HTREEITEM focusItem = TreeView_GetSelection(hwnd);
                TV_ITEM tv_item;

                tv_item.hItem = focusItem;
                tv_item.mask = TVIF_STATE;
                tv_item.stateMask = TVIS_SELECTED;

                TreeView_GetItem(hwnd, &tv_item);

                bool wasFocusSelected = (tv_item.state & TVIS_SELECTED) != 0;

                tv_item.hItem = item;
                tv_item.mask = TVIF_STATE;
                tv_item.stateMask = TVIS_SELECTED;

                TreeView_GetItem(hwnd, &tv_item);

                bool wasFocus = item == focusItem;
                bool wasSelected = (tv_item.state & TVIS_SELECTED) != 0;
                
                if(ctrlKeyPressed)
                {
                    TreeView_Select(hwnd, item, TVGN_CARET);

                    if(wasSelected)
                    {
                        tv_item.hItem = item;
                        tv_item.mask = TVIF_STATE;
                        tv_item.stateMask = TVIS_SELECTED;
                        tv_item.state = 0;

                        TreeView_SetItem(hwnd, &tv_item);
                    }


                    if(!wasFocus && wasFocusSelected || !wasSelected)
                    {
                        tv_item.hItem = focusItem;
                        tv_item.mask = TVIF_STATE;
                        tv_item.stateMask = TVIS_SELECTED;
                        tv_item.state = TVIS_SELECTED;

                        TreeView_SetItem(hwnd, &tv_item);
                    }

                    return TRUE;
                }
                else if(!shiftKeyPressed)
                {
                    // need to iterate all the items and 
                    // make sure they aren't selected
                    HTREEITEM rootItem = TreeView_GetRoot(hwnd);

                    if(rootItem)
                    {
                        do
                        {
                            tv_item.hItem = rootItem;
                            tv_item.mask = TVIF_STATE;
                            tv_item.stateMask = TVIS_SELECTED;
                            tv_item.state = 0;

                            TreeView_SetBranch(hwnd, &tv_item);
                        
                        }while(rootItem = TreeView_GetNextSibling(hwnd, rootItem));
                    }

                    // need to set this back cause windows won't
                    // set it if it is already the focus item and
                    // we just deselected it
                    if(wasSelected && wasFocus)
                    {
                        tv_item.hItem = focusItem;
                        tv_item.mask = TVIF_STATE;
                        tv_item.stateMask = TVIS_SELECTED;
                        tv_item.state = TVIS_SELECTED;

                        TreeView_SetItem(hwnd, &tv_item);
                    }
                    
                    if(selectedOnMouseDown)
                    {
                        if(g_editItem != item)
                        {
                            // i should do this in the notify but it is ignoring me
                            if(item != m_hMyMusicItem &&
                               item != m_hPlaylistItem &&
                               item != m_hAllItem &&
                               item != m_hUncatItem &&
                               item != m_hNewPlaylistItem &&
                               item != m_hStreamsItem &&
                               item != m_hFavoritesItem &&
                               item != m_hNewFavoritesItem &&
                               item != m_hPortableItem &&
                               TreeView_GetParent(m_hMusicView, item) != m_hPortableItem &&
                               item != m_hCDItem &&
                               TreeView_GetParent(m_hMusicView, item) != m_hCDItem)
                            {
                                // pause a half sec so this does not
                                // look so jarring
                                //Sleep(500);
                                SetTimer(hwnd, 1, GetDoubleClickTime(), NULL);
                                g_editItem = item;
                                //EditItemLabel(hwnd, item);
                            }
                        }
                        else
                        {
                            g_editItem = NULL;
                        }
                    }
                }
            }

                    
            break;
        }

        case WM_SETFOCUS:
        case WM_KILLFOCUS:
        {
            UpdateButtonStates();
            InvalidateRect(hwnd, NULL, TRUE);
            break;
        }
    } 
	
	//  Pass all non-custom messages to old window proc
	return CallWindowProc(lpOldProc, hwnd, msg, wParam, lParam );
}