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 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 153 ConfigView::~ConfigView() 154 { 155 fSettings->Release(); 156 } 157 158 159 void 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 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