Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feacture Request] Customize the look and feel by widget #71

Open
sirlordt opened this issue Mar 10, 2022 · 5 comments
Open

[Feacture Request] Customize the look and feel by widget #71

sirlordt opened this issue Mar 10, 2022 · 5 comments

Comments

@sirlordt
Copy link

Is possible make api to do something like "skins"?. I mean to change the look and feel by widget not only the color.

Maybe a setter where you can set to the widget witch char use to draw the border, the shadow. In the window widget can be nice you can set the position of the buttons. For example move the close button from the left to the right. Aside right from maximize button and change the icon to X.

O even better define custom button to attach to upper left, upper right, lower left, lower right to the window widget.

You can change from "Turbo Vision Style" to "Ubuntu Style":

image

O maybe to "Ubuntu Server Setup Style":

image

Thanks!!!.

@magiblot
Copy link
Owner

magiblot commented Mar 10, 2022

Ideally, there could be an external widgets library with a custom TFrame which allows you to change skins easily. Unfortunately, I don't have the time to do something like this.

But maybe there is one thing that can be done. In the file source/tvision/tvtext1.cpp there are the definitions of the border chars of several views. For example, TFrame::frameChars:

char _NEAR TFrame::frameChars[33] =
    "   \xC0 \xB3\xDA\xC3 \xD9\xC4\xC1\xBF\xB4\xC2\xC5   \xC8 \xBA\xC9\xC7 \xBC\xCD\xCF\xBB\xB6\xD1 "; // for UnitedStates code page

These chars are encoded in codepage 437. Actually, the string looks like this:

"   └ │┌├ ┘─┴┐┤┬┼   ╚ ║╔╟ ╝═╧╗╢╤ "

Or, in vertical:

TFrame::frameChars[0]   = ' '
TFrame::frameChars[1]   = ' '
TFrame::frameChars[2]   = ' '
TFrame::frameChars[3]   = ''
TFrame::frameChars[4]   = ' '
TFrame::frameChars[5]   = ''
TFrame::frameChars[6]   = ''
TFrame::frameChars[7]   = ''
TFrame::frameChars[8]   = ' '
TFrame::frameChars[9]   = ''
TFrame::frameChars[10]  = ''
TFrame::frameChars[11]  = ''
TFrame::frameChars[12]  = ''
TFrame::frameChars[13]  = ''
TFrame::frameChars[14]  = ''
TFrame::frameChars[15]  = ''
TFrame::frameChars[16]  = ' '
TFrame::frameChars[17]  = ' '
TFrame::frameChars[18]  = ' '
TFrame::frameChars[19]  = ''
TFrame::frameChars[20]  = ' '
TFrame::frameChars[21]  = ''
TFrame::frameChars[22]  = ''
TFrame::frameChars[23]  = ''
TFrame::frameChars[24]  = ' '
TFrame::frameChars[25]  = ''
TFrame::frameChars[26]  = ''
TFrame::frameChars[27]  = ''
TFrame::frameChars[28]  = ''
TFrame::frameChars[29]  = ''
TFrame::frameChars[30]  = ''
TFrame::frameChars[31]  = ' '

Therefore, it would be possible to change the skin by changing these arrays. Unfortunately, these arrays are private members.

You can cheat and write something like this in a file which doesn't include <tvision/tv.h>:

class TFrame
{
public:

    static char frameChars[33];
    static const char * closeIcon;
    static const char * zoomIcon;
    static const char * unZoomIcon;
};

void useCustomSkin()
{
    TFrame::frameChars[19]  = '\xC0';
    TFrame::frameChars[21]  = '\xB3';
    TFrame::frameChars[22]  = '\xDA';
    TFrame::frameChars[23]  = '\xC3';
    TFrame::frameChars[25]  = '\xD9';
    TFrame::frameChars[26]  = '\xC4';
    TFrame::frameChars[27]  = '\xC1';
    TFrame::frameChars[28]  = '\xBF';
    TFrame::frameChars[29]  = '\xB4';
    TFrame::frameChars[30]  = '\xC2';
    TFrame::closeIcon       = "\xB4~X~\xC3";
    TFrame::zoomIcon        = "\xB4~\x18~\xC3";
    TFrame::unZoomIcon      = "\xB4~\x12~\xC3";
}

Then you will get something like this:
Screenshot_20220310_213041

@sirlordt
Copy link
Author

Ok thanks, Let me try,

@WillianBR
Copy link

Ideally, there could be an external widgets library with a custom TFrame which allows you to change skins easily. Unfortunately, I don't have the time to do something like this.

But maybe there is one thing that can be done. In the file source/tvision/tvtext1.cpp there are the definitions of the border chars of several views. For example, TFrame::frameChars:

char _NEAR TFrame::frameChars[33] =
    "   \xC0 \xB3\xDA\xC3 \xD9\xC4\xC1\xBF\xB4\xC2\xC5   \xC8 \xBA\xC9\xC7 \xBC\xCD\xCF\xBB\xB6\xD1 "; // for UnitedStates code page

These chars are encoded in codepage 437. Actually, the string looks like this:

"   └ │┌├ ┘─┴┐┤┬┼   ╚ ║╔╟ ╝═╧╗╢╤ "

Or, in vertical:

TFrame::frameChars[0]   = ' '
TFrame::frameChars[1]   = ' '
TFrame::frameChars[2]   = ' '
TFrame::frameChars[3]   = ''
TFrame::frameChars[4]   = ' '
TFrame::frameChars[5]   = ''
TFrame::frameChars[6]   = ''
TFrame::frameChars[7]   = ''
TFrame::frameChars[8]   = ' '
TFrame::frameChars[9]   = ''
TFrame::frameChars[10]  = ''
TFrame::frameChars[11]  = ''
TFrame::frameChars[12]  = ''
TFrame::frameChars[13]  = ''
TFrame::frameChars[14]  = ''
TFrame::frameChars[15]  = ''
TFrame::frameChars[16]  = ' '
TFrame::frameChars[17]  = ' '
TFrame::frameChars[18]  = ' '
TFrame::frameChars[19]  = ''
TFrame::frameChars[20]  = ' '
TFrame::frameChars[21]  = ''
TFrame::frameChars[22]  = ''
TFrame::frameChars[23]  = ''
TFrame::frameChars[24]  = ' '
TFrame::frameChars[25]  = ''
TFrame::frameChars[26]  = ''
TFrame::frameChars[27]  = ''
TFrame::frameChars[28]  = ''
TFrame::frameChars[29]  = ''
TFrame::frameChars[30]  = ''
TFrame::frameChars[31]  = ' '

Therefore, it would be possible to change the skin by changing these arrays. Unfortunately, these arrays are private members.

You can cheat and write something like this in a file which doesn't include <tvision/tv.h>:

class TFrame
{
public:

    static char frameChars[33];
    static const char * closeIcon;
    static const char * zoomIcon;
    static const char * unZoomIcon;
};

void useCustomSkin()
{
    TFrame::frameChars[19]  = '\xC0';
    TFrame::frameChars[21]  = '\xB3';
    TFrame::frameChars[22]  = '\xDA';
    TFrame::frameChars[23]  = '\xC3';
    TFrame::frameChars[25]  = '\xD9';
    TFrame::frameChars[26]  = '\xC4';
    TFrame::frameChars[27]  = '\xC1';
    TFrame::frameChars[28]  = '\xBF';
    TFrame::frameChars[29]  = '\xB4';
    TFrame::frameChars[30]  = '\xC2';
    TFrame::closeIcon       = "\xB4~X~\xC3";
    TFrame::zoomIcon        = "\xB4~\x18~\xC3";
    TFrame::unZoomIcon      = "\xB4~\x12~\xC3";
}

Then you will get something like this: Screenshot_20220310_213041

I'll definitely use this trick!

The block used to close the window is ugly and say nothing! People get use to a big [X] as the close button.

In the perfect world the classes shound have a setPallete() method!

@WillianBR
Copy link

@magiblot

I have one small question!

Do you got the TV original library and rewrote some parts?

Because it's required is huge effort to change the TV theme. I wanna change the button colors, but change the pallete require a few tricks!

I'm thinking about save the pallete on disk and when the app start, check if there's a pallete file and load it. Or may be I'll save the pallete to a byte array and if the file is missing, load from memory.

One more intrusive question.

Do you have time to a chat, one to one?

Where are you from?

I'm from Brazil (TZ -3).

@magiblot
Copy link
Owner

magiblot commented Jan 3, 2023

Changing the palette values for all views is relatively simple. For example, if I modify the constructor of THelloApp (hello.cpp) like this:

THelloApp::THelloApp() :
    TProgInit( &THelloApp::initStatusLine,
               &THelloApp::initMenuBar,
               &THelloApp::initDeskTop
             )
{
    TPalette &palette = getPalette();       /*  foregr.   backgr.  */
    palette[cpGrayDialog[3  - 1]] = TColorAttr(0xbf0303,    '\x7'); // Frame icon
    palette[cpGrayDialog[10 - 1]] = TColorAttr(0xffffff, 0xb218b2); // Button normal
    palette[cpGrayDialog[12 - 1]] = TColorAttr(0x00007f, 0xb218b2); // Button selected
}

Then I am able to make the dialog look like this:

Screenshot_20230103_015222

In order to write that I first had to look at dialogs.h, where it lists the palette entries for TDialog:

/* ---------------------------------------------------------------------- */
/* class TDialog */
/* */
/* Palette layout */
/* 1 = Frame passive */
/* 2 = Frame active */
/* 3 = Frame icon */
/* 4 = ScrollBar page area */
/* 5 = ScrollBar controls */
/* 6 = StaticText */
/* 7 = Label normal */
/* 8 = Label selected */
/* 9 = Label shortcut */
/* 10 = Button normal */
/* 11 = Button default */
/* 12 = Button selected */

What makes TPalettes difficult is that they are nested. They contain indices into other palettes. Therefore, as soon as you want to design a palette for a new class you created, it becomes really hard to get the palettes right.

For this reason I made the TView::mapColor method virtual. By overrding it in your custom classes, you can skip the nested palette lookup and return colors directly. But for standard classes, the simplest way to change their color is to modify the application's palette as I showed earlier.

All of this is explained in the Extended color support section of the README (in an expandable section at the end of the document).

Do you have time to a chat, one to one?

Where are you from?

I am from Spain. However, I would not like to communicate using my phone number; would you be comfortable using regular e-mails? ([email protected]).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants