1 /*
2 * Copyright 2010-2017, Haiku, Inc. All rights reserved.
3 * Distributed under the terms of the MIT License.
4 *
5 * Authors:
6 * Philippe Houdoin
7 */
8
9
10 #include "ConfigView.h"
11
12 #include <stdio.h>
13 #include <string.h>
14
15 #include <Catalog.h>
16 #include <CheckBox.h>
17 #include <LayoutBuilder.h>
18 #include <MenuField.h>
19 #include <MenuItem.h>
20 #include <Message.h>
21 #include <PopUpMenu.h>
22 #include <Slider.h>
23 #include <StringView.h>
24
25 #include "webp/encode.h"
26
27 #include "TranslatorSettings.h"
28 #include "WebPTranslator.h"
29
30
31 #undef B_TRANSLATION_CONTEXT
32 #define B_TRANSLATION_CONTEXT "ConfigView"
33
34
35 static const uint32 kMsgQuality = 'qlty';
36 static const uint32 kMsgPreset = 'prst';
37 static const uint32 kMsgMethod = 'metd';
38 static const uint32 kMsgPreprocessing = 'pprc';
39
40 static const struct preset_name {
41 const char* name;
42 WebPPreset id;
43 } kPresetNames[] = {
44 { B_TRANSLATE("Default"), WEBP_PRESET_DEFAULT },
45 { B_TRANSLATE("Picture"), WEBP_PRESET_PICTURE },
46 { B_TRANSLATE("Photo"), WEBP_PRESET_PHOTO },
47 { B_TRANSLATE("Drawing"), WEBP_PRESET_DRAWING },
48 { B_TRANSLATE("Icon"), WEBP_PRESET_ICON },
49 { B_TRANSLATE("Text"), WEBP_PRESET_TEXT },
50 { NULL },
51 };
52
53
ConfigView(TranslatorSettings * settings)54 ConfigView::ConfigView(TranslatorSettings* settings)
55 :
56 BGroupView(B_TRANSLATE("WebPTranslator Settings"), B_VERTICAL),
57 fSettings(settings)
58 {
59 SetViewUIColor(B_PANEL_BACKGROUND_COLOR);
60
61 BStringView* title = new BStringView("title",
62 B_TRANSLATE("WebP image translator"));
63 title->SetFont(be_bold_font);
64
65 char versionString[256];
66 sprintf(versionString, "v%d.%d.%d, %s",
67 static_cast<int>(B_TRANSLATION_MAJOR_VERSION(WEBP_TRANSLATOR_VERSION)),
68 static_cast<int>(B_TRANSLATION_MINOR_VERSION(WEBP_TRANSLATOR_VERSION)),
69 static_cast<int>(B_TRANSLATION_REVISION_VERSION(
70 WEBP_TRANSLATOR_VERSION)),
71 __DATE__);
72
73 BStringView* version = new BStringView("version", versionString);
74
75 BString copyrightsText;
76 BStringView *copyrightView = new BStringView("Copyright",
77 B_TRANSLATE(B_UTF8_COPYRIGHT "2010-2017 Haiku Inc."));
78
79 BString libwebpInfo = B_TRANSLATE(
80 "Based on libwebp %version%");
81 int v = WebPGetEncoderVersion();
82 char libwebpVersion[32];
83 snprintf(libwebpVersion, sizeof(libwebpVersion),
84 "%d.%d.%d", v >> 16, (v>>8)&255, v&255);
85 libwebpInfo.ReplaceAll("%version%", libwebpVersion);
86
87 BStringView *copyright2View = new BStringView("Copyright2",
88 libwebpInfo.String());
89 BStringView *copyright3View = new BStringView("Copyright3",
90 B_TRANSLATE(B_UTF8_COPYRIGHT "2010-2017 Google Inc."));
91
92 // output parameters
93
94 fPresetsMenu = new BPopUpMenu(B_TRANSLATE("Preset"));
95 const struct preset_name* preset = kPresetNames;
96 while (preset->name != NULL) {
97 BMessage* msg = new BMessage(kMsgPreset);
98 msg->AddInt32("value", preset->id);
99
100 BMenuItem* item = new BMenuItem(preset->name, msg);
101 if (fSettings->SetGetInt32(WEBP_SETTING_PRESET) == preset->id)
102 item->SetMarked(true);
103 fPresetsMenu->AddItem(item);
104
105 preset++;
106 }
107 BMenuField* presetsField = new BMenuField(B_TRANSLATE("Output preset:"),
108 fPresetsMenu);
109
110 fQualitySlider = new BSlider("quality", B_TRANSLATE("Output quality:"),
111 new BMessage(kMsgQuality), 0, 100, B_HORIZONTAL, B_BLOCK_THUMB);
112 fQualitySlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
113 fQualitySlider->SetHashMarkCount(10);
114 fQualitySlider->SetLimitLabels(B_TRANSLATE("Low"), B_TRANSLATE("High"));
115 fQualitySlider->SetValue(fSettings->SetGetInt32(WEBP_SETTING_QUALITY));
116
117 fMethodSlider = new BSlider("method", B_TRANSLATE("Compression method:"),
118 new BMessage(kMsgMethod), 0, 6, B_HORIZONTAL, B_BLOCK_THUMB);
119 fMethodSlider->SetHashMarks(B_HASH_MARKS_BOTTOM);
120 fMethodSlider->SetHashMarkCount(7);
121 fMethodSlider->SetLimitLabels(B_TRANSLATE("Fast"),
122 B_TRANSLATE("Slower but better"));
123 fMethodSlider->SetValue(fSettings->SetGetInt32(WEBP_SETTING_METHOD));
124
125 fPreprocessingCheckBox = new BCheckBox("preprocessing",
126 B_TRANSLATE("Preprocessing filter"), new BMessage(kMsgPreprocessing));
127 if (fSettings->SetGetBool(WEBP_SETTING_PREPROCESSING))
128 fPreprocessingCheckBox->SetValue(B_CONTROL_ON);
129
130 // Build the layout
131 BLayoutBuilder::Group<>(this, B_VERTICAL, 0)
132 .SetInsets(B_USE_DEFAULT_SPACING)
133 .Add(title)
134 .Add(version)
135 .Add(copyrightView)
136 .AddGlue()
137 .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING)
138 .Add(presetsField->CreateLabelLayoutItem(), 0, 0)
139 .AddGroup(B_HORIZONTAL, 0.0f, 1, 0)
140 .Add(presetsField->CreateMenuBarLayoutItem(), 0.0f)
141 .AddGlue()
142 .End()
143 .End()
144 .Add(fQualitySlider)
145 .Add(fMethodSlider)
146 .Add(fPreprocessingCheckBox)
147 .AddGlue()
148 .Add(copyright2View)
149 .Add(copyright3View);
150 }
151
152
~ConfigView()153 ConfigView::~ConfigView()
154 {
155 fSettings->Release();
156 }
157
158
159 void
AttachedToWindow()160 ConfigView::AttachedToWindow()
161 {
162 BGroupView::AttachedToWindow();
163
164 fPresetsMenu->SetTargetForItems(this);
165
166 fQualitySlider->SetTarget(this);
167 fMethodSlider->SetTarget(this);
168 fPreprocessingCheckBox->SetTarget(this);
169
170 if (Parent() == NULL && Window()->GetLayout() == NULL) {
171 Window()->SetLayout(new BGroupLayout(B_VERTICAL));
172 Window()->ResizeTo(PreferredSize().Width(), PreferredSize().Height());
173 }
174 }
175
176
177 void
MessageReceived(BMessage * message)178 ConfigView::MessageReceived(BMessage* message)
179 {
180 struct {
181 const char* name;
182 uint32 what;
183 TranSettingType type;
184 } maps[] = {
185 { WEBP_SETTING_PRESET, kMsgPreset, TRAN_SETTING_INT32 },
186 { WEBP_SETTING_QUALITY, kMsgQuality, TRAN_SETTING_INT32 },
187 { WEBP_SETTING_METHOD, kMsgMethod, TRAN_SETTING_INT32 },
188 { WEBP_SETTING_PREPROCESSING, kMsgPreprocessing, TRAN_SETTING_BOOL },
189 { NULL }
190 };
191
192 int i;
193 for (i = 0; maps[i].name != NULL; i++) {
194 if (maps[i].what == message->what)
195 break;
196 }
197
198 if (maps[i].name == NULL) {
199 BGroupView::MessageReceived(message);
200 return;
201 }
202
203 int32 value;
204 if (message->FindInt32("value", &value) == B_OK
205 || message->FindInt32("be:value", &value) == B_OK) {
206 switch(maps[i].type) {
207 case TRAN_SETTING_BOOL:
208 {
209 bool boolValue = value;
210 fSettings->SetGetBool(maps[i].name, &boolValue);
211 break;
212 }
213 case TRAN_SETTING_INT32:
214 fSettings->SetGetInt32(maps[i].name, &value);
215 break;
216 }
217 fSettings->SaveSettings();
218 }
219 }
220