Ejemplo n.º 1
0
HRESULT SetupBDAStreamOutFormat( JNIEnv *env, DShowCaptureInfo* pCapInfo, int streamType )
{
	ITSParser2 *pTSParser = NULL;
	HRESULT hr = pCapInfo->pSplitter->QueryInterface(IID_ITSParser2, (void**)&pTSParser);
	if ( FAILED( hr ) )
	{
		slog((env, "get TS Splitter interface failed\r\n" ));
	} else
	{
		if ( streamType == 31 )
		{
			slog( (env,"Splitter Filter set output mpeg2 format \r\n") );
			pTSParser->SetOutputFormat( 1 );
			setOutputFormat( (CHANNEL_DATA*)pCapInfo->channel, 1 );
		} else
		if ( streamType == 32 )
		{
			slog( (env,"Splitter Filter output transport stream format \r\n") );
			pTSParser->SetOutputFormat( 0 );
			setOutputFormat( (CHANNEL_DATA*)pCapInfo->channel, 0 );
		}
	}
	SAFE_RELEASE(pTSParser);
	return hr;
}
Ejemplo n.º 2
0
static bool isOK_setFormat(void) {
	if (!isOK_setOutputFormat()) {
		return false;
	}
	OutputFormat format;
	char separator[] = { '%', 'X' };
	ushort code = 1;
	nameString name = "multiformat";
	ushort precision = 5;
	bool leftJusfified = false;
	ushort width = 12;
	nameString output;
	nameString result[2][2] = { { "% 12.5lg", "% 12.5lg %% % 12.5lg" }, //
		{ "% 12.5lg", "% 12.5lg X % 12.5lg" } };
	for (ushort i = 0; i < 2; i++) {
		setOutputFormat(&format, precision, width, separator[i], leftJusfified, name, code);
		SAVE_FUNCTION_CALLER();
		setFormats(output, 1, &format);
		if (strcmp(result[i][0], output)) {
			PRINT_ERROR();
			return false;
		}
		SAVE_FUNCTION_CALLER();
		setFormats(output, 2, &format);
		if (strcmp(result[i][1], output)) {
			PRINT_ERROR();
			return false;
		}
	}
	PRINT_OK();
	return true;
}
Ejemplo n.º 3
0
void Routine::releaseStatement(thread_db* tdbb)
{
	if (getStatement())
	{
		getStatement()->release(tdbb);
		setStatement(NULL);
	}

	setInputFormat(NULL);
	setOutputFormat(NULL);

	flags &= ~FLAG_SCANNED;
}
Ejemplo n.º 4
0
static bool isOK_setOutputFormat(void) {
	if (!isOK_setFormatForOneNumber()) {
		return false;
	}
	OutputFormat format;
	char separator = '%';
	ushort code = 0;
	nameString name[6] = { "ab", "bd", "cf", "dh", "ej", "fl" };
	ushort precision = 2 * SPECIAL_CHARACTER_LENGTH;
	bool leftJusfified = false;
	ushort width;
	for (ushort i = 0; i < 2; i++, neg(&leftJusfified)) {
		width = (ushort) (precision - 2 * SPECIAL_CHARACTER_LENGTH);
		for (ushort j = 0; j < 3; j++, code++) {
			ushort k = (ushort) (3 * i + j);
			SAVE_FUNCTION_CALLER();
			setOutputFormat(&format, precision, width, separator, leftJusfified, name[k], code);
			if (format.precision != precision) {
				PRINT_ERROR();
				return false;
			}
			if (format.width < width) {
				PRINT_ERROR();
				return false;
			}
			if (format.width < precision) {
				PRINT_ERROR();
				return false;
			}
			if (strcmp(name[k], format.name)) {
				PRINT_ERROR();
				return false;
			}
			width = (ushort) (width + 2 * SPECIAL_CHARACTER_LENGTH);
		}
	}
	/// @todo a hibás bemenet nincs leellenőrizve!!!
	PRINT_OK();
	return true;
}
Ejemplo n.º 5
0
status_t BnMediaRecorder::onTransact(
                                     uint32_t code, const Parcel& data, Parcel* reply,
                                     uint32_t flags)
{
    switch (code) {
        case RELEASE: {
            ALOGV("RELEASE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(release());
            return NO_ERROR;
        } break;
        case INIT: {
            ALOGV("INIT");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(init());
            return NO_ERROR;
        } break;
        case CLOSE: {
            ALOGV("CLOSE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(close());
            return NO_ERROR;
        } break;
        case RESET: {
            ALOGV("RESET");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(reset());
            return NO_ERROR;
        } break;
        case STOP: {
            ALOGV("STOP");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(stop());
            return NO_ERROR;
        } break;
        case START: {
            ALOGV("START");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(start());
            return NO_ERROR;
        } break;
        case PREPARE: {
            ALOGV("PREPARE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(prepare());
            return NO_ERROR;
        } break;
        case GET_MAX_AMPLITUDE: {
            ALOGV("GET_MAX_AMPLITUDE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            int max = 0;
            status_t ret = getMaxAmplitude(&max);
            reply->writeInt32(max);
            reply->writeInt32(ret);
            return NO_ERROR;
        } break;
        case SET_VIDEO_SOURCE: {
            ALOGV("SET_VIDEO_SOURCE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            int vs = data.readInt32();
            reply->writeInt32(setVideoSource(vs));
            return NO_ERROR;
        } break;
        case SET_AUDIO_SOURCE: {
            ALOGV("SET_AUDIO_SOURCE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            int as = data.readInt32();
            reply->writeInt32(setAudioSource(as));
            return NO_ERROR;
        } break;
        case SET_OUTPUT_FORMAT: {
            ALOGV("SET_OUTPUT_FORMAT");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            int of = data.readInt32();
            reply->writeInt32(setOutputFormat(of));
            return NO_ERROR;
        } break;
        case SET_VIDEO_ENCODER: {
            ALOGV("SET_VIDEO_ENCODER");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            int ve = data.readInt32();
            reply->writeInt32(setVideoEncoder(ve));
            return NO_ERROR;
        } break;
        case SET_AUDIO_ENCODER: {
            ALOGV("SET_AUDIO_ENCODER");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            int ae = data.readInt32();
            reply->writeInt32(setAudioEncoder(ae));
            return NO_ERROR;

        } break;
        case SET_OUTPUT_FILE_FD: {
            ALOGV("SET_OUTPUT_FILE_FD");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            int fd = dup(data.readFileDescriptor());
            int64_t offset = data.readInt64();
            int64_t length = data.readInt64();
            reply->writeInt32(setOutputFile(fd, offset, length));
            ::close(fd);
            return NO_ERROR;
        } break;
        case SET_VIDEO_SIZE: {
            ALOGV("SET_VIDEO_SIZE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            int width = data.readInt32();
            int height = data.readInt32();
            reply->writeInt32(setVideoSize(width, height));
            return NO_ERROR;
        } break;
        case SET_VIDEO_FRAMERATE: {
            ALOGV("SET_VIDEO_FRAMERATE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            int frames_per_second = data.readInt32();
            reply->writeInt32(setVideoFrameRate(frames_per_second));
            return NO_ERROR;
        } break;
        case SET_PARAMETERS: {
            ALOGV("SET_PARAMETER");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(setParameters(data.readString8()));
            return NO_ERROR;
        } break;
        case SET_LISTENER: {
            ALOGV("SET_LISTENER");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            sp<IMediaRecorderClient> listener =
                interface_cast<IMediaRecorderClient>(data.readStrongBinder());
            reply->writeInt32(setListener(listener));
            return NO_ERROR;
        } break;
        case SET_CLIENT_NAME: {
            ALOGV("SET_CLIENT_NAME");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            reply->writeInt32(setClientName(data.readString16()));
            return NO_ERROR;
        }
        case SET_PREVIEW_SURFACE: {
            ALOGV("SET_PREVIEW_SURFACE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            sp<IGraphicBufferProducer> surface = interface_cast<IGraphicBufferProducer>(
                    data.readStrongBinder());
            reply->writeInt32(setPreviewSurface(surface));
            return NO_ERROR;
        } break;
        case SET_CAMERA: {
            ALOGV("SET_CAMERA");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            sp<ICamera> camera = interface_cast<ICamera>(data.readStrongBinder());
            sp<ICameraRecordingProxy> proxy =
                interface_cast<ICameraRecordingProxy>(data.readStrongBinder());
            reply->writeInt32(setCamera(camera, proxy));
            return NO_ERROR;
        } break;
        case SET_INPUT_SURFACE: {
            ALOGV("SET_INPUT_SURFACE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            sp<IGraphicBufferConsumer> surface = interface_cast<IGraphicBufferConsumer>(
                    data.readStrongBinder());
            reply->writeInt32(setInputSurface(surface));
            return NO_ERROR;
        } break;
        case QUERY_SURFACE_MEDIASOURCE: {
            ALOGV("QUERY_SURFACE_MEDIASOURCE");
            CHECK_INTERFACE(IMediaRecorder, data, reply);
            // call the mediaserver side to create
            // a surfacemediasource
            sp<IGraphicBufferProducer> surfaceMediaSource = querySurfaceMediaSource();
            // The mediaserver might have failed to create a source
            int returnedNull= (surfaceMediaSource == NULL) ? 1 : 0 ;
            reply->writeInt32(returnedNull);
            if (!returnedNull) {
                reply->writeStrongBinder(IInterface::asBinder(surfaceMediaSource));
            }
            return NO_ERROR;
        } break;
        default:
            return BBinder::onTransact(code, data, reply, flags);
    }
}
status_t BnMediaRecorder::onTransact(
    uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    switch(code) {
    case RELEASE: {
        LOGV("RELEASE");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        reply->writeInt32(release());
        return NO_ERROR;
    }
    break;
    case INIT: {
        LOGV("INIT");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        reply->writeInt32(init());
        return NO_ERROR;
    }
    break;
    case CLOSE: {
        LOGV("CLOSE");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        reply->writeInt32(close());
        return NO_ERROR;
    }
    break;
    case RESET: {
        LOGV("RESET");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        reply->writeInt32(reset());
        return NO_ERROR;
    }
    break;
    case STOP: {
        LOGV("STOP");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        reply->writeInt32(stop());
        return NO_ERROR;
    }
    break;
    case START: {
        LOGV("START");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        reply->writeInt32(start());
        return NO_ERROR;
    }
    break;
    case PREPARE: {
        LOGV("PREPARE");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        reply->writeInt32(prepare());
        return NO_ERROR;
    }
    break;
    case GET_MAX_AMPLITUDE: {
        LOGV("GET_MAX_AMPLITUDE");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        int max = 0;
        status_t ret = getMaxAmplitude(&max);
        reply->writeInt32(max);
        reply->writeInt32(ret);
        return NO_ERROR;
    }
    break;
    case SET_VIDEO_SOURCE: {
        LOGV("SET_VIDEO_SOURCE");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        int vs = data.readInt32();
        reply->writeInt32(setVideoSource(vs));
        return NO_ERROR;
    }
    break;
    case SET_AUDIO_SOURCE: {
        LOGV("SET_AUDIO_SOURCE");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        int as = data.readInt32();
        reply->writeInt32(setAudioSource(as));
        return NO_ERROR;
    }
    break;
    case SET_OUTPUT_FORMAT: {
        LOGV("SET_OUTPUT_FORMAT");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        int of = data.readInt32();
        reply->writeInt32(setOutputFormat(of));
        return NO_ERROR;
    }
    break;
    case SET_VIDEO_ENCODER: {
        LOGV("SET_VIDEO_ENCODER");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        int ve = data.readInt32();
        reply->writeInt32(setVideoEncoder(ve));
        return NO_ERROR;
    }
    break;
    case SET_AUDIO_ENCODER: {
        LOGV("SET_AUDIO_ENCODER");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        int ae = data.readInt32();
        reply->writeInt32(setAudioEncoder(ae));
        return NO_ERROR;

    }
    break;
    case SET_OUTPUT_FILE_PATH: {
        LOGV("SET_OUTPUT_FILE_PATH");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        const char* path = data.readCString();
        reply->writeInt32(setOutputFile(path));
        return NO_ERROR;
    }
    break;
    case SET_OUTPUT_FILE_FD: {
        LOGV("SET_OUTPUT_FILE_FD");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        int fd = dup(data.readFileDescriptor());
        int64_t offset = data.readInt64();
        int64_t length = data.readInt64();
        reply->writeInt32(setOutputFile(fd, offset, length));
        return NO_ERROR;
    }
    break;
    case SET_VIDEO_SIZE: {
        LOGV("SET_VIDEO_SIZE");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        int width = data.readInt32();
        int height = data.readInt32();
        reply->writeInt32(setVideoSize(width, height));
        return NO_ERROR;
    }
    break;
    case SET_VIDEO_FRAMERATE: {
        LOGV("SET_VIDEO_FRAMERATE");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        int frames_per_second = data.readInt32();
        reply->writeInt32(setVideoFrameRate(frames_per_second));
        return NO_ERROR;
    }
    break;
    case SET_PARAMETERS: {
        LOGV("SET_PARAMETER");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        reply->writeInt32(setParameters(data.readString8()));
        return NO_ERROR;
    }
    break;
    case SET_LISTENER: {
        LOGV("SET_LISTENER");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        sp<IMediaPlayerClient> listener =
            interface_cast<IMediaPlayerClient>(data.readStrongBinder());
        reply->writeInt32(setListener(listener));
        return NO_ERROR;
    }
    break;
    case SET_PREVIEW_SURFACE: {
        LOGV("SET_PREVIEW_SURFACE");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        sp<ISurface> surface = interface_cast<ISurface>(data.readStrongBinder());
        reply->writeInt32(setPreviewSurface(surface));
        return NO_ERROR;
    }
    break;
    case SET_CAMERA: {
        LOGV("SET_CAMERA");
        CHECK_INTERFACE(IMediaRecorder, data, reply);
        sp<ICamera> camera = interface_cast<ICamera>(data.readStrongBinder());
        reply->writeInt32(setCamera(camera));
        return NO_ERROR;
    }
    break;
    default:
        return BBinder::onTransact(code, data, reply, flags);
    }
}
Ejemplo n.º 7
0
// Parse the messages of a blr request. For specified message, allocate a format (Format) block.
void Routine::parseMessages(thread_db* tdbb, CompilerScratch* csb, BlrReader blrReader)
{
	if (blrReader.getLength() < 2)
		status_exception::raise(Arg::Gds(isc_metadata_corrupt));

	csb->csb_blr_reader = blrReader;

	const SSHORT version = csb->csb_blr_reader.getByte();

	switch (version)
	{
		case blr_version4:
		case blr_version5:
		//case blr_version6:
			break;

		default:
			status_exception::raise(
				Arg::Gds(isc_metadata_corrupt) <<
				Arg::Gds(isc_wroblrver2) << Arg::Num(blr_version4) << Arg::Num(blr_version5/*6*/) <<
					Arg::Num(version));
	}

	if (csb->csb_blr_reader.getByte() != blr_begin)
		status_exception::raise(Arg::Gds(isc_metadata_corrupt));

	while (csb->csb_blr_reader.getByte() == blr_message)
	{
		const USHORT msgNumber = csb->csb_blr_reader.getByte();
		USHORT count = csb->csb_blr_reader.getWord();
		Format* format = Format::newFormat(*tdbb->getDefaultPool(), count);

		USHORT padField;
		const bool shouldPad = csb->csb_message_pad.get(msgNumber, padField);

		USHORT maxAlignment = 0;
		ULONG offset = 0;
		USHORT i = 0;

		for (Format::fmt_desc_iterator desc = format->fmt_desc.begin(); i < count; ++i, ++desc)
		{
			const USHORT align = PAR_desc(tdbb, csb, &*desc);
			if (align)
				offset = FB_ALIGN(offset, align);

			desc->dsc_address = (UCHAR*)(IPTR) offset;
			offset += desc->dsc_length;

			maxAlignment = MAX(maxAlignment, align);

			if (maxAlignment && shouldPad && i + 1 == padField)
				offset = FB_ALIGN(offset, maxAlignment);
		}

		format->fmt_length = offset;

		switch (msgNumber)
		{
			case 0:
				setInputFormat(format);
				break;

			case 1:
				setOutputFormat(format);
				break;

			default:
				delete format;
		}
	}
}
ColorEditor::ColorEditor(QWidget *parent) :
    QFrame(parent),
    d(new ColorEditorImpl(this))
{
    setFocusPolicy(Qt::StrongFocus);
    setFrameShape(QFrame::StyledPanel);
    setCursor(QCursor(Qt::ArrowCursor));

    // Build UI
    // Close button
    auto closeBtn = new QToolButton(this);
    closeBtn->setFixedSize(24, 24);
    closeBtn->setIcon(QIcon(QLatin1String(Core::Constants::ICON_BUTTON_CLOSE)));

    connect(closeBtn, &QToolButton::clicked,
            this, &ColorEditor::close);

    // Color format selection
    d->rgbBtn->setText(QLatin1String("rgb"));
    d->hsvBtn->setText(QLatin1String("hsv"));
    d->hslBtn->setText(QLatin1String("hsl"));
    d->qmlRgbaBtn->setText(QLatin1String("Qt.rgba"));
    d->qmlHslaBtn->setText(QLatin1String("Qt.hsla"));
    d->vecBtn->setText(QLatin1String("vec"));
    d->hexBtn->setText(QLatin1String("hex"));

    d->rgbBtn->setCheckable(true);
    d->hsvBtn->setCheckable(true);
    d->hslBtn->setCheckable(true);
    d->qmlRgbaBtn->setCheckable(true);
    d->qmlHslaBtn->setCheckable(true);
    d->vecBtn->setCheckable(true);
    d->hexBtn->setCheckable(true);

    // Build layouts
    d->formatsLayout->setSpacing(0);

    d->colorFrame->setMinimumSize(QSize(30, 35));

    auto rightLayout = new QVBoxLayout;
    rightLayout->addWidget(d->colorFrame);
    rightLayout->addStretch();

    auto leftPanelLayout = new QVBoxLayout;
    leftPanelLayout->addWidget(closeBtn);
    leftPanelLayout->addStretch();

    auto *colorWidgetsLayout = new QHBoxLayout;
    colorWidgetsLayout->addWidget(d->colorPicker);
    colorWidgetsLayout->addWidget(d->hueSlider);
    colorWidgetsLayout->addWidget(d->saturationSlider);
    colorWidgetsLayout->addWidget(d->valueSlider);
    colorWidgetsLayout->addWidget(d->opacitySlider);
    colorWidgetsLayout->addLayout(rightLayout);

    auto *centerLayout = new QVBoxLayout;
    centerLayout->addLayout(colorWidgetsLayout);
    centerLayout->addLayout(d->formatsLayout);

    auto *mainLayout = new QHBoxLayout(this);
    mainLayout->addLayout(leftPanelLayout);
    mainLayout->addSpacing(0);
    mainLayout->addLayout(centerLayout);

    // Color format selection logic
    d->btnGroup->addButton(d->rgbBtn);
    d->btnGroup->addButton(d->hsvBtn);
    d->btnGroup->addButton(d->hslBtn);
    d->btnGroup->addButton(d->qmlRgbaBtn);
    d->btnGroup->addButton(d->qmlHslaBtn);
    d->btnGroup->addButton(d->vecBtn);
    d->btnGroup->addButton(d->hexBtn);

    connect(d->btnGroup, static_cast<void (QButtonGroup::*)(QAbstractButton *)>(&QButtonGroup::buttonClicked),
            [=] (QAbstractButton *btn) {
        ColorFormat format;

        if (btn == d->rgbBtn) {
            format = ColorFormat::QCssRgbUCharFormat;
        }
        else if (btn == d->hsvBtn) {
            format = ColorFormat::QssHsvFormat;
        }
        else if (btn == d->hslBtn) {
            format = ColorFormat::CssHslFormat;
        }
        else if (btn == d->qmlRgbaBtn) {
            format = ColorFormat::QmlRgbaFormat;
        }
        else if (btn == d->qmlHslaBtn) {
            format = ColorFormat::QmlHslaFormat;
        }
        else if (btn == d->vecBtn) {
            format = ColorFormat::GlslFormat;
        }
        else if (btn == d->hexBtn)
            format = ColorFormat::HexFormat;

        d->setCurrentFormat(format);
    });

    // Color changes logic
    connect(d->colorPicker, &ColorPickerWidget::colorChanged,
            [=](const QColor &pureColor) {
        QColor newColor(pureColor);
        newColor.setAlpha(d->opacitySlider->value());

        d->updateColorWidgets(newColor, ColorEditorImpl::UpdateFromColorPicker);
        d->setCurrentColor(newColor);
    });

    connect(d->hueSlider, &HueSlider::valueChanged,
            [=](int hue) {
        QColor newColor = QColor::fromHsv(hue,
                                          d->color.hsvSaturation(),
                                          d->color.value(),
                                          d->opacitySlider->value());

        d->updateColorWidgets(newColor,
                              ColorEditorImpl::UpdateFromHueSlider);
        d->setCurrentColor(newColor);
    });

    connect(d->saturationSlider, &SaturationSlider::valueChanged,
            [=](int sat) {
        QColor newColor = QColor::fromHsv(d->color.hsvHue(),
                                          sat,
                                          d->color.value(),
                                          d->opacitySlider->value());

        d->updateColorWidgets(newColor,
                              ColorEditorImpl::UpdateFromSaturationSlider);
        d->setCurrentColor(newColor);
    });

    connect(d->valueSlider, &ValueSlider::valueChanged,
            [=](int val) {
        QColor newColor = QColor::fromHsv(d->color.hsvHue(),
                                          d->color.hsvSaturation(),
                                          val,
                                          d->opacitySlider->value());

        d->updateColorWidgets(newColor,
                              ColorEditorImpl::UpdateFromValueSlider);
        d->setCurrentColor(newColor);
    });


    connect(d->opacitySlider, &OpacitySlider::valueChanged,
            [=](int opacity) {
        QColor newColor = QColor::fromHsv(d->hueSlider->value(),
                                          d->color.hsvSaturation(),
                                          d->color.value(),
                                          opacity);

        d->updateColorWidgets(newColor,
                              ColorEditorImpl::UpdateFromOpacitySlider);
        d->setCurrentColor(newColor);
    });

    setColorCategory(ColorCategory::AnyCategory);
    setOutputFormat(ColorFormat::QCssRgbUCharFormat);
    setColor(Qt::red);
}
ColorEditor::ColorEditor(QWidget *parent) :
    QFrame(parent),
    d(new ColorEditorImpl(this))
{
    setFocusPolicy(Qt::StrongFocus);
    setCursor(QCursor(Qt::ArrowCursor));

    // Build UI
    // Color format selection
    d->rgbBtn->setText(QLatin1String("rgb"));
    d->hsvBtn->setText(QLatin1String("hsv"));
    d->hslBtn->setText(QLatin1String("hsl"));
    d->qmlRgbaBtn->setText(QLatin1String("Qt.rgba"));
    d->qmlHslaBtn->setText(QLatin1String("Qt.hsla"));
    d->vecBtn->setText(QLatin1String("vec"));
    d->hexBtn->setText(QLatin1String("hex"));

    d->rgbBtn->setCheckable(true);
    d->hsvBtn->setCheckable(true);
    d->hslBtn->setCheckable(true);
    d->qmlRgbaBtn->setCheckable(true);
    d->qmlHslaBtn->setCheckable(true);
    d->vecBtn->setCheckable(true);
    d->hexBtn->setCheckable(true);

    // Build layouts
    d->formatsLayout->setSpacing(0);

    d->colorFrame->setMinimumSize(QSize(30, 35));

    auto rightLayout = new QVBoxLayout;
    rightLayout->addWidget(d->colorFrame);
    rightLayout->addStretch();

    auto leftPanelLayout = new QVBoxLayout;
    leftPanelLayout->addStretch();

    auto colorWidgetsLayout = new QHBoxLayout;
    colorWidgetsLayout->addWidget(d->colorPicker);
    colorWidgetsLayout->addWidget(d->hueSlider);
    colorWidgetsLayout->addWidget(d->saturationSlider);
    colorWidgetsLayout->addWidget(d->valueSlider);
    colorWidgetsLayout->addWidget(d->opacitySlider);
    colorWidgetsLayout->addLayout(rightLayout);

    auto centerLayout = new QVBoxLayout;
    centerLayout->addLayout(colorWidgetsLayout);
    centerLayout->addLayout(d->formatsLayout);

    auto mainLayout = new QHBoxLayout(this);
    mainLayout->addLayout(leftPanelLayout);
    mainLayout->addSpacing(0);
    mainLayout->addLayout(centerLayout);

    // Color format selection logic
    d->btnGroup->addButton(d->rgbBtn);
    d->btnGroup->addButton(d->hsvBtn);
    d->btnGroup->addButton(d->hslBtn);
    d->btnGroup->addButton(d->qmlRgbaBtn);
    d->btnGroup->addButton(d->qmlHslaBtn);
    d->btnGroup->addButton(d->vecBtn);
    d->btnGroup->addButton(d->hexBtn);

    d->buttonToColorFormat.insert(d->rgbBtn, ColorFormat::QCssRgbUCharFormat);
    d->buttonToColorFormat.insert(d->hsvBtn, ColorFormat::QssHsvFormat);
    d->buttonToColorFormat.insert(d->hslBtn, ColorFormat::CssHslFormat);
    d->buttonToColorFormat.insert(d->qmlRgbaBtn, ColorFormat::QmlRgbaFormat);
    d->buttonToColorFormat.insert(d->qmlHslaBtn, ColorFormat::QmlHslaFormat);
    d->buttonToColorFormat.insert(d->vecBtn, ColorFormat::GlslFormat);
    d->buttonToColorFormat.insert(d->hexBtn, ColorFormat::HexFormat);

    connect(d->btnGroup, qOverload<QAbstractButton *>(&QButtonGroup::buttonClicked),
            [=] (QAbstractButton *btn) {
        ColorFormat format = d->buttonToColorFormat.value(btn);

        d->setCurrentFormat(format);
    });

    // Color changes logic
    connect(d->colorPicker, &ColorPickerWidget::colorChanged,
            [=](const QColor &color) { d->onPickerColorChanged(color); });

    connect(d->hueSlider, &HueSlider::valueChanged,
            [=](int hue) { d->onHueChanged(hue); });

    connect(d->saturationSlider, &SaturationSlider::valueChanged,
            [=](int sat) { d->onSaturationChanged(sat); });

    connect(d->valueSlider, &ValueSlider::valueChanged,
            [=](int val) { d->onValueChanged(val); });

    connect(d->opacitySlider, &OpacitySlider::valueChanged,
            [=](int opacity) { d->onOpacityChanged(opacity); });

    setColorCategory(ColorCategory::AnyCategory);
    setOutputFormat(ColorFormat::QCssRgbUCharFormat);
    setColor(Qt::red);
}