top

How To Create Custom CAPH Theme

Published 2014-10-28 | (Compatible with SDK 5.1 and 2014 models)

A theme determines the overall look. Creating a unifying theme is one of the most important steps in designing an application. A good theme will flow easily throughout your application.

Overview

There are several themes in an application, and they can switch between each other. A class style file is a theme which defines the following elements:color, font-size, width, height, background etc.

Prerequisites

To introduce creating CAPH Application using custom theme, for example, you should include caph.wui dependencies, basic widget of UI, the base style of UI, and app source files in your application by putting the following code in the <head> and <body> sections of myTheme.html, just as follows:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<!DOCTYPE HTML>
<html>
<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
    <tltle>Theme</title>
	
    <!-- load caph-level1-unified.min.js -->
    <script src="$CAPH/1.0.0/caph-level1-unified.min.js"></script>
    <link href="$CAPH/1.0.0/caph.css" rel="stylesheet" type="text/stylesheet">
	
    <!-- load the app -->
    <script src="myTheme.js"></script>
</head>
<body onload="app.run();">
</body>
</html>

Source files mentioned above are explained in the following table.

File Description
caph-level1-unified.min.js It includes all kinds of basic widget of UI which will be used. It includes external libraries also.
caph.css The default class style of caph.wui.
myTheme.js The file created by you includes widgets in a theme.

Environment

In order to use Samsung Smart TV SDK and caph.wui to run your applications, you might need a text editor to create files that comprise HTML, JavaScript and CSS files for your application. Samsung Smart TV is required to verify if your application running well, but you can also use the emulator provided with the SDK to debug and test the applications before uploading them on to the TV device.

Source Files

Note

The files needed for the sample application are myTheme.html, myTheme.js, theme.css. To download source files, click here.

 

How to Develop

  • You need to define the necessary UI components and variables :
    1. Import namespace "caph.wui.widget.ThemeMgr";
    2. Create the theme object using the constructors "ThemeMgr()";
    3. Create two buttons to switch the theme.
  • You need to call the APIs to operate the theme :
    1. enableTheme : Enable a theme according themeName;
    2. disableTheme : Disable a theme according themeName;
    3. addTheme : Add a user theme. If one user theme has exist, next theme with the same name will cover previous existing theme;
    4. removeTheme : Remove a theme, current theme can't be removed.

The code is as follows :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/**
* caph.Wul Theme sample
*/

var app = app || {};

app.run = function() {
    app.handleLoad();
    //import the all namespaces
    var Page = caph.wui.widget.UIContext;
    var HighLight = caph.wui.widget.HighlightHelper;
    var ThemeMgr = caph.wui.widget.ThemeMgr;
    var Strip = caph.wui.widget.Strip;
    var InputBox = caph.wui.widget.InputBox;
    var ProgressBar = caph.wui.widget.ProgressBar;
    var Button = caph.wui.widget.Button;
    var Image = caph.wui.widget.Image;
    var ListWidget = caph.wui.widget.ListWidget;
    var Panel = caph.wui.widget.Panel;
	
    try {
        var page = new Page();
        var screen = window.innerHeight < window.innerWidth ? window.innerHeight : window.innerWidth;
        var ratio = screen / 1080;
        //the button's position
        var position = {
            'x' : 0 * ratio,
            'y' : 0 * ratio,
            'z' : 5
        };
        //new theme's object
        var themeMgrObj = new ThemeMgr();
        var firstTheme = 'caph';
        var secondTheme = 'secondTheme';
        //new theme's path
        var path = '$CAPH/1.0.0/caph.css';
        //add first theme
        themeMgrObj.addTheme(firstTheme, path);
        //enable first theme
        themeMgrObj.enableTheme(firstTheme);
        //new button
        var btnFristTheme = new Button({});
        //add click event listener for btnFirstTheme
        btnFirstTheme.addEventListener("click",
        function() {
            //remove first theme
            themeMgrObj.removeTheme(firstTheme);
            path = '$CAPH/1.0.0/caph.css';
            //add first theme
            themeMgrObj.addTheme(firstTheme, path);
            //enable first theme
            themeMgrObj.enableTheme(firstTheme);
        );
        //set btnFirstTheme's position
        btnSecondTheme.setPosition(position.x, position.y, position.z);
        //set btnFirstTheme's size
        btnFirstTheme.setSize(350 * ratio , 94 * ratio);
        //set btnFirstTheme's text
        btnFirstTheme.setText('First Theme');
        //add btnFirstTheme to the page
        btnFirstTheme.render(page);
		
        //new button
        var btnSecondTheme = new Button({});
        //add click event listener for btnSecondTheme
        btnSecondTheme.addEventListener("click",
        function() {
            //remove first theme
            themeMgrObj.removeTheme(secondTheme);
            //change the path
            path = 'theme.css';
            //add second theme
            themeMgrObj.addTheme(secondTheme, path);
            //enable second theme
            themeMgrObj.enableTheme(secondTheme);
        });
        //set btnSecondTheme's position
        btnSecondTheme.setPosition((position.x + 400) * ratio, position.y, position.z);
        //set btnSecondTheme's size
        btnSecondTheme.setSize(350 * ratio, 94 * ratio);
        //set btnSecondTheme's text
        btnSecondTheme.setText('Second Theme');
        //add btnSecondTheme to the page
        btnSecondTheme.render(page);
        //create other components
        createComponents();
        page.show();
        //support the highlight
        HighLight.init(page);
        if(caph) {
            caph.wui.widget.KeyControl.init();
        }
    } catch(e) {
        console.error(e.message);
    }
    //create other components
    function createComponents() {
        //new strip
        var strip = new Strip({
            'maxSize' : 2,
            //Defines the Strip has block numbers
            'frame' : { //define the strip's size
                'width' : 400 * ratio,
                'height' : 60 * ratio
            },
            'topleft-position' : { //define the strip's position
                'x' : 800 * ratio,
                'y' : 60 * ratio,
                'z' : position.z
            },
            'cls' : 'u-testsuite-strip-bb' //define the strip's css class
        });
        //add the first strip
        strip.addItem(0, 'first strip');
        //add the second strip
        strip.addItem(1, 'second strip');
        //render the strip
        strip.render(page);
        //new InputBox
        var input = new InputBox({
            'frame' : { //define the input's size
                'width' : 200 * ratio,
                'height' : 94 * ratio
            },
            'topleft-position' : { //define the input's position
                'x' : 100 * ratio,
                'y' : 340 * ratio,
                'z' : 5* ratio
            },
            'text' : { //define the input's text
                'data' : 'Input Box'
            }
        });
        //render the input
        input.render(page);
        //new ProgressBar
        var progressbar = new ProgressBar({
            'frame' : { //define the progressbar's size
                'width' : 200 * ratio
            },
            'progress' : 0,
            //define the progressbar's default progress
            'topleft-position' : { //define the progressbar's position
                x : 500 * ratio,
                y : 340 * ratio,
                z : 5
            }
        });
        //The increment updated in one second
        progressbar.setIncrement(0.5);
        //render the progressbar
        progressbar.render(page);
        //start progress
        progressbar.start();
        //new Image
        var image0 = new Image({
            width : 400 * ratio,
            height : 300 * ratio,
            url : 'img/1.png' //set the image0's url
        });
        //set image0's position
        image0.setPosition(800 * ratio, 340 * ratio, 5);
        //render the image0
        image0.render(page);
        //new listwidgetObj's options
        var options = {
            'frame' : { //define the listwidgetObj's size
                'width' : 700 * ratio,
                'height' : 300 * ratio,
                'cycle' : false,
            },
            'maxSize' : 3,
            //Defines the listwidgetObj has block numbers
            'center-position' : { //define the listwidgetObj's center position
                'x' : 400 * ratio,
                'y' : 600 * ratio,
                'z' : 0
            },
            'interval' : 30,
            'item' : { //set item's attribute
                'item_width' : 150 * ratio,
                'item_height' : 200 * ratio,
                'margin' : '0 0'
            }
        };
        //new ListWidget
        var listwidgetObj = new ListWidget(options);
        //set the item
        var optionsListWidgetA = { //define the listwidgetObj's item's size
            'width' : 285 * ratio,
            'height' : 385 * ratio,
            text : { //define the listwidgetObj's item's text attribute
                'textHeight' : 45 * ratio,
                'margin' : '25 0'
            },
            'labelScroll' : true
        };
        var optionsListWidgetB = { //define the listwidgetObj's item's size
            'width' : 300 * ratio,
            'height' : 385 * ratio,
            text : { //define the listwidgetObj's item text attribute
                'textHeight' : 45,
                'margin' : '25 0',
            },
            'labelScroll' : false
        };
        //new panel0
        var panel0 = new Panel(optionsListWidgetB);
        //new panel1
        var panel1 = new Panel(optionsListWidgetB);
        //new panel2
        var panel2 = new Panel(optionsListWidgetA, true};
        //add panel to the listwidgetObj
        listwidgetObj.addItem(0, panel0);
        listwidgetObj.addItem(1, panel1);
        listwidgetObj.addItem(2, panel2);
        //set panel0's image
        panel0.setURL('img/page1.jpg');
        //set panel0's text
        panel0.setText('kate!');
        panel1.setURL('img/page2.jpg');
        panel1.setText('Lily');
        panel2.setURL('img/page3.jpg');
        panel2.setText('Potter');
        listwidgetObj.render(page);
    }
};

app.handleLoad = function() {
    if(window.curWidget) {
        window.curWidget.setPreference('ready', 'true');
    }
};

Screenshots of this example look like this :

  1. First theme
  2. Second theme

Related Document