Changeset 148

Show
Ignore:
Timestamp:
03/08/07 13:57:19 (1 year ago)
Author:
bsmith7
Message:

Lots of little client improvements

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • dmp/trunk/Bridge/Bridge.csproj

    r141 r148  
    1 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
     1<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> 
    22  <PropertyGroup> 
    33    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> 
  • dmp/trunk/DataObjects/DataObjects.csproj

    r87 r148  
    4242  </ItemGroup> 
    4343  <ItemGroup> 
     44    <Compile Include="GPair.cs" /> 
    4445    <Compile Include="Playlist.cs" /> 
    4546    <Compile Include="Track.cs" /> 
  • dmp/trunk/client/wpfclient/ControlTemplates.xaml

    r132 r148  
    4747        </ControlTemplate> 
    4848 
     49        <ControlTemplate x:Key="ServerRemove" TargetType="{x:Type Button}"> 
     50                <Image Name="Icon" Source="pack://application:,,/resources/ServerRem_nohover.png" Width="18" Height="18"/> 
     51                <ControlTemplate.Triggers> 
     52                        <Trigger Property="UIElement.IsMouseOver" Value="true"> 
     53                                <Setter TargetName="Icon" Property="Image.Source" Value="pack://application:,,/resources/ServerRem_hover.png"/> 
     54                        </Trigger> 
     55                </ControlTemplate.Triggers> 
     56        </ControlTemplate> 
     57         
    4958</ResourceDictionary> 
  • dmp/trunk/client/wpfclient/SongViewer.cs

    r132 r148  
    1414    public class SongViewer : Control 
    1515    { 
    16         private DataTable songDT = null; 
     16                Brush ColSortBGColor = Brushes.LightGray; //Background color to be used for the column that is being sorted 
     17                Brush ColNonSortBGColor = Brushes.White;//Background color for non-sorted columns 
     18 
     19                Brush RowMajorColor = Brushes.LightSteelBlue; 
     20                Brush RowMinorColor = Brushes.White; 
     21                 
     22                Brush HighlightedRowColor = Brushes.LightGreen; 
     23 
     24        private DataTable songDT = new DataTable(); 
    1725        public DataTable SongDT { 
    1826            get{ return songDT; } 
    1927            set{  
    20                 songDT = value; 
    21                 currentView = songDT.DefaultView; 
     28                DataView newView = value.DefaultView; 
     29                                newView.Sort = currentView.Sort; 
     30                                newView.RowFilter = currentView.RowFilter; 
     31                                 
     32                                songDT = value; 
     33                                currentView = newView; 
     34 
     35                                UpdateVertScrollSize(); 
    2236                InvalidateVisual(); 
    2337            } 
    2438        } 
    2539 
    26         private DataView currentView = null
     40        private DataView currentView = new DataView()
    2741        public DataView CurrentView { 
    2842            get { return currentView; } 
     
    3751            columns = new LinkedList<string>(); 
    3852            iMargin = 2; 
    39         } 
     53 
     54                        HighlightedRow.SongId = -1; 
     55                        HighlightedRow.LibId = -1; 
     56                        HighlightedRow.LastIndex = -1; 
     57        } 
     58 
     59                struct RowRecord{ 
     60                        public int SongId; 
     61                        public int LibId; 
     62                        public int LastIndex; 
     63                } 
    4064 
    4165        //This represents the first song to be displayed 
     
    4367        private int FirstIndex { 
    4468            set { 
    45                 firstIndex = value; 
    46                 InvalidateVisual(); 
     69                                if(value==firstIndex) 
     70                                        return; 
     71 
     72                                int newValue; 
     73                                //We need to make sure the new value is valud 
     74                                if(value<0) 
     75                                        newValue=0; 
     76                                else if(value >= currentView.Count - visibleRows + 1 ) 
     77                                        newValue = currentView.Count - visibleRows + 2; 
     78                                else  
     79                                        newValue = value; 
     80 
     81                                if(newValue != firstIndex){ 
     82                                        firstIndex = newValue; 
     83                                        vertScrollBar.Value = firstIndex; 
     84                                        InvalidateVisual(); 
     85                                } 
    4786            } 
    4887            get{ return firstIndex; } 
    4988        } 
     89 
     90                //Last fully drawn index 
     91                private int LastIndex { 
     92                        get{ 
     93                                return Math.Min(firstIndex+visibleRows-2, currentView.Count-1); 
     94                        } 
     95                } 
    5096 
    5197        ScrollBar vertScrollBar; 
     
    109155 
    110156            //Have to draw a rectangle for header row 
    111             dc.DrawRectangle(Brushes.White, new Pen(Brushes.White, 0),  
     157            /*dc.DrawRectangle(Brushes.White, new Pen(Brushes.White, 0),  
    112158                    new Rect(currentPt, new Point(currentPt.X + RenderSize.Width, currentPt.Y + fontHeight))); 
    113  
     159                        */ 
    114160 
    115161            //Compute width for each column 
     
    120166            while (currentCol != null) 
    121167            { 
    122                 DrawCell(currentCol.Value, dc, currentPt, colWidth); 
     168                                Brush bgBrush; 
     169                                if(currentCol.Value == currentSortCol) 
     170                                        bgBrush = ColSortBGColor; 
     171                                else 
     172                                        bgBrush = ColNonSortBGColor; 
     173 
     174                                dc.DrawRectangle(bgBrush, new Pen(Brushes.White, 0),  
     175                    new Rect(currentPt, new Point(currentPt.X + colWidth, currentPt.Y + fontHeight))); 
     176 
     177                                string colName; 
     178                                if(currentCol.Value == currentSortCol){ 
     179                                        if(Ascending) 
     180                                                colName = currentCol.Value + "  [A-Z]"; 
     181                                        else 
     182                                                colName = currentCol.Value + "  [Z-A]"; 
     183                                } 
     184                                else 
     185                                        colName = currentCol.Value; 
     186 
     187                DrawCell(colName, dc, currentPt, colWidth); 
    123188                 
    124189                currentCol = currentCol.Next; 
     
    135200 
    136201                Brush currentBrush; 
    137                 if ((int)currentView[i]["id"] == highlightedId) { 
    138                     currentBrush = Brushes.Tomato; 
     202 
     203                                bool rowHighlighted = ((int)currentView[i]["id"] == HighlightedRow.SongId); 
     204                if (rowHighlighted) { 
     205                    currentBrush = HighlightedRowColor; 
    139206                    fontColor = Brushes.White; 
     207 
     208                                        HighlightedRow.LastIndex = i; 
    140209                } 
    141210                else  
    142                     currentBrush = (i % 2 == 1) ? Brushes.LightSteelBlue : Brushes.White
     211                    currentBrush = (i % 2 == 1) ? RowMajorColor : RowMinorColor
    143212 
    144213                dc.DrawRectangle(currentBrush, new Pen(Brushes.White, 0), new Rect(currentPt, 
     
    153222                    currentCol = currentCol.Next; 
    154223                } 
    155                 if ((int)currentView[i]["id"] == highlightedId) 
     224                if (rowHighlighted) 
    156225                    fontColor = Brushes.Black; 
    157226 
     
    220289        //Changes the range of the scrollbars when the number of displayed rows or count changes 
    221290        void UpdateVertScrollSize(){ 
    222             if(SongDT == null || SongDT.Rows.Count < VisibleRows) 
     291            if(SongDT == null || currentView.Count < VisibleRows) 
    223292                vertScrollBar.Visibility = Visibility.Hidden; 
    224293            else{ 
    225294                vertScrollBar.Visibility = Visibility.Visible; 
    226                 vertScrollBar.Maximum = SongDT.Rows.Count - (VisibleRows - 1); 
    227                 vertScrollBar.ViewportSize = VisibleRows-1; 
    228             } 
    229         } 
    230  
    231         int highlightedIndex = -1; 
    232         int highlightedId = -1; 
    233  
     295                vertScrollBar.Maximum = currentView.Count - (VisibleRows - 1); 
     296                vertScrollBar.ViewportSize = Math.Max(0, VisibleRows-1); 
     297            } 
     298        } 
     299 
     300        RowRecord HighlightedRow; 
     301                 
    234302        Brush fontColor = Brushes.Black; 
    235303 
    236304        protected override void OnMouseDown(MouseButtonEventArgs e) 
    237305        { 
     306                        Focus(); 
     307 
    238308            switch (e.ChangedButton) 
    239309            { 
     
    249319                        if (e.ClickCount == 2) 
    250320                            MessageBox.Show("Doubleclick occured"); 
    251                         highlightedIndex = rowClicked - 1; 
    252                         highlightedId = (int)currentView[highlightedIndex]["id"]; 
     321 
     322                                                HighlightedRow.LastIndex = rowClicked -1; 
     323                                                HighlightedRow.SongId = (int)currentView[HighlightedRow.LastIndex]["id"]; 
     324 
    253325                        InvalidateVisual(); 
    254326                    } 
     
    281353        } 
    282354 
     355                string currentSortCol = null; 
     356                bool Ascending = true; 
     357 
    283358        void SortOnColName(string colName) 
    284359        { 
    285             if (CurrentView.Sort == colName) 
    286                 CurrentView.Sort = colName + " DESC"; 
    287             else 
    288                 currentView.Sort = colName; 
    289  
    290             InvalidateVisual(); 
    291         } 
     360                        if(colName == currentSortCol){ 
     361                                if(Ascending){ 
     362                                        currentView.Sort = colName + " DESC"; 
     363                                        Ascending = false; 
     364                                } 
     365                                else { 
     366                                        currentView.Sort = colName; 
     367                                        Ascending = true; 
     368                                } 
     369                        } 
     370                        else { 
     371                                currentView.Sort = colName; 
     372                                currentSortCol = colName; 
     373                                Ascending = true; 
     374                        } 
     375                         
     376                        InvalidateVisual(); 
     377                } 
    292378 
    293379        TextBox searchBox; 
     
    301387        } 
    302388 
     389                //Sets the filter option for real-time searching 
    303390        void OnSearchBoxUpdate(Object sender, TextChangedEventArgs args) 
    304391        { 
     
    306393 
    307394            CurrentView.RowFilter = "Artist LIKE '*"+currentSearch+"*' OR Album LIKE '*"+currentSearch+"*' OR Title LIKE '*"+currentSearch+"*'"; 
    308             InvalidateVisual(); 
    309         } 
     395            UpdateVertScrollSize(); 
     396                        InvalidateVisual(); 
     397        } 
     398 
     399                protected override void OnKeyDown(KeyEventArgs e) 
     400                { 
     401                        Focus(); 
     402 
     403                        switch(e.Key){ 
     404                                case Key.Up : 
     405                                        MoveHighlight(-1); 
     406                                        //MessageBox.Show("asdf"); 
     407                                        break; 
     408                                case Key.Down: 
     409                                        MoveHighlight(1); 
     410                                        break; 
     411                                default:         
     412                                //base.OnKeyDown(e); 
     413                                        break; 
     414                        } 
     415                        e.Handled = true; 
     416                } 
     417 
     418                protected override void OnKeyUp(KeyEventArgs e) 
     419                { 
     420                        //base.OnKeyUp(e); 
     421                } 
     422 
     423                protected override void OnMouseWheel(MouseWheelEventArgs e) 
     424                { 
     425                        int lineDelta = 2*Math.Sign(e.Delta); 
     426                        FirstIndex -= lineDelta; 
     427                } 
     428 
     429                //Returns the value that's in the middle 
     430                int MidRange(int p1, int p2, int p3){ 
     431                        int max = Math.Max(Math.Max(p1, p2), p3); 
     432                        int min = Math.Min(Math.Min(p1, p2), p3); 
     433 
     434                        if(p1 != max && p1 != min) 
     435                                return p1; 
     436 
     437                        if(p2 != max && p2 != min) 
     438                                return p2; 
     439 
     440                                return p3; 
     441                } 
     442 
     443                //This changes the currently highlighted song 
     444                void MoveHighlight(int amount){ 
     445                        //First make sure the currently highlighted song is even displayed 
     446                        if((int)currentView[HighlightedRow.LastIndex]["id"] != HighlightedRow.SongId) 
     447                                return; 
     448 
     449                        int newIndex = HighlightedRow.LastIndex + amount; 
     450                        //Make sure the new index is valid 
     451                        if(newIndex<0 || newIndex >= currentView.Count) 
     452                                return; 
     453 
     454                        HighlightedRow.LastIndex = newIndex; 
     455                        HighlightedRow.SongId = (int)currentView[newIndex]["id"]; 
     456                         
     457                        if(newIndex < FirstIndex){ 
     458                                FirstIndex = newIndex; 
     459                        } 
     460                        else if(newIndex > LastIndex){ 
     461                                FirstIndex++; 
     462                        } 
     463 
     464                        InvalidateVisual(); 
     465                } 
    310466    } 
    311467} 
  • dmp/trunk/client/wpfclient/main_window.xaml

    r132 r148  
    3535                <TextBox Width="60" Height="20" Margin="5"  Name="SearchBox" Grid.Row="0" Grid.Column="2"/> 
    3636 
    37                 <!--StackPanel Grid.Row="1" Grid.Column="0" Margin="5"> 
    38                         <Expander IsExpanded="True"  Header="Servers"> 
    39                                 <StackPanel Name="serverStack"/>                                 
    40                         </Expander> 
    41                 </StackPanel--> 
    4237                <StackPanel Name="serverStack" Grid.Row="1" Grid.Column="0" Margin="5"> 
    4338      <!--StackPanel Orientation="Horizontal"> 
  • dmp/trunk/client/wpfclient/main_window.xaml.cs

    r139 r148  
    3636 
    3737            songViewBorder.Child = songView; 
     38                        songView.Focusable = true; 
    3839 
    3940            myBridge = new Bridge(); 
    40             myBridge.myServiceLocator.Found += serverFound; 
    41             myBridge.myServiceLocator.Removed += serverRemoved; 
     41 
     42            myBridge.ServerAdded += serverAdded; 
     43            myBridge.ServerRemoved += serverRemoved; 
    4244            myBridge.StartZeroConf(); 
    4345             
     
    5658        delegate void ServerUpdateDelegate(); 
    5759 
    58         Queue<DAAP.Service> newServers = new Queue<DAAP.Service>(); 
    59         private void serverFound(object o, DAAP.ServiceArgs args){ 
     60                //Queue to store arguments that can be passed across threads, string is servername, bool connection status 
     61        Queue<GPair<string, bool>> newServers = new Queue<GPair<string, bool>>(); 
     62        private void serverAdded(object o, ServerStatusEventArgs args){ 
    6063            lock(newServers){ 
    61                 newServers.Enqueue(args.Service); 
    62             } 
    63  
    64             serverStack.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new ServerUpdateDelegate(addServer)); 
     64                newServers.Enqueue(new GPair<string, bool>(args.ServerName, args.ServerIsConnected)); 
     65            } 
     66 
     67            serverStack.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,  
     68                                        new ServerUpdateDelegate(addServer)); 
    6569        } 
    6670 
     
    7074        void addServer() 
    7175        { 
    72             DAAP.Service server; 
     76            GPair<string, bool> server; 
    7377            lock (newServers) 
    7478            { 
     
    7680            } 
    7781             
    78             StackPanel newButton = CreateServerButton(server.Name); 
    79             displayedServers.Add(server.Name, newButton); 
     82            StackPanel newButton = CreateServerButton(server.First, server.Second); 
     83            displayedServers.Add(server.First, newButton); 
    8084            serverStack.Children.Add(newButton); 
    8185        } 
    8286 
    83         Queue<DAAP.Service> removedServers = new Queue<DAAP.Service>(); 
    84         void serverRemoved(object o, DAAP.ServiceArgs args){ 
     87        Queue<string> removedServers = new Queue<string>(); 
     88        void serverRemoved(object o, ServerStatusEventArgs args){ 
    8589            lock(removedServers){ 
    86                 removedServers.Enqueue(args.Service); 
    87             } 
    88             serverStack.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal, new ServerUpdateDelegate(removeServer)); 
     90                removedServers.Enqueue(args.ServerName); 
     91            } 
     92            serverStack.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,  
     93                                        new ServerUpdateDelegate(removeServer)); 
    8994        } 
    9095 
    9196        void removeServer() 
    9297        { 
    93             DAAP.Service service; 
     98            string serverName; 
    9499            lock(removedServers){ 
    95                 service = removedServers.Dequeue(); 
    96             } 
    97  
    98             serverStack.Children.Remove(displayedServers[service.Name]); 
    99             displayedServers.Remove(service.Name); 
    100         } 
    101  
    102         private StackPanel CreateServerButton(string serverName) { 
     100                serverName = removedServers.Dequeue(); 
     101            } 
     102 
     103            serverStack.Children.Remove(displayedServers[serverName]); 
     104            displayedServers.Remove(serverName); 
     105        } 
     106 
     107        private StackPanel CreateServerButton(string serverName, bool connected) { 
    103108            StackPanel mainPanel = new StackPanel(); 
    104109            mainPanel.Orientation = Orientation.Horizontal; 
    105110 
    106111            BitmapImage bitmap = new BitmapImage(); 
    107             bitmap.BeginInit(); 
    108             bitmap.UriSource = new Uri("pack://application:,,/resources/Server_red.png"); 
     112            bitmap.BeginInit();          
     113            bitmap.UriSource = GetServerStatus(connected); 
    109114            bitmap.EndInit(); 
    110115 
     
    118123            mainPanel.Children.Add(serverText); 
    119124 
    120             Button addButton = new Button(); 
    121             addButton.Template = (ControlTemplate)this.FindResource("ServerAdd"); 
    122             mainPanel.Children.Add(addButton); 
     125            Button controlButton = new Button(); 
     126            controlButton.Template = GetButtonTemplate(connected); 
     127                        controlButton.PreviewMouseLeftButtonDown += OnServerAdd; 
     128                        controlButton.Content = serverName; 
     129            mainPanel.Children.Add(controlButton); 
    123130 
    124131            return mainPanel; 
    125132        } 
    126133 
     134        private Uri GetServerStatus(bool connected){ 
     135            if(connected) 
     136                return new Uri("pack://application:,,/resources/Server_green.png"); 
     137            else 
     138                                return new Uri("pack://application:,,/resources/Server_red.png"); 
     139                } 
     140 
     141                private ControlTemplate GetButtonTemplate(bool connected){ 
     142                        if(connected) 
     143                                return (ControlTemplate)FindResource("ServerRemove"); 
     144                        else 
     145                                return (ControlTemplate)FindResource("ServerAdd"); 
     146                } 
     147                 
     148                Queue<GPair<string, bool>> statusQueue = new Queue<GPair<string, bool>>(); 
     149                private void ServerStatusChanged(string serverName, bool connected){ 
     150                        lock(statusQueue){ 
     151                                statusQueue.Enqueue(new GPair<string, bool>(serverName, connected)); 
     152                        } 
     153 
     154                        serverStack.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,  
     155                                        new ServerUpdateDelegate(ChangeServerStatus)); 
     156                } 
     157 
     158                //Will change a server button status to connected or disconnected regardless of earlier state 
     159                void ChangeServerStatus() { 
     160                        GPair<string, bool> server; 
     161                        lock(statusQueue){ 
     162                                server = statusQueue.Dequeue(); 
     163                        } 
     164                         
     165                        StackPanel mainPanel = displayedServers[server.First]; 
     166                        BitmapImage bitmap = (BitmapImage)((Image)mainPanel.Children[0]).Source; 
     167 
     168                        bitmap.BeginInit(); 
     169                        bitmap.UriSource = GetServerStatus(server.Second); 
     170                        bitmap.EndInit(); 
     171 
     172                        Button controlButton = (Button)mainPanel.Children[2]; 
     173                        controlButton.Template = GetButtonTemplate(server.Second); 
     174                } 
     175 
     176                Queue<DataTable> datatableQueue = new Queue<DataTable>(); 
     177                private void DataTableChanged(object o, SongListChangedEventArgs args){ 
     178                        lock(datatableQueue){ 
     179                                datatableQueue.Enqueue(args.NewTable); 
     180                        } 
     181 
     182                        serverStack.Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Normal,  
     183                                        new ServerUpdateDelegate(ChangeDataTable)); 
     184                } 
     185 
     186                void ChangeDataTable(){ 
     187                        DataTable newDT; 
     188                        lock(datatableQueue){ 
     189                                newDT = datatableQueue.Dequeue(); 
     190                        } 
     191 
     192                        songView.SongDT = newDT; 
     193                } 
     194 
     195                private void OnServerAdd(object sender, MouseButtonEventArgs args){ 
     196                        Button source = (Button)sender; 
     197                        MessageBox.Show("Server "+(string)source.Content+" added!"); 
     198                } 
     199 
     200                //Populates a datatable with dummy data for testing purposes 
    127201        private DataTable createTestTable() 
    128202        { 
  • dmp/trunk/client/wpfclient/wpfclient.csproj

    r130 r148  
    4141  </ItemGroup> 
    4242  <ItemGroup> 
     43    <Compile Include="GPair.cs" /> 
    4344    <Compile Include="main_window.xaml.cs"> 
    4445      <SubType>Code</SubType> 
     
    7879    <Resource Include="resources\ServerAdd_nohover.png" /> 
    7980  </ItemGroup> 
     81  <ItemGroup> 
     82    <Resource Include="resources\ServerRem_hover.png" /> 
     83    <Resource Include="resources\ServerRem_nohover.png" /> 
     84    <Resource Include="resources\Server_green.png" /> 
     85  </ItemGroup> 
    8086  <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" /> 
    8187  <Import Project="$(MSBuildBinPath)\Microsoft.WinFX.targets" />