Просмотр исходного кода

Feature: live filter and sorting

- Live filter: Edit box OnChange filters by title/author\n- Sorting: ComboBox for Recently Added / Title / Author\n- BookCollection: add SortByTitle/SortByAuthor\n- Layout adjusts positions of search and sort controls
Codex CLI 4 месяцев назад
Родитель
Сommit
88872e2242
3 измененных файлов с 104 добавлено и 2 удалено
  1. 34 0
      src/bookcollection.pas
  2. 18 0
      src/main.lfm
  3. 52 2
      src/main.pas

+ 34 - 0
src/bookcollection.pas

@@ -25,6 +25,8 @@ TBookCollection = class(TObject)
     function Count: Integer;
     procedure Clear;
     procedure SwapBooks(Source, Dest: Integer);
+    procedure SortByTitle;
+    procedure SortByAuthor;
     constructor Create;
     destructor Destroy; override;
 
@@ -79,6 +81,38 @@ begin
  mList.Move(Source,Dest);
 end;
 
+function CmpText(const A, B: String): Integer;
+var sA, sB: String;
+begin
+  sA := UTF8LowerCase(Trim(A));
+  sB := UTF8LowerCase(Trim(B));
+  if sA < sB then Exit(-1)
+  else if sA > sB then Exit(1)
+  else Exit(0);
+end;
+
+function CompareByTitle(Item1, Item2: Pointer): Integer;
+begin
+  Result := CmpText(TBook(Item1).Title, TBook(Item2).Title);
+end;
+
+function CompareByAuthor(Item1, Item2: Pointer): Integer;
+begin
+  Result := CmpText(TBook(Item1).Authors, TBook(Item2).Authors);
+end;
+
+procedure TBookCollection.SortByTitle;
+begin
+  if Assigned(mList) then
+    mList.Sort(@CompareByTitle);
+end;
+
+procedure TBookCollection.SortByAuthor;
+begin
+  if Assigned(mList) then
+    mList.Sort(@CompareByAuthor);
+end;
+
 constructor TBookCollection.Create;
 begin
   mList:=TFPList.Create;

+ 18 - 0
src/main.lfm

@@ -54,6 +54,7 @@ object Form1: TForm1
     Width = 176
     AutoSelect = False
     BorderStyle = bsNone
+    OnChange = EditSearchChange
     OnEnter = EditSearchEnter
     OnExit = EditSearchExit
     OnKeyPress = EditSearchKeyPress
@@ -63,6 +64,23 @@ object Form1: TForm1
     Text = 'Search...'
     TextHintFontColor = clBtnText
   end
+  object ComboSort: TComboBox
+    Left = 400
+    Height = 23
+    Top = 15
+    Width = 192
+    ItemHeight = 15
+    Style = csDropDownList
+    OnChange = ComboSortChange
+    TabOrder = 2
+    Items.Strings = (
+      'Recently Added'
+      'Title'
+      'Author'
+    )
+    ItemIndex = 0
+    Text = 'Recently Added'
+  end
   object ButtonSettings: TImage
     Left = 80
     Height = 42

+ 52 - 2
src/main.pas

@@ -7,7 +7,7 @@ interface
 uses
   Classes, Sysutils, Fileutil, Forms, Controls, Graphics, Dialogs, ExtCtrls, LazFileUtils,
   Book, BookCollection, LCLIntf, LResources, StdCtrls, LCLType, IniFiles, unitSettingsDialog,
-  unitCoverWorker, unitStorageXML, unitMetadata;
+  unitCoverWorker, unitStorageXML, unitMetadata, LazUTF8;
 
 
 type
@@ -15,6 +15,7 @@ type
   { TForm1 }
   TForm1 = class(TForm)
     EditSearch: Tedit;
+    ComboSort: TComboBox;
     ButtonSettings: Timage;
     ImageToolBar: Timage;
     ButtonAdd: Timage;
@@ -29,7 +30,9 @@ type
     procedure ButtonSettingsMouseLeave({%H-}Sender: TObject);
     procedure EditSearchEnter({%H-}Sender: TObject);
     procedure EditSearchExit({%H-}Sender: TObject);
+    procedure EditSearchChange({%H-}Sender: TObject);
     procedure EditSearchKeyPress({%H-}Sender: TObject; var Key: Char);
+    procedure ComboSortChange({%H-}Sender: TObject);
     procedure FormClose({%H-}Sender: TObject; var CloseAction: TCloseAction);
     procedure FormCreate({%H-}Sender: TObject);
     procedure FormKeyDown({%H-}Sender: TObject; var Key: Word; {%H-}Shift: TShiftState);
@@ -47,6 +50,7 @@ type
     mAdd,mAddHover,mGear,mGearHover:TPicture;
     LayoutTimer: TTimer;
     procedure LayoutTimerTick(Sender: TObject);
+    procedure ApplyFilterAndLayout;
   public
     { public declarations }
   end;
@@ -252,7 +256,9 @@ begin
  if isClosing then Exit;
  RearrangeBooksOnScreen();
 
- EditSearch.Left:=Width-EditSearch.Width-20;
+ EditSearch.Left := Width - EditSearch.Width - 20;
+ if Assigned(ComboSort) then
+   ComboSort.Left := EditSearch.Left - ComboSort.Width - 12;
 End;
 
 function TForm1.GetBookIndexAtPoint(X, Y: Integer): Integer;
@@ -588,3 +594,47 @@ initialization
 {$i mybookshelf.lrs}
 
 end.
+procedure TForm1.EditSearchChange({%H-}Sender: TObject);
+begin
+  ApplyFilterAndLayout;
+end;
+
+procedure TForm1.ComboSortChange({%H-}Sender: TObject);
+begin
+  case ComboSort.ItemIndex of
+    0: ; // Recently Added (keep current order)
+    1: bookList.SortByTitle;
+    2: bookList.SortByAuthor;
+  end;
+  ApplyFilterAndLayout;
+end;
+
+procedure TForm1.ApplyFilterAndLayout;
+var
+  q, lt, la: String;
+  i: Integer;
+  b: TBook;
+  showIt: Boolean;
+begin
+  if (bookList = nil) then Exit;
+  q := UTF8LowerCase(Trim(EditSearch.Text));
+  if (q = '') or (q = 'search...') then
+  begin
+    // show all
+    for i := 0 to bookList.Count - 1 do
+      if Assigned(bookList.Books[i].Cover) then
+        bookList.Books[i].Cover.Visible := True;
+  end
+  else
+  begin
+    for i := 0 to bookList.Count - 1 do
+    begin
+      b := bookList.Books[i];
+      lt := UTF8LowerCase(b.Title);
+      la := UTF8LowerCase(b.Authors);
+      showIt := (Pos(q, lt) > 0) or (Pos(q, la) > 0);
+      if Assigned(b.Cover) then b.Cover.Visible := showIt;
+    end;
+  end;
+  RearrangeBooksOnScreen();
+end;