/* * Copyright 2021, Haiku, Inc. All rights reserved. * Distributed under the terms of the MIT License. * * Authors: * Emmanuel Gil Peyrot */ #include "ConfigView.h" #include #include #include #include #include #include #include #include #include #include #include #include "avif/avif.h" #include "TranslatorSettings.h" #include "AVIFTranslator.h" #undef B_TRANSLATION_CONTEXT #define B_TRANSLATION_CONTEXT "ConfigView" static const uint32 kMsgLossless = 'losl'; static const uint32 kMsgPixelFormat = 'pfmt'; static const uint32 kMsgQuality = 'qlty'; static const uint32 kMsgSpeed = 'sped'; static const uint32 kMsgTilesHorizontal = 'tilh'; static const uint32 kMsgTilesVertical = 'tilv'; ConfigView::ConfigView(TranslatorSettings* settings) : BGroupView(B_TRANSLATE("AVIFTranslator Settings"), B_VERTICAL), fSettings(settings) { SetViewUIColor(B_PANEL_BACKGROUND_COLOR); BStringView* title = new BStringView("title", B_TRANSLATE("AVIF image translator")); title->SetFont(be_bold_font); char versionString[256]; sprintf(versionString, "v%d.%d.%d, %s", static_cast(B_TRANSLATION_MAJOR_VERSION(AVIF_TRANSLATOR_VERSION)), static_cast(B_TRANSLATION_MINOR_VERSION(AVIF_TRANSLATOR_VERSION)), static_cast(B_TRANSLATION_REVISION_VERSION( AVIF_TRANSLATOR_VERSION)), __DATE__); BStringView* version = new BStringView("version", versionString); BString copyrightsText; BStringView *copyrightView = new BStringView("Copyright", B_TRANSLATE(B_UTF8_COPYRIGHT "2021 Emmanuel Gil Peyrot")); BString libavifInfo = B_TRANSLATE( "Based on libavif %version%"); libavifInfo.ReplaceAll("%version%", avifVersion()); BStringView *copyright2View = new BStringView("Copyright2", libavifInfo.String()); BStringView *copyright3View = new BStringView("Copyright3", B_TRANSLATE(B_UTF8_COPYRIGHT "2019 Joe Drago. All rights reserved.")); // output parameters fLosslessCheckBox = new BCheckBox("lossless", B_TRANSLATE("Lossless"), new BMessage(kMsgLossless)); bool lossless; fSettings->SetGetBool(AVIF_SETTING_LOSSLESS, &lossless); if (lossless) fLosslessCheckBox->SetValue(B_CONTROL_ON); fPixelFormatMenu = new BPopUpMenu(B_TRANSLATE("Pixel format")); static const avifPixelFormat pixelFormats[4] = { AVIF_PIXEL_FORMAT_YUV444, AVIF_PIXEL_FORMAT_YUV420, AVIF_PIXEL_FORMAT_YUV400, AVIF_PIXEL_FORMAT_YUV422, }; for (size_t i = 0; i < 4; ++i) { BMessage* msg = new BMessage(kMsgPixelFormat); msg->AddInt32("value", pixelFormats[i]); BMenuItem* item = new BMenuItem( avifPixelFormatToString(pixelFormats[i]), msg); if (fSettings->SetGetInt32(AVIF_SETTING_PIXEL_FORMAT) == pixelFormats[i]) item->SetMarked(true); fPixelFormatMenu->AddItem(item); } BMenuField* pixelFormatField = new BMenuField(B_TRANSLATE("Pixel format:"), fPixelFormatMenu); rgb_color barColor = { 0, 0, 229, 255 }; fQualitySlider = new BSlider("quality", B_TRANSLATE("Output quality:"), new BMessage(kMsgQuality), AVIF_QUANTIZER_BEST_QUALITY, AVIF_QUANTIZER_WORST_QUALITY, B_HORIZONTAL, B_BLOCK_THUMB); fQualitySlider->SetHashMarks(B_HASH_MARKS_BOTTOM); fQualitySlider->SetHashMarkCount(8); fQualitySlider->SetLimitLabels(B_TRANSLATE("Best"), B_TRANSLATE("Worst")); fQualitySlider->UseFillColor(true, &barColor); fQualitySlider->SetValue(fSettings->SetGetInt32(AVIF_SETTING_QUALITY)); fQualitySlider->SetEnabled(!lossless); fSpeedSlider = new BSlider("speed", B_TRANSLATE("Compression speed:"), new BMessage(kMsgSpeed), AVIF_SPEED_SLOWEST, AVIF_SPEED_FASTEST, B_HORIZONTAL, B_BLOCK_THUMB); fSpeedSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); fSpeedSlider->SetHashMarkCount(11); fSpeedSlider->SetLimitLabels(B_TRANSLATE("Slow"), B_TRANSLATE("Faster but worse quality")); fSpeedSlider->UseFillColor(true, &barColor); fSpeedSlider->SetValue(fSettings->SetGetInt32(AVIF_SETTING_SPEED)); fHTilesSlider = new BSlider("htiles", B_TRANSLATE("Horizontal tiles:"), new BMessage(kMsgTilesHorizontal), 1, 6, B_HORIZONTAL, B_BLOCK_THUMB); fHTilesSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); fHTilesSlider->SetHashMarkCount(6); fHTilesSlider->SetLimitLabels(B_TRANSLATE("1"), B_TRANSLATE("2⁶")); fHTilesSlider->UseFillColor(true, &barColor); fHTilesSlider->SetValue( fSettings->SetGetInt32(AVIF_SETTING_TILES_HORIZONTAL)); fVTilesSlider = new BSlider("vtiles", B_TRANSLATE("Vertical tiles:"), new BMessage(kMsgTilesVertical), 1, 6, B_HORIZONTAL, B_BLOCK_THUMB); fVTilesSlider->SetHashMarks(B_HASH_MARKS_BOTTOM); fVTilesSlider->SetHashMarkCount(6); fVTilesSlider->SetLimitLabels(B_TRANSLATE("1"), B_TRANSLATE("2⁶")); fVTilesSlider->UseFillColor(true, &barColor); fVTilesSlider->SetValue( fSettings->SetGetInt32(AVIF_SETTING_TILES_VERTICAL)); // Build the layout BLayoutBuilder::Group<>(this, B_VERTICAL, 0) .SetInsets(B_USE_DEFAULT_SPACING) .Add(title) .Add(version) .Add(copyrightView) .AddGlue() .Add(fLosslessCheckBox) .AddGrid(B_USE_DEFAULT_SPACING, B_USE_SMALL_SPACING) .Add(pixelFormatField->CreateLabelLayoutItem(), 0, 0) .AddGroup(B_HORIZONTAL, 0.0f, 1, 0) .Add(pixelFormatField->CreateMenuBarLayoutItem(), 0.0f) .AddGlue() .End() .End() .Add(fQualitySlider) .Add(fSpeedSlider) .Add(fHTilesSlider) .Add(fVTilesSlider) .AddGlue() .Add(copyright2View) .Add(copyright3View); } ConfigView::~ConfigView() { fSettings->Release(); } void ConfigView::AttachedToWindow() { BGroupView::AttachedToWindow(); fQualitySlider->SetTarget(this); fSpeedSlider->SetTarget(this); fHTilesSlider->SetTarget(this); fVTilesSlider->SetTarget(this); if (Parent() == NULL && Window()->GetLayout() == NULL) { Window()->SetLayout(new BGroupLayout(B_VERTICAL)); Window()->ResizeTo(PreferredSize().Width(), PreferredSize().Height()); } } void ConfigView::MessageReceived(BMessage* message) { struct { const char* name; uint32 what; TranSettingType type; } maps[] = { { AVIF_SETTING_LOSSLESS, kMsgLossless, TRAN_SETTING_BOOL }, { AVIF_SETTING_PIXEL_FORMAT, kMsgPixelFormat, TRAN_SETTING_INT32 }, { AVIF_SETTING_QUALITY, kMsgQuality, TRAN_SETTING_INT32 }, { AVIF_SETTING_SPEED, kMsgSpeed, TRAN_SETTING_INT32 }, { AVIF_SETTING_TILES_HORIZONTAL, kMsgTilesHorizontal, TRAN_SETTING_INT32 }, { AVIF_SETTING_TILES_VERTICAL, kMsgTilesVertical, TRAN_SETTING_INT32 }, { NULL } }; int i; for (i = 0; maps[i].name != NULL; i++) { if (maps[i].what == message->what) break; } if (maps[i].name == NULL) { BGroupView::MessageReceived(message); return; } int32 value; if (message->FindInt32("value", &value) == B_OK || message->FindInt32("be:value", &value) == B_OK) { switch(maps[i].type) { case TRAN_SETTING_BOOL: { bool boolValue = value; fSettings->SetGetBool(maps[i].name, &boolValue); if (maps[i].what == kMsgLossless) fSpeedSlider->SetEnabled(!boolValue); break; } case TRAN_SETTING_INT32: fSettings->SetGetInt32(maps[i].name, &value); break; } fSettings->SaveSettings(); } }