development version (master branch)
Overview
Examples
Screenshots
Comparisons
Applications
Download
Documentation
Tutorials
UppHub
Status & Roadmap
FAQ
Authors & License
Forums
Funding U++
Search on this site











SourceForge.net Logo

SourceForge.net Logo

GitHub Logo

Discord Logo

ThemeChangeSensitive

 

 

 

 

MyApp.h

 

#ifndef _SkinSensitive_SkinSensitive_h

#define _SkinSensitive_SkinSensitive_h

 

#include <CtrlLib/CtrlLib.h>

 

using namespace Upp;

 

#define LAYOUTFILE <SkinSensitive/SkinSensitive.lay>

#include <CtrlCore/lay.h>

 

class SkinSensitive : public WithSkinSensitiveLayout<TopWindow> {

public:

    SkinSensitive();

};

 

#endif

 

 

 

main.cpp

 

#include <CtrlLib/CtrlLib.h>

 

#ifndef _SkinSensitive_SkinSensitive_h

#define _SkinSensitive_SkinSensitive_h

 

#include <CtrlLib/CtrlLib.h>

 

using namespace Upp;

 

#define LAYOUTFILE <ThemeChangeSensitive/MyApp.lay>

#include <CtrlCore/lay.h>

 

struct MyApp : public WithMyAppLayout<TopWindow> {

    virtual void Skin();

    

    Image MakeImage();

    

    MyApp();

};

 

#endif

 

Image MyApp::MakeImage()

{ // make some image in a way that reflects dark/light mode

    Size sz = CtrlImg::HandCursor().GetSize();

    ImageDraw iw(sz.cx, sz.cy);

    iw.DrawRect(sz, SColorFace());

    iw.DrawImage(0, 0, CtrlImg::HandCursor()); // HandCursor is adjusted wrt dark/light

    iw.DrawRect(sz.cx / 2, sz.cy / 2, DPI(5), DPI(5), SColorHighlight()); // SColorHighlight is adjusted wrt dark/light

    return iw;

}

 

void MyApp::Skin()

{ // called on opening window and on theme change

    list4.Clear(); // just refill the list with new colors

    list4.Add(AttrText("Blend(SRed, SYellow)").NormalInk(Blend(SRed(), SYellow())).Bold());

    list4.Add(AttrText("SLtBlue").NormalInk(SBlue().Resolved()).Bold()); // Resolved converts SBlue to normal color, just as does Blend

    list4.Add(AttrText("Blend(SRed, SLtBlue)").NormalInk(Blend(SRed(), SLtBlue())).Bold());

    

    img3.SetImage(MakeImage());

}

 

MyApp::MyApp()

{

    CtrlLayout(*this, "How to dynamically react to theme changes");

    list1.AddColumn("Ignoring skin change");

    list1.NoCursor();

    list1.Add(AttrText("Blend(Red, Yellow)").NormalInk(Blend(SRed(), SYellow())).Bold());

    list1.Add(AttrText("SBlue").NormalInk(SBlue().Resolved()).Bold()); // Resolved converts SBlue to normal color, just as does Blend, for testing

    list1.Add(AttrText("Blend(Red, LtBlue)").NormalInk(Blend(SRed(), SLtBlue())).Bold());

    

    list2.AddColumn("Using AColor");

    list2.NoCursor();

    list2.Add(AttrText("Blend(Red, Yellow)").NormalInk(AColor(Blend(Red(), Yellow()))).Bold()); // Light theme color that gets adjusted if theme is dark

    list2.Add(AttrText("SLtBlue").NormalInk(AColor(Blue())).Bold());

    list2.Add(AttrText("Blend(Red, LtBlue)").NormalInk(AColor(Blend(Red(), LtBlue()))).Bold());

 

    list3.AddColumn("Using SColor");

    list3.NoCursor();

    static SColor ry([] { return Blend(SRed(), SYellow()); }); // Gets reevaluated on skin change

    static SColor rb([] { return Blend(SRed(), SLtBlue()); });

    list3.Add(AttrText("Blend(Red, Yellow)").NormalInk(ry).Bold());

    list3.Add(AttrText("SLtBlue").NormalInk(SBlue()).Bold()); // SBlue is different based on skin

    list3.Add(AttrText("Blend(Red, LtBlue)").NormalInk(rb).Bold());

    

    list4.AddColumn("Reloaded with Skin");

    list4.NoCursor();

    

    img1.SetImage(CtrlImg::HandCursor()); // iml image constants react to theme changes (even theirs copies)

    img2.SetImage(MakeImage()); // the image copy is stored just once and does not reflect theme changes

    

    std << [=] { Ctrl::SetSkin(ChStdSkin); };

    dark << [=] { Ctrl::SetSkin(ChDarkSkin); };

    host << [=] { Ctrl::SetSkin(ChHostSkin); };

    

    toggle << [=] { Ctrl::SwapDarkLight(); };

    

#ifndef _DEBUG

    info = "Predefined key for Toggle dark was set to Space";

#endif

}

 

GUI_APP_MAIN

{

#ifndef _DEBUG

    Ctrl::SwapDarkLightKey(K_SPACE); // just to demonstrate that toggle key can be activated in Release mode too and/or different

#endif

 

    Ctrl::SkinChangeSensitive(); // activate changes of skin (theme) when host theme changes

    MyApp().Run();

}

 

 

 

MyApp.lay

 

LAYOUT(MyAppLayout, 644, 348)

    ITEM(Upp::ArrayCtrl, list1, LeftPosZ(4, 156).TopPosZ(4, 148))

    ITEM(Upp::ArrayCtrl, list2, LeftPosZ(164, 156).TopPosZ(4, 148))

    ITEM(Upp::ArrayCtrl, list3, LeftPosZ(324, 156).TopPosZ(4, 148))

    ITEM(Upp::ArrayCtrl, list4, LeftPosZ(484, 156).TopPosZ(4, 148))

    ITEM(Upp::Button, std, SetLabel(t_("Set Standard skin")).LeftPosZ(4, 112).TopPosZ(284, 24))

    ITEM(Upp::Button, dark, SetLabel(t_("Set Standard dark skin")).LeftPosZ(120, 140).TopPosZ(284, 24))

    ITEM(Upp::Button, host, SetLabel(t_("Set Host platform skin")).LeftPosZ(264, 140).TopPosZ(284, 24))

    ITEM(Upp::Button, toggle, SetLabel(t_("Toggle dark")).LeftPosZ(4, 104).TopPosZ(316, 24))

    ITEM(Upp::Label, info, SetLabel(t_("In debug mode, the prefined key for Toggle dark is Ctrl+Num[*]")).LeftPosZ(112, 328).TopPosZ(316, 24))

    ITEM(Upp::ImageCtrl, img1, LeftPosZ(4, 60).TopPosZ(156, 36))

    ITEM(Upp::ImageCtrl, img2, LeftPosZ(4, 60).TopPosZ(196, 36))

    ITEM(Upp::ImageCtrl, img3, LeftPosZ(4, 60).TopPosZ(236, 36))

    ITEM(Upp::Label, dv___12, SetLabel(t_("This image is sourced as iml constant and automatically adjusts to theme changes")).LeftPosZ(68, 452).TopPosZ(156, 36))

    ITEM(Upp::Label, dv___13, SetLabel(t_("This image is created and does not change when theme changes")).LeftPosZ(68, 452).TopPosZ(196, 36))

    ITEM(Upp::Label, dv___14, SetLabel(t_("This image is created but is changed by Skin method")).LeftPosZ(68, 452).TopPosZ(236, 36))

END_LAYOUT

 

 

 

 

SkinSensitive.lay

 

LAYOUT(MyAppLayout, 200, 100)

END_LAYOUT

 

 

 

 

 

Do you want to contribute?