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

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;
     function Count: Integer;
     procedure Clear;
     procedure Clear;
     procedure SwapBooks(Source, Dest: Integer);
     procedure SwapBooks(Source, Dest: Integer);
+    procedure SortByTitle;
+    procedure SortByAuthor;
     constructor Create;
     constructor Create;
     destructor Destroy; override;
     destructor Destroy; override;
 
 
@@ -79,6 +81,38 @@ begin
  mList.Move(Source,Dest);
  mList.Move(Source,Dest);
 end;
 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;
 constructor TBookCollection.Create;
 begin
 begin
   mList:=TFPList.Create;
   mList:=TFPList.Create;

+ 18 - 0
src/main.lfm

@@ -54,6 +54,7 @@ object Form1: TForm1
     Width = 176
     Width = 176
     AutoSelect = False
     AutoSelect = False
     BorderStyle = bsNone
     BorderStyle = bsNone
+    OnChange = EditSearchChange
     OnEnter = EditSearchEnter
     OnEnter = EditSearchEnter
     OnExit = EditSearchExit
     OnExit = EditSearchExit
     OnKeyPress = EditSearchKeyPress
     OnKeyPress = EditSearchKeyPress
@@ -63,6 +64,23 @@ object Form1: TForm1
     Text = 'Search...'
     Text = 'Search...'
     TextHintFontColor = clBtnText
     TextHintFontColor = clBtnText
   end
   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
   object ButtonSettings: TImage
     Left = 80
     Left = 80
     Height = 42
     Height = 42

+ 52 - 2
src/main.pas

@@ -7,7 +7,7 @@ interface
 uses
 uses
   Classes, Sysutils, Fileutil, Forms, Controls, Graphics, Dialogs, ExtCtrls, LazFileUtils,
   Classes, Sysutils, Fileutil, Forms, Controls, Graphics, Dialogs, ExtCtrls, LazFileUtils,
   Book, BookCollection, LCLIntf, LResources, StdCtrls, LCLType, IniFiles, unitSettingsDialog,
   Book, BookCollection, LCLIntf, LResources, StdCtrls, LCLType, IniFiles, unitSettingsDialog,
-  unitCoverWorker, unitStorageXML, unitMetadata;
+  unitCoverWorker, unitStorageXML, unitMetadata, LazUTF8;
 
 
 
 
 type
 type
@@ -15,6 +15,7 @@ type
   { TForm1 }
   { TForm1 }
   TForm1 = class(TForm)
   TForm1 = class(TForm)
     EditSearch: Tedit;
     EditSearch: Tedit;
+    ComboSort: TComboBox;
     ButtonSettings: Timage;
     ButtonSettings: Timage;
     ImageToolBar: Timage;
     ImageToolBar: Timage;
     ButtonAdd: Timage;
     ButtonAdd: Timage;
@@ -29,7 +30,9 @@ type
     procedure ButtonSettingsMouseLeave({%H-}Sender: TObject);
     procedure ButtonSettingsMouseLeave({%H-}Sender: TObject);
     procedure EditSearchEnter({%H-}Sender: TObject);
     procedure EditSearchEnter({%H-}Sender: TObject);
     procedure EditSearchExit({%H-}Sender: TObject);
     procedure EditSearchExit({%H-}Sender: TObject);
+    procedure EditSearchChange({%H-}Sender: TObject);
     procedure EditSearchKeyPress({%H-}Sender: TObject; var Key: Char);
     procedure EditSearchKeyPress({%H-}Sender: TObject; var Key: Char);
+    procedure ComboSortChange({%H-}Sender: TObject);
     procedure FormClose({%H-}Sender: TObject; var CloseAction: TCloseAction);
     procedure FormClose({%H-}Sender: TObject; var CloseAction: TCloseAction);
     procedure FormCreate({%H-}Sender: TObject);
     procedure FormCreate({%H-}Sender: TObject);
     procedure FormKeyDown({%H-}Sender: TObject; var Key: Word; {%H-}Shift: TShiftState);
     procedure FormKeyDown({%H-}Sender: TObject; var Key: Word; {%H-}Shift: TShiftState);
@@ -47,6 +50,7 @@ type
     mAdd,mAddHover,mGear,mGearHover:TPicture;
     mAdd,mAddHover,mGear,mGearHover:TPicture;
     LayoutTimer: TTimer;
     LayoutTimer: TTimer;
     procedure LayoutTimerTick(Sender: TObject);
     procedure LayoutTimerTick(Sender: TObject);
+    procedure ApplyFilterAndLayout;
   public
   public
     { public declarations }
     { public declarations }
   end;
   end;
@@ -252,7 +256,9 @@ begin
  if isClosing then Exit;
  if isClosing then Exit;
  RearrangeBooksOnScreen();
  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;
 End;
 
 
 function TForm1.GetBookIndexAtPoint(X, Y: Integer): Integer;
 function TForm1.GetBookIndexAtPoint(X, Y: Integer): Integer;
@@ -588,3 +594,47 @@ initialization
 {$i mybookshelf.lrs}
 {$i mybookshelf.lrs}
 
 
 end.
 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;