From a508ad751f7b7b0ec460b14833872085a99fc8cc Mon Sep 17 00:00:00 2001 From: Ichthyostega Date: Sun, 4 Aug 2019 17:00:18 +0200 Subject: [PATCH] Investigation: clarify handling of CSS3 box-shadow for custom drawing - CSS3 effects like box-shadow are applied with the StyleContext::render_background() function * first, an outset box-shadow is rendered _outside_ the box given as parameter to `render_background()` * then the box is filled with the background colour * and last, an inset box-shadow is rendered _inside_ the area of a would-be border, without rendering the border itself. * consequently we can not shade the border itself and we can not shade the content --- research/gtk-style-experiment.cpp | 45 +++++---- research/gtk-style-experiment.css | 7 +- wiki/thinkPad.ichthyo.mm | 158 +++++++++++++++++++++++++----- 3 files changed, 164 insertions(+), 46 deletions(-) diff --git a/research/gtk-style-experiment.cpp b/research/gtk-style-experiment.cpp index 466919197..69b4ecce2 100644 --- a/research/gtk-style-experiment.cpp +++ b/research/gtk-style-experiment.cpp @@ -29,10 +29,24 @@ ** ## Setup for investigation ** - add a separate dummy Gtk::Frame widget as `testFrame_` ** - apply custom styling to that frame, by virtue of a CSS class '.experiment' - ** - pick up the Gtk::StyleContext of that `testFrame_` - ** - use this style context to draw a custom frame onto the canvas + ** - pick up the Gtk::StyleContext of that `testFrame_` to get the CSS path + ** - build a "free standing" new Gtk::StyleContext and apply the CSS path found + ** - use this style context to draw a custom frame and background onto the canvas ** - control extension of that custom drawing through the top margin CSS setting of testFrame_ ** + ** ## Findings + ** - it works as intended + ** - however, care must be taken to apply CSS cascading properly (generic vs specific selectors) + ** - the context_save/restore functionality seems to be broken on a "free standing" style context; + ** however it works as expected on a style context associated to an existing and realised widget. + ** - workaround is to add / remove classes explicitly. + ** - CSS3 effects like box-shadow are applied with the StyleContext::render_background() function + ** * first, an outset box-shadow is rendered _outside_ the box given as parameter to `render_background()` + ** * then the box is filled with the background colour + ** * and last, an inset box-shadow is rendered _inside_ the area of a would-be border, + ** without rendering the border itself. + ** * consequently we can not shade the border itself and we can not shade the content + ** ** @see stage::timeline::BodyCanvasWidget */ @@ -44,7 +58,6 @@ #include "lib/error.hpp" #include "lib/util.hpp" -#include ////////////////////TODO WIP #include using util::cStr; @@ -55,7 +68,7 @@ namespace research { namespace { const string STYLESHEET_NAME{"gtk-style-experiment.css"}; - const string RESOURCE_PATH{"$ORIGIN/gui"}; + const string RESOURCE_PATH {"$ORIGIN/gui"}; const string CLASS_experiment{"experiment"}; const string CLASS_slopeDeep1{"track-slope-deep1"}; @@ -221,7 +234,6 @@ namespace research { PStyleContext style = Gtk::StyleContext::create(); style->set_screen(Gdk::Screen::get_default()); style->set_path(path); -// style->add_class(slopeClassName(2)); return style; } @@ -246,10 +258,9 @@ namespace research { cout << "style.path: " << canvas_.xObservedPath <get_margin().get_top(); - auto path = style_->get_path(); if (xBorderSiz > 1) { -// style_->invalidate(); -// style_->context_save(); -// style_->set_screen(Gdk::Screen::get_default()); -// style_->set_path(path); -// style_->invalidate(); - style_->add_class(slopeClassName(xBorderSiz)); +// style_->context_save(); // <<<---does not work. Asked on SO: https://stackoverflow.com/q/57342478 + style_->add_class(slopeClassName(xBorderSiz)); } xObservedSize = style_->get_border().get_top(); @@ -341,6 +345,13 @@ namespace research { ,50 // width of the area ,height // height to fill ); + // NOTE: all box-shadow effects are rendered *here* + style_->render_background (cox + ,40 + ,60 + ,80 + ,height + ); if (xBorderSiz > 1) { // style_->context_restore(); diff --git a/research/gtk-style-experiment.css b/research/gtk-style-experiment.css index 493fa4d36..c03f55edd 100644 --- a/research/gtk-style-experiment.css +++ b/research/gtk-style-experiment.css @@ -28,10 +28,12 @@ * This styling will be picked up by our custom drawing code */ frame.experiment { - margin: 4ex 0; + margin: 2em 1ex 0; border-style: inset; border-color: IndianRed; background-color: Lime; + box-shadow: inset 2px 2px 5px 1px DeepSkyBlue, + 5px 5px 2px 10px DeepPink; } .track-slope-deep1 { border-width: 5px; @@ -39,8 +41,9 @@ .track-slope-deep2 { border-width: 10px; } - .track-slope-deep3 { + frame.track-slope-deep3 { border-width: 14px; + border-color: Cyan; } .track-slope-deep4 { border-width: 17px; diff --git a/wiki/thinkPad.ichthyo.mm b/wiki/thinkPad.ichthyo.mm index 40a4b9859..11c045521 100644 --- a/wiki/thinkPad.ichthyo.mm +++ b/wiki/thinkPad.ichthyo.mm @@ -22861,10 +22861,8 @@ - - - - + + @@ -22903,7 +22901,9 @@ - + + + @@ -22926,22 +22926,15 @@ - - - - - - - - - - - + + + + - - + + @@ -23026,8 +23019,8 @@ - - + + @@ -23077,8 +23070,19 @@ - - + + + + + + + + + + + + + @@ -23091,8 +23095,68 @@ + + + + + + + + + + + +
    +
  • + Gut ist es insofern, daß man mit einem render_background bereits alles bekommt +
  • +
  • + allerdings muß der Rahmen dann ganz genau passend darüber gezeichnet werden +
  • +
  • + man kann damit weder den Rahmen schattieren, noch den enthaltenen Content +
  • +
+

+ allerdings verhält sich das normale Zeichnen ganz genauso; das sind allgemeine Einschränkungen (von CSS? GTK?) +

+ + +
+ +
+ + + + + + + + + + + + + + +

+ box-shadow (inset) innerhalb des Rechteckss, und innerhalb der (gedachten) border +

+ + +
+ +
+
+
+
+
+ + + +
@@ -44705,6 +44769,37 @@
+ + + + + + + + + + + + +

+ <offX> <offY> [<blur> [<spread>]] <colour> +

+ + +
+
+ + + + + + + + + + + + @@ -46191,8 +46286,8 @@ - - + + @@ -46201,7 +46296,7 @@ - + @@ -46508,18 +46603,27 @@ - + + + + + - + + + + + +