[LyX/master] Let branch color accept alpha values
Koji Yokota
yokota at lyx.org
Sun Jun 7 02:24:21 UTC 2026
commit ff4a7c4c53b4104c827fe7e6999d61699b3a341f
Author: Koji Yokota <yokota at lyx.org>
Date: Fri Jun 5 21:07:34 2026 +0900
Let branch color accept alpha values
---
src/BranchList.cpp | 15 +++++++++------
src/BranchList.h | 2 +-
src/Color.cpp | 11 +++++++++++
src/Color.h | 2 ++
src/frontends/Application.h | 2 ++
src/frontends/qt/ColorCache.cpp | 6 ++++++
src/frontends/qt/ColorCache.h | 2 ++
src/frontends/qt/GuiApplication.cpp | 17 +++++++++++++++++
src/frontends/qt/GuiApplication.h | 1 +
src/frontends/qt/GuiBranches.cpp | 29 +++++++++++++++++------------
src/frontends/qt/GuiBranches.h | 2 ++
src/frontends/qt/GuiDocument.cpp | 10 +++++-----
12 files changed, 75 insertions(+), 24 deletions(-)
diff --git a/src/BranchList.cpp b/src/BranchList.cpp
index 557a36175e..66b5bbc3bb 100644
--- a/src/BranchList.cpp
+++ b/src/BranchList.cpp
@@ -104,11 +104,11 @@ void Branch::setColor(string const & col)
void Branch::setColors(string const & lmcol, string const & dmcol)
{
if (lmcol.empty() && lmcolor_ == "background" && support::prefixIs(dmcol, "#"))
- lmcolor_ = X11hexname(inverseRGBColor(rgbFromHexName(dmcol)));
+ lmcolor_ = X11hexname(inverseARGBColor(argbFromHexName(dmcol)));
else if (!lmcol.empty())
lmcolor_ = lmcol;
if (dmcol.empty() && dmcolor_ == "background" && support::prefixIs(lmcol, "#"))
- dmcolor_ = X11hexname(inverseRGBColor(rgbFromHexName(lmcol)));
+ dmcolor_ = X11hexname(inverseARGBColor(argbFromHexName(lmcol)));
else if (!dmcol.empty())
dmcolor_ = dmcol;
@@ -118,13 +118,16 @@ void Branch::setColors(string const & lmcol, string const & dmcol)
if (lmcolor == "none")
lmcolor = "background";
// if we have background color, keep semantic value, as system colors might vary
- else if (lmcolor != "background" && (lmcolor.size() != 7 || lmcolor[0] != '#'))
- lmcolor = lcolor.getX11HexName(lcolor.getFromLyXName(lmcolor));
+ else if (lmcolor != "background" &&
+ ((lmcolor.size() != 7 && lmcolor.size() != 9) || lmcolor[0] != '#'))
+ lmcolor = lcolor.get32bitHexName(lcolor.getFromLyXName(lmcolor));
if (dmcolor == "none")
dmcolor = "background";
// if we have background color, keep semantic value, as system colors might vary
- else if (dmcolor != "background" && (dmcolor.size() != 7 || dmcolor[0] != '#'))
- dmcolor = lcolor.getX11HexName(lcolor.getFromLyXName(dmcolor), true);
+ else if (dmcolor != "background" &&
+ ((dmcolor.size() != 7 && dmcolor.size() != 9) || dmcolor[0] != '#')) {
+ dmcolor = lcolor.get32bitHexName(lcolor.getFromLyXName(dmcolor), true);
+ }
// FIXME UNICODE
lcolor.setColor("branch" + convert<string>(branch_list_id_)
diff --git a/src/BranchList.h b/src/BranchList.h
index 0678563cb7..7d6d3874e6 100644
--- a/src/BranchList.h
+++ b/src/BranchList.h
@@ -67,7 +67,7 @@ public:
///
std::string const & darkModeColor() const;
/**
- * Set background color from a hexcolor string "#rrggbb" or a lyx color name.
+ * Set background color from a hexcolor string "#aarrggbb" or a lyx color name.
* Use Color:background if the string is no valid color.
* This ensures compatibility with LyX 1.4.0 that had the symbolic
* color "none" that was displayed as Color:background.
diff --git a/src/Color.cpp b/src/Color.cpp
index a032fa8f20..df20600729 100644
--- a/src/Color.cpp
+++ b/src/Color.cpp
@@ -207,6 +207,17 @@ RGBColor const inverseRGBColor(RGBColor color)
}
+ARGBColor const inverseARGBColor(ARGBColor color)
+{
+ // color.a is unchanged
+ color.r = 255 - color.r;
+ color.g = 255 - color.g;
+ color.b = 255 - color.b;
+
+ return color;
+}
+
+
Color::Color(ColorCode base_color) : baseColor(base_color),
mergeColor(Color_ignore)
{}
diff --git a/src/Color.h b/src/Color.h
index 94df2bff3b..186f16563d 100644
--- a/src/Color.h
+++ b/src/Color.h
@@ -72,6 +72,8 @@ std::string const outputLaTeXColor(RGBColor const & color);
RGBColor const RGBColorFromLaTeX(std::string const & color);
/// Inverted color
RGBColor const inverseRGBColor(RGBColor color);
+/// Inverted color: alpha value is unchanged
+ARGBColor const inverseARGBColor(ARGBColor color);
} // namespace lyx
diff --git a/src/frontends/Application.h b/src/frontends/Application.h
index 615cca5150..58daba8c81 100644
--- a/src/frontends/Application.h
+++ b/src/frontends/Application.h
@@ -201,6 +201,8 @@ public:
* It returns false on failure and sets r, g, b to 0.
*/
virtual bool getRgbColor(ColorCode col, RGBColor & rgbcol) = 0;
+ /// ARGB version
+ virtual bool getArgbColor(ColorCode col, ARGBColor & argbcol) = 0;
/// Like getRgbColor(), but static and slower
static bool getRgbColorUncached(ColorCode col, RGBColor & rgbcol);
diff --git a/src/frontends/qt/ColorCache.cpp b/src/frontends/qt/ColorCache.cpp
index 4955aaf3ce..357548f27f 100644
--- a/src/frontends/qt/ColorCache.cpp
+++ b/src/frontends/qt/ColorCache.cpp
@@ -218,4 +218,10 @@ QColor const rgb2qcolor(RGBColor const & rgb)
}
+QColor const argb2qcolor(ARGBColor const & argb)
+{
+ return QColor(argb.r, argb.g, argb.b, argb.a);
+}
+
+
} // namespace lyx
diff --git a/src/frontends/qt/ColorCache.h b/src/frontends/qt/ColorCache.h
index 17e70a737d..b0d140e147 100644
--- a/src/frontends/qt/ColorCache.h
+++ b/src/frontends/qt/ColorCache.h
@@ -76,6 +76,8 @@ private:
///
QColor const rgb2qcolor(RGBColor const &);
+///
+QColor const argb2qcolor(ARGBColor const &);
} // namespace lyx
diff --git a/src/frontends/qt/GuiApplication.cpp b/src/frontends/qt/GuiApplication.cpp
index f3070c525d..535404ccc0 100644
--- a/src/frontends/qt/GuiApplication.cpp
+++ b/src/frontends/qt/GuiApplication.cpp
@@ -3112,6 +3112,23 @@ bool GuiApplication::getRgbColor(ColorCode col, RGBColor & rgbcol)
return true;
}
+bool GuiApplication::getArgbColor(ColorCode col, ARGBColor &argbcol)
+{
+ QColor const & qcol = d->color_cache_.get(col);
+ if (!qcol.isValid()) {
+ argbcol.a = 0;
+ argbcol.r = 0;
+ argbcol.g = 0;
+ argbcol.b = 0;
+ return false;
+ }
+ argbcol.a = qcol.alpha();
+ argbcol.r = qcol.red();
+ argbcol.g = qcol.green();
+ argbcol.b = qcol.blue();
+ return true;
+}
+
bool Application::getRgbColorUncached(ColorCode col, RGBColor & rgbcol)
{
diff --git a/src/frontends/qt/GuiApplication.h b/src/frontends/qt/GuiApplication.h
index db84925ca9..3f03ad1458 100644
--- a/src/frontends/qt/GuiApplication.h
+++ b/src/frontends/qt/GuiApplication.h
@@ -74,6 +74,7 @@ public:
void exit(int status) override;
bool event(QEvent * e) override;
bool getRgbColor(ColorCode col, RGBColor & rgbcol) override;
+ bool getArgbColor(ColorCode col, ARGBColor & argbcol) override;
bool isInDarkMode() override;
bool isLightColor(RGBColor const & rgb) override;
std::string const hexName(ColorCode col) override;
diff --git a/src/frontends/qt/GuiBranches.cpp b/src/frontends/qt/GuiBranches.cpp
index c85eb6789f..5d6d88a687 100644
--- a/src/frontends/qt/GuiBranches.cpp
+++ b/src/frontends/qt/GuiBranches.cpp
@@ -76,6 +76,8 @@ GuiBranches::GuiBranches(QWidget * parent)
newBranchLE->installEventFilter(this);
newBranchLE->setValidator(new NoNewLineValidator(newBranchLE));
+
+ colorbg_ = ColorCache::setSwatchBackground(30, 10);
}
@@ -134,15 +136,16 @@ void GuiBranches::updateView()
newItem->setText(1, it->isSelected() ? qt_("Yes") : qt_("No"));
std::string bcolor = it->color();
- RGBColor rgbcol;
- if (bcolor.size() == 7 && bcolor[0] == '#')
- rgbcol = lyx::rgbFromHexName(bcolor);
+ ARGBColor argbcol;
+ if ((bcolor.size() == 7 || bcolor.size() == 9) && bcolor[0] == '#')
+ argbcol = lyx::argbFromHexName(bcolor);
else
- guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
- QColor const itemcolor = rgb2qcolor(rgbcol);
+ guiApp->getArgbColor(lcolor.getFromLyXName(bcolor), argbcol);
+ QColor const itemcolor = argb2qcolor(argbcol);
if (itemcolor.isValid()) {
QPixmap coloritem(30, 10);
coloritem.fill(itemcolor);
+ coloritem = ColorCache::mergePixmaps(&coloritem, &colorbg_);
newItem->setIcon(2, QIcon(coloritem));
}
newItem->setText(3, it->hasFileNameSuffix() ? qt_("Yes") : qt_("No"));
@@ -371,19 +374,21 @@ void GuiBranches::toggleColor(QTreeWidgetItem * item)
if (!branch)
return;
+ // bcolor can be 16bit- or 32bit-hex for backward compatibility
std::string bcolor = branch->color();
- RGBColor rgbcol;
- if (bcolor.size() == 7 && bcolor[0] == '#')
- rgbcol = lyx::rgbFromHexName(bcolor);
+ ARGBColor argbcol;
+ if ((bcolor.size() == 9 || bcolor.size() == 7) && bcolor[0] == '#')
+ argbcol = lyx::argbFromHexName(bcolor);
else
- guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
- QColor const initial = rgb2qcolor(rgbcol);
- QColor ncol = GuiDialog::getColor(initial, this);
+ guiApp->getArgbColor(lcolor.getFromLyXName(bcolor), argbcol);
+ QColor const initial = argb2qcolor(argbcol);
+ QColor ncol = GuiDialog::getColor(initial, this, QString(),
+ QColorDialog::ShowAlphaChannel);
if (!ncol.isValid())
return;
// add the color to the branchlist
- branch->setColor(fromqstr(ncol.name()));
+ branch->setColor(fromqstr(ncol.name(QColor::HexArgb)));
newBranchLE->clear();
updateView();
}
diff --git a/src/frontends/qt/GuiBranches.h b/src/frontends/qt/GuiBranches.h
index 64cf83f889..684161d3b1 100644
--- a/src/frontends/qt/GuiBranches.h
+++ b/src/frontends/qt/GuiBranches.h
@@ -87,6 +87,8 @@ private:
ButtonController undef_bc_;
///
QStringList unknown_branches_;
+ ///
+ QPixmap colorbg_;
};
} // namespace frontend
diff --git a/src/frontends/qt/GuiDocument.cpp b/src/frontends/qt/GuiDocument.cpp
index ea19171bf3..65e5239b1f 100644
--- a/src/frontends/qt/GuiDocument.cpp
+++ b/src/frontends/qt/GuiDocument.cpp
@@ -5353,12 +5353,12 @@ void GuiDocument::dispatchParams()
docstring const & current_branch = it->branch();
Branch const * branch = branchlist.find(current_branch);
string const bcolor = branch->color();
- RGBColor rgbcol;
- if (bcolor.size() == 7 && bcolor[0] == '#')
- rgbcol = lyx::rgbFromHexName(bcolor);
+ ARGBColor argbcol;
+ if ((bcolor.size() == 7 || bcolor.size() ==9) && bcolor[0] == '#')
+ argbcol = lyx::argbFromHexName(bcolor);
else
- guiApp->getRgbColor(lcolor.getFromLyXName(bcolor), rgbcol);
- string const x11hexname = X11hexname(rgbcol);
+ guiApp->getArgbColor(lcolor.getFromLyXName(bcolor), argbcol);
+ string const x11hexname = X11hexname(argbcol);
// display the new color
docstring const str = current_branch + ' ' + from_ascii(x11hexname);
dispatch(FuncRequest(LFUN_SET_COLOR, str));
More information about the lyx-cvs
mailing list