commit 0b732463e07593ca651beae1fdcc95218dde34a0
parent 7738ba0fe5d3b6449f1df2b59919e4746c10f147
Author: cfillion <cfillion@users.noreply.github.com>
Date: Sat, 28 Oct 2017 16:37:52 -0700
manager: display enabled status using REAPER's checkbox icons
Diffstat:
8 files changed, 152 insertions(+), 33 deletions(-)
diff --git a/src/iconlist.cpp b/src/iconlist.cpp
@@ -0,0 +1,53 @@
+/* ReaPack: Package manager for REAPER
+ * Copyright (C) 2015-2017 Christian Fillion
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "iconlist.hpp"
+
+#ifdef _WIN32
+# define DEFINE_ICON(icon, rc, _) IconList::Icon IconList::icon = MAKEINTRESOURCE(rc)
+#else
+# define DEFINE_ICON(icon, _, name) IconList::Icon IconList::icon = name
+#endif
+
+DEFINE_ICON(CheckedIcon, 141, "checked");
+DEFINE_ICON(UncheckedIcon, 142, "unchecke");
+
+IconList::IconList(const std::initializer_list<const Win32::char_type *> &icons)
+{
+ m_list = ImageList_Create(16, 16, 1, (int)icons.size(), (int)icons.size());
+
+ for(const auto *icon : icons)
+ loadIcon(icon);
+}
+
+void IconList::loadIcon(const Win32::char_type *name)
+{
+#ifdef _WIN32
+ HINSTANCE reaper = GetModuleHandle(nullptr);
+ HICON icon = LoadIcon(reaper, name);
+ ImageList_AddIcon(m_list, icon);
+#else
+ HICON icon = LoadNamedImage(name, true);
+ ImageList_Add(m_list, icon, 0);
+#endif
+ DestroyIcon(icon);
+}
+
+IconList::~IconList()
+{
+ ImageList_Destroy(m_list);
+}
diff --git a/src/iconlist.hpp b/src/iconlist.hpp
@@ -0,0 +1,49 @@
+/* ReaPack: Package manager for REAPER
+ * Copyright (C) 2015-2017 Christian Fillion
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#ifndef REAPACK_ICONLIST_HPP
+#define REAPACK_ICONLIST_HPP
+
+#include "win32.hpp"
+
+#include <initializer_list>
+
+#ifdef _WIN32
+# include <windows.h>
+# include <commctrl.h>
+#else
+# include <swell.h>
+#endif
+
+class IconList {
+public:
+ typedef const Win32::char_type *Icon;
+
+ static Icon CheckedIcon;
+ static Icon UncheckedIcon;
+
+ IconList(const std::initializer_list<Icon> &icons);
+ ~IconList();
+
+ void loadIcon(Icon icon);
+ HIMAGELIST handle() const { return m_list; }
+
+private:
+ HIMAGELIST m_list;
+};
+
+#endif
diff --git a/src/listview.cpp b/src/listview.cpp
@@ -17,6 +17,7 @@
#include "listview.hpp"
+#include "iconlist.hpp"
#include "menu.hpp"
#include "time.hpp"
#include "version.hpp"
@@ -24,14 +25,22 @@
#include <boost/algorithm/string/case_conv.hpp>
+using namespace std;
+
+static int adjustWidth(const int points)
+{
#ifdef _WIN32
-# include <commctrl.h>
+ if(points < 1)
+ return points;
+ else
+ return (int)ceil(points * 0.863); // magic number to make pretty sizes...
+#else
+ return points;
#endif
-
-using namespace std;
+}
ListView::ListView(HWND handle, const Columns &columns)
- : Control(handle), m_customizable(false), m_sort(), m_defaultSort(), m_dirty(0)
+ : Control(handle), m_dirty(0), m_customizable(false), m_sort(), m_defaultSort()
{
for(const Column &col : columns)
addColumn(col);
@@ -116,6 +125,25 @@ void ListView::updateCell(int row, int cell)
m_dirty |= NeedFilterFlag;
}
+void ListView::enableIcons()
+{
+ static IconList list({IconList::UncheckedIcon, IconList::CheckedIcon});
+
+ // NOTE: the list must have the LVS_SHAREIMAGELISTS style to prevent
+ // it from taking ownership of the image list
+ ListView_SetImageList(handle(), list.handle(), LVSIL_SMALL);
+}
+
+void ListView::setRowIcon(const int row, const int image)
+{
+ LVITEM item{};
+ item.iItem = translate(row);
+ item.iImage = image;
+ item.mask |= LVIF_IMAGE;
+
+ ListView_SetItem(handle(), &item);
+}
+
void ListView::removeRow(const int userIndex)
{
// translate to view index before fixing lParams
@@ -509,18 +537,6 @@ int ListView::translateBack(const int internalIndex) const
return -1;
}
-int ListView::adjustWidth(const int points)
-{
-#ifdef _WIN32
- if(points < 1)
- return points;
- else
- return (int)ceil(points * 0.863); // magic number to make pretty sizes...
-#else
- return points;
-#endif
-}
-
void ListView::headerMenu(const int x, const int y)
{
enum { ACTION_RESTORE = 800 };
@@ -668,6 +684,11 @@ void ListView::Row::setCell(const int i, const string &val, void *data)
m_list->updateCell(m_userIndex, i);
}
+void ListView::Row::setChecked(bool checked)
+{
+ m_list->setRowIcon(m_userIndex, checked);
+}
+
vector<string> ListView::Row::filterValues() const
{
vector<string> values;
diff --git a/src/listview.hpp b/src/listview.hpp
@@ -66,6 +66,7 @@ public:
const Cell &cell(const int i) const { return m_cells[i]; }
void setCell(const int i, const std::string &, void *data = nullptr);
+ void setChecked(bool check = true);
std::vector<std::string> filterValues() const;
@@ -121,6 +122,7 @@ public:
void clear();
void reset();
void autoSizeHeader();
+ void enableIcons();
int currentIndex() const;
int itemUnderMouse() const;
@@ -158,6 +160,7 @@ protected:
friend Row;
friend BeginEdit;
void updateCell(int row, int cell);
+ void setRowIcon(int row, int icon);
void endEdit();
private:
@@ -178,7 +181,6 @@ private:
void onNotify(LPNMHDR, LPARAM) override;
bool onContextMenu(HWND, int, int) override;
- static int adjustWidth(int);
void setExStyle(int style, bool enable = true);
void setSortArrow(bool);
void handleDoubleClick();
@@ -191,15 +193,15 @@ private:
void reindexVisible();
void filter();
+ int m_dirty;
+ Filter m_filter;
+
bool m_customizable;
std::vector<Column> m_cols;
std::vector<RowPtr> m_rows;
boost::optional<Sort> m_sort;
boost::optional<Sort> m_defaultSort;
- Filter m_filter;
- int m_dirty;
-
VoidSignal m_onSelect;
VoidSignal m_onActivate;
MenuSignal m_onContextMenu;
diff --git a/src/manager.cpp b/src/manager.cpp
@@ -65,11 +65,11 @@ void Manager::onInit()
disable(m_apply);
m_list = createControl<ListView>(IDC_LIST, ListView::Columns{
- {"Name", 115},
- {"Index URL", 415},
- {"State", 60},
+ {"Name", 145},
+ {"Index URL", 445},
});
+ m_list->enableIcons();
m_list->onActivate(bind(&Manager::aboutRepo, this, true));
m_list->onSelect(bind(&Dialog::startTimer, this, 100, 0, true));
m_list->onContextMenu(bind(&Manager::fillContextMenu, this, _1, _2));
@@ -327,20 +327,15 @@ void Manager::refresh()
int c = 0;
auto row = m_list->createRow();
+ row->setChecked(isRemoteEnabled(remote));
row->setCell(c++, remote.name());
row->setCell(c++, remote.url());
- updateEnabledCell(row->index(), remote);
if(find(selected.begin(), selected.end(), remote.name()) != selected.end())
m_list->select(row->index());
}
}
-void Manager::updateEnabledCell(int index, const Remote &remote)
-{
- m_list->row(index)->setCell(2, isRemoteEnabled(remote) ? "Enabled" : "Disabled");
-}
-
void Manager::setMods(const ModsCallback &cb, const bool updateRow)
{
ListView::BeginEdit edit(m_list);
@@ -371,7 +366,7 @@ void Manager::setMods(const ModsCallback &cb, const bool updateRow)
}
if(updateRow)
- updateEnabledCell(index, remote);
+ m_list->row(index)->setChecked(isRemoteEnabled(remote)); // TODO: move into cb
}
}
diff --git a/src/manager.hpp b/src/manager.hpp
@@ -56,7 +56,6 @@ private:
Remote getRemote(int index) const;
bool fillContextMenu(Menu &, int index) const;
- void updateEnabledCell(int index, const Remote &);
void setMods(const ModsCallback &, bool updateRow);
void setRemoteEnabled(bool);
bool isRemoteEnabled(const Remote &) const;
diff --git a/src/resource.rc b/src/resource.rc
@@ -33,7 +33,7 @@ BEGIN
LTEXT "The repositories enabled in this list are used to populate the package list:",
IDC_LABEL, 5, 5, 360, 10
CONTROL "", IDC_LIST, WC_LISTVIEW, LVS_REPORT | LVS_SHOWSELALWAYS |
- WS_BORDER | WS_TABSTOP, 5, 18, 360, 200
+ LVS_SHAREIMAGELISTS | WS_BORDER | WS_TABSTOP, 5, 18, 360, 200
PUSHBUTTON "&Browse packages", IDC_BROWSE, 5, 221, 75, 14
PUSHBUTTON "&Import/export...", IDC_IMPORT, 83, 221, 65, 14
PUSHBUTTON "&Options...", IDC_OPTIONS, 151, 221, 45, 14
diff --git a/win32.tup b/win32.tup
@@ -25,7 +25,7 @@ SQLFLAGS += /DSQLITE_OMIT_COMPILEOPTION_DIAGS /DSQLITE_OMIT_CAST
SQLFLAGS += /DSQLITE_OMIT_CHECK /DSQLITE_OMIT_DECLTYPE /DSQLITE_OMIT_DEPRECATED
LD := $(WRAP) link
-LDFLAGS := /nologo User32.lib Shell32.lib Gdi32.lib Comdlg32.lib
+LDFLAGS := /nologo User32.lib Shell32.lib Gdi32.lib Comdlg32.lib Comctl32.lib
LDFLAGS += vendor/libcurl@(SUFFIX)/lib/libcurl_a.lib
LDFLAGS += $(TUP_VARIANTDIR)/src/resource.res
LDFLAGS += $(TUP_VARIANTDIR)/build/vendor/sqlite3.o