mirror of
https://github.com/aseprite/aseprite.git
synced 2025-03-03 16:13:43 +00:00
Add zoom slider in StatusBar (issue #420)
This commit is contained in:
parent
fa53692221
commit
4dc6da286e
@ -375,6 +375,7 @@ add_library(app-lib
|
||||
ui/workspace.cpp
|
||||
ui/workspace_panel.cpp
|
||||
ui/workspace_tabs.cpp
|
||||
ui/zoom_entry.cpp
|
||||
ui_context.cpp
|
||||
util/autocrop.cpp
|
||||
util/clipboard.cpp
|
||||
|
@ -74,6 +74,9 @@ public:
|
||||
|
||||
void onScrollChanged(Editor* editor) override {
|
||||
updatePreviewEditor(this);
|
||||
|
||||
if (isActive())
|
||||
StatusBar::instance()->updateFromEditor(this);
|
||||
}
|
||||
|
||||
void onAfterFrameChanged(Editor* editor) override {
|
||||
|
@ -372,7 +372,7 @@ void Editor::setEditorScroll(const gfx::Point& scroll, bool blitValidRegion)
|
||||
}
|
||||
}
|
||||
|
||||
void Editor::setEditorZoom(Zoom zoom)
|
||||
void Editor::setEditorZoom(const render::Zoom& zoom)
|
||||
{
|
||||
setZoomAndCenterInMouse(
|
||||
zoom, ui::get_mouse_position(),
|
||||
@ -1386,7 +1386,7 @@ bool Editor::isInsideSelection()
|
||||
m_document->mask()->containsPoint(spritePos.x, spritePos.y);
|
||||
}
|
||||
|
||||
void Editor::setZoomAndCenterInMouse(Zoom zoom,
|
||||
void Editor::setZoomAndCenterInMouse(const Zoom& zoom,
|
||||
const gfx::Point& mousePos, ZoomBehavior zoomBehavior)
|
||||
{
|
||||
HideBrushPreview hide(m_brushPreview);
|
||||
|
@ -121,10 +121,10 @@ namespace app {
|
||||
const render::Zoom& zoom() const { return m_zoom; }
|
||||
const gfx::Point& padding() const { return m_padding; }
|
||||
|
||||
void setZoom(render::Zoom zoom) { m_zoom = zoom; }
|
||||
void setZoom(const render::Zoom& zoom) { m_zoom = zoom; }
|
||||
void setDefaultScroll();
|
||||
void setEditorScroll(const gfx::Point& scroll, bool blitValidRegion);
|
||||
void setEditorZoom(render::Zoom zoom);
|
||||
void setEditorZoom(const render::Zoom& zoom);
|
||||
|
||||
// Updates the Editor's view.
|
||||
void updateEditor();
|
||||
@ -174,7 +174,7 @@ namespace app {
|
||||
// Returns true if the cursor is inside the active mask/selection.
|
||||
bool isInsideSelection();
|
||||
|
||||
void setZoomAndCenterInMouse(render::Zoom zoom,
|
||||
void setZoomAndCenterInMouse(const render::Zoom& zoom,
|
||||
const gfx::Point& mousePos, ZoomBehavior zoomBehavior);
|
||||
|
||||
void pasteImage(const Image* image, const Mask* mask);
|
||||
|
@ -1323,12 +1323,7 @@ void SkinTheme::paintSlider(PaintEvent& ev)
|
||||
|
||||
// Draw text
|
||||
std::string old_text = widget->getText();
|
||||
|
||||
{
|
||||
char buf[128];
|
||||
sprintf(buf, "%d", value);
|
||||
widget->setTextQuiet(buf);
|
||||
}
|
||||
widget->setTextQuiet(widget->convertValueToText(value));
|
||||
|
||||
{
|
||||
IntersectClip clip(g, Rect(rc.x, rc.y, x-rc.x, rc.h));
|
||||
|
@ -31,6 +31,7 @@
|
||||
#include "app/ui/status_bar.h"
|
||||
#include "app/ui/timeline.h"
|
||||
#include "app/ui/toolbar.h"
|
||||
#include "app/ui/zoom_entry.h"
|
||||
#include "app/ui_context.h"
|
||||
#include "app/util/range_utils.h"
|
||||
#include "base/bind.h"
|
||||
@ -198,6 +199,8 @@ StatusBar::StatusBar()
|
||||
m_currentFrame = new GotoFrameEntry();
|
||||
m_newFrame = new Button("+");
|
||||
m_newFrame->Click.connect(Bind<void>(&StatusBar::newFrame, this));
|
||||
m_zoomEntry = new ZoomEntry;
|
||||
m_zoomEntry->ZoomChange.connect(&StatusBar::onChangeZoom, this);
|
||||
|
||||
setup_mini_look(m_currentFrame);
|
||||
setup_mini_look(m_newFrame);
|
||||
@ -209,6 +212,7 @@ StatusBar::StatusBar()
|
||||
|
||||
box1->addChild(m_frameLabel);
|
||||
box1->addChild(box4);
|
||||
box1->addChild(m_zoomEntry);
|
||||
|
||||
m_docControls->addChild(box1);
|
||||
}
|
||||
@ -217,6 +221,7 @@ StatusBar::StatusBar()
|
||||
TooltipManager* tooltipManager = new TooltipManager();
|
||||
addChild(tooltipManager);
|
||||
tooltipManager->addTooltipFor(m_currentFrame, "Current Frame", BOTTOM);
|
||||
tooltipManager->addTooltipFor(m_zoomEntry, "Zoom Level", BOTTOM);
|
||||
|
||||
Preferences::instance().toolBox.activeTool.AfterChange.connect(
|
||||
Bind<void>(&StatusBar::onCurrentToolChange, this));
|
||||
@ -250,6 +255,12 @@ void StatusBar::clearText()
|
||||
setStatusText(1, "");
|
||||
}
|
||||
|
||||
void StatusBar::updateFromEditor(Editor* editor)
|
||||
{
|
||||
if (editor)
|
||||
m_zoomEntry->setZoom(editor->zoom());
|
||||
}
|
||||
|
||||
bool StatusBar::setStatusText(int msecs, const char *format, ...)
|
||||
{
|
||||
if ((ui::clock() > m_timeout) || (msecs > 0)) {
|
||||
@ -527,4 +538,10 @@ void StatusBar::newFrame()
|
||||
UIContext::instance()->executeCommand(cmd);
|
||||
}
|
||||
|
||||
void StatusBar::onChangeZoom(const render::Zoom& zoom)
|
||||
{
|
||||
if (current_editor)
|
||||
current_editor->setEditorZoom(zoom);
|
||||
}
|
||||
|
||||
} // namespace app
|
||||
|
@ -29,10 +29,14 @@ namespace ui {
|
||||
class Window;
|
||||
}
|
||||
|
||||
namespace render {
|
||||
class Zoom;
|
||||
}
|
||||
|
||||
namespace app {
|
||||
class ButtonSet;
|
||||
class Editor;
|
||||
class StatusBar;
|
||||
class ZoomEntry;
|
||||
|
||||
namespace tools {
|
||||
class Tool;
|
||||
@ -57,6 +61,9 @@ namespace app {
|
||||
void showTool(int msecs, tools::Tool* tool);
|
||||
void showSnapToGridWarning(bool state);
|
||||
|
||||
// Used by AppEditor to update the zoom level in the status bar.
|
||||
void updateFromEditor(Editor* editor);
|
||||
|
||||
protected:
|
||||
void onResize(ui::ResizeEvent& ev) override;
|
||||
void onPreferredSize(ui::PreferredSizeEvent& ev) override;
|
||||
@ -75,6 +82,7 @@ namespace app {
|
||||
void onCurrentToolChange();
|
||||
void onCelOpacitySliderChange();
|
||||
void newFrame();
|
||||
void onChangeZoom(const render::Zoom& zoom);
|
||||
|
||||
enum State { SHOW_TEXT, SHOW_COLOR, SHOW_TOOL };
|
||||
|
||||
@ -92,6 +100,7 @@ namespace app {
|
||||
ui::Label* m_frameLabel;
|
||||
ui::Entry* m_currentFrame; // Current frame and go to frame entry
|
||||
ui::Button* m_newFrame; // Button to create a new frame
|
||||
ZoomEntry* m_zoomEntry;
|
||||
doc::Document* m_doc; // Document used to show the cel slider
|
||||
|
||||
// Tip window
|
||||
|
70
src/app/ui/zoom_entry.cpp
Normal file
70
src/app/ui/zoom_entry.cpp
Normal file
@ -0,0 +1,70 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include "app/ui/zoom_entry.h"
|
||||
|
||||
#include "app/modules/gui.h"
|
||||
#include "base/scoped_value.h"
|
||||
#include "gfx/rect.h"
|
||||
#include "gfx/region.h"
|
||||
#include "ui/manager.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/popup_window.h"
|
||||
#include "ui/slider.h"
|
||||
#include "ui/system.h"
|
||||
#include "ui/theme.h"
|
||||
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
namespace app {
|
||||
|
||||
using namespace gfx;
|
||||
using namespace ui;
|
||||
|
||||
ZoomEntry::ZoomEntry()
|
||||
: IntEntry(0, render::Zoom::linearValues()-1, this)
|
||||
{
|
||||
setSuffix("%");
|
||||
setup_mini_look(this);
|
||||
|
||||
setZoom(render::Zoom(1, 1));
|
||||
}
|
||||
|
||||
void ZoomEntry::setZoom(const render::Zoom& zoom)
|
||||
{
|
||||
setText(onGetTextFromValue(zoom.linearScale()));
|
||||
}
|
||||
|
||||
void ZoomEntry::onValueChange()
|
||||
{
|
||||
IntEntry::onValueChange();
|
||||
|
||||
render::Zoom zoom = render::Zoom::fromLinearScale(getValue());
|
||||
ZoomChange(zoom);
|
||||
}
|
||||
|
||||
std::string ZoomEntry::onGetTextFromValue(int value)
|
||||
{
|
||||
render::Zoom zoom = render::Zoom::fromLinearScale(value);
|
||||
|
||||
char buf[256];
|
||||
std::sprintf(buf, "%.1f", zoom.scale() * 100.0);
|
||||
return buf;
|
||||
}
|
||||
|
||||
int ZoomEntry::onGetValueFromText(const std::string& text)
|
||||
{
|
||||
double value = std::strtod(text.c_str(), nullptr);
|
||||
return render::Zoom::fromScale(value / 100.0).linearScale();
|
||||
}
|
||||
|
||||
} // namespace app
|
37
src/app/ui/zoom_entry.h
Normal file
37
src/app/ui/zoom_entry.h
Normal file
@ -0,0 +1,37 @@
|
||||
// Aseprite
|
||||
// Copyright (C) 2001-2015 David Capello
|
||||
//
|
||||
// This program is free software; you can redistribute it and/or modify
|
||||
// it under the terms of the GNU General Public License version 2 as
|
||||
// published by the Free Software Foundation.
|
||||
|
||||
#ifndef APP_UI_ZOOM_ENTRY_H_INCLUDED
|
||||
#define APP_UI_ZOOM_ENTRY_H_INCLUDED
|
||||
#pragma once
|
||||
|
||||
#include "render/zoom.h"
|
||||
#include "ui/int_entry.h"
|
||||
#include "ui/slider.h"
|
||||
|
||||
namespace app {
|
||||
|
||||
class ZoomEntry : public ui::IntEntry
|
||||
, public ui::SliderDelegate {
|
||||
public:
|
||||
ZoomEntry();
|
||||
|
||||
void setZoom(const render::Zoom& zoom);
|
||||
|
||||
Signal1<void, const render::Zoom&> ZoomChange;
|
||||
|
||||
private:
|
||||
// SliderDelegate impl
|
||||
std::string onGetTextFromValue(int value) override;
|
||||
int onGetValueFromText(const std::string& text) override;
|
||||
|
||||
void onValueChange() override;
|
||||
};
|
||||
|
||||
} // namespace app
|
||||
|
||||
#endif
|
@ -54,7 +54,7 @@ void Zoom::out()
|
||||
}
|
||||
}
|
||||
|
||||
int Zoom::linearScale()
|
||||
int Zoom::linearScale() const
|
||||
{
|
||||
for (int i=0; i<scales_size; ++i) {
|
||||
// Exact match
|
||||
@ -82,10 +82,13 @@ Zoom Zoom::fromLinearScale(int i)
|
||||
// static
|
||||
int Zoom::findClosestLinearScale(double scale)
|
||||
{
|
||||
for (int i=0; i<scales_size-1; ++i) {
|
||||
double min = double(scales[i ][0]) / double(scales[i ][1]) - 0.5;
|
||||
double max = double(scales[i+1][0]) / double(scales[i+1][1]) - 0.5;
|
||||
if (scale >= min && scale <= max)
|
||||
for (int i=1; i<scales_size-1; ++i) {
|
||||
double min = double(scales[i-1][0]) / double(scales[i-1][1]);
|
||||
double mid = double(scales[i ][0]) / double(scales[i ][1]);
|
||||
double max = double(scales[i+1][0]) / double(scales[i+1][1]);
|
||||
|
||||
if (scale >= (min+mid)/2.0 &&
|
||||
scale <= (mid+max)/2.0)
|
||||
return i;
|
||||
}
|
||||
if (scale < 1.0)
|
||||
@ -94,4 +97,9 @@ int Zoom::findClosestLinearScale(double scale)
|
||||
return scales_size-1;
|
||||
}
|
||||
|
||||
int Zoom::linearValues()
|
||||
{
|
||||
return scales_size;
|
||||
}
|
||||
|
||||
} // namespace render
|
||||
|
@ -53,7 +53,7 @@ namespace render {
|
||||
|
||||
// Returns an linear zoom scale. This position can be incremented
|
||||
// or decremented to get a new zoom value.
|
||||
int linearScale();
|
||||
int linearScale() const;
|
||||
|
||||
bool operator==(const Zoom& other) const {
|
||||
return m_num == other.m_num && m_den == other.m_den;
|
||||
@ -65,6 +65,7 @@ namespace render {
|
||||
|
||||
static Zoom fromScale(double scale);
|
||||
static Zoom fromLinearScale(int i);
|
||||
static int linearValues();
|
||||
|
||||
private:
|
||||
static int findClosestLinearScale(double scale);
|
||||
|
@ -13,9 +13,11 @@
|
||||
#include "base/scoped_value.h"
|
||||
#include "gfx/rect.h"
|
||||
#include "gfx/region.h"
|
||||
#include "she/font.h"
|
||||
#include "ui/manager.h"
|
||||
#include "ui/message.h"
|
||||
#include "ui/popup_window.h"
|
||||
#include "ui/preferred_size_event.h"
|
||||
#include "ui/slider.h"
|
||||
#include "ui/system.h"
|
||||
#include "ui/theme.h"
|
||||
@ -26,14 +28,17 @@ namespace ui {
|
||||
|
||||
using namespace gfx;
|
||||
|
||||
IntEntry::IntEntry(int min, int max)
|
||||
IntEntry::IntEntry(int min, int max, SliderDelegate* sliderDelegate)
|
||||
: Entry(int(std::ceil(std::log10((double)max)))+1, "")
|
||||
, m_min(min)
|
||||
, m_max(max)
|
||||
, m_slider(m_min, m_max, m_min, sliderDelegate)
|
||||
, m_popupWindow(NULL)
|
||||
, m_slider(NULL)
|
||||
, m_changeFromSlider(false)
|
||||
{
|
||||
m_slider.setFocusStop(false); // In this way the IntEntry doesn't lost the focus
|
||||
m_slider.setTransparent(true);
|
||||
m_slider.Change.connect(&IntEntry::onChangeSlider, this);
|
||||
}
|
||||
|
||||
IntEntry::~IntEntry()
|
||||
@ -43,7 +48,7 @@ IntEntry::~IntEntry()
|
||||
|
||||
int IntEntry::getValue() const
|
||||
{
|
||||
int value = getTextInt();
|
||||
int value = m_slider.convertTextToValue(getText());
|
||||
return MID(m_min, value, m_max);
|
||||
}
|
||||
|
||||
@ -51,10 +56,10 @@ void IntEntry::setValue(int value)
|
||||
{
|
||||
value = MID(m_min, value, m_max);
|
||||
|
||||
setTextf("%d", value);
|
||||
setText(m_slider.convertValueToText(value));
|
||||
|
||||
if (m_slider && !m_changeFromSlider)
|
||||
m_slider->setValue(value);
|
||||
if (m_popupWindow && !m_changeFromSlider)
|
||||
m_slider.setValue(value);
|
||||
|
||||
onValueChange();
|
||||
}
|
||||
@ -81,13 +86,13 @@ bool IntEntry::onProcessMessage(Message* msg)
|
||||
if (hasCapture()) {
|
||||
MouseMessage* mouseMsg = static_cast<MouseMessage*>(msg);
|
||||
Widget* pick = getManager()->pick(mouseMsg->position());
|
||||
if (pick == m_slider) {
|
||||
if (pick == &m_slider) {
|
||||
releaseMouse();
|
||||
|
||||
MouseMessage mouseMsg2(kMouseDownMessage,
|
||||
mouseMsg->buttons(),
|
||||
mouseMsg->position());
|
||||
m_slider->sendMessage(&mouseMsg2);
|
||||
m_slider.sendMessage(&mouseMsg2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -121,6 +126,20 @@ bool IntEntry::onProcessMessage(Message* msg)
|
||||
return Entry::onProcessMessage(msg);
|
||||
}
|
||||
|
||||
void IntEntry::onPreferredSize(PreferredSizeEvent& ev)
|
||||
{
|
||||
int min_w = getFont()->textLength(m_slider.convertValueToText(m_min));
|
||||
int max_w = getFont()->textLength(m_slider.convertValueToText(m_max));
|
||||
|
||||
int w = MAX(min_w, max_w) + getFont()->charWidth('%');
|
||||
int h = getTextHeight();
|
||||
|
||||
w += border().width();
|
||||
h += border().height();
|
||||
|
||||
ev.setPreferredSize(w, h);
|
||||
}
|
||||
|
||||
void IntEntry::onEntryChange()
|
||||
{
|
||||
Entry::onEntryChange();
|
||||
@ -134,9 +153,17 @@ void IntEntry::onValueChange()
|
||||
|
||||
void IntEntry::openPopup()
|
||||
{
|
||||
m_slider.setValue(getValue());
|
||||
|
||||
Rect rc = getBounds();
|
||||
rc.y += rc.h;
|
||||
rc.h += 2*guiscale();
|
||||
int sliderH = m_slider.getPreferredSize().h;
|
||||
|
||||
if (rc.y+rc.h+sliderH < ui::display_h())
|
||||
rc.y += rc.h;
|
||||
else
|
||||
rc.y -= sliderH;
|
||||
|
||||
rc.h = sliderH;
|
||||
rc.w = 128*guiscale();
|
||||
if (rc.x+rc.w > ui::display_w())
|
||||
rc.x = rc.x - rc.w + getBounds().w;
|
||||
@ -152,36 +179,42 @@ void IntEntry::openPopup()
|
||||
rgn.createUnion(rgn, Region(getBounds()));
|
||||
m_popupWindow->setHotRegion(rgn);
|
||||
|
||||
m_slider = new Slider(m_min, m_max, getValue());
|
||||
m_slider->setFocusStop(false); // In this way the IntEntry doesn't lost the focus
|
||||
m_slider->setTransparent(true);
|
||||
m_slider->Change.connect(&IntEntry::onChangeSlider, this);
|
||||
m_popupWindow->addChild(m_slider);
|
||||
|
||||
m_popupWindow->addChild(&m_slider);
|
||||
m_popupWindow->openWindow();
|
||||
}
|
||||
|
||||
void IntEntry::closePopup()
|
||||
{
|
||||
if (m_popupWindow) {
|
||||
removeSlider();
|
||||
|
||||
m_popupWindow->closeWindow(NULL);
|
||||
delete m_popupWindow;
|
||||
m_popupWindow = NULL;
|
||||
m_slider = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void IntEntry::onChangeSlider()
|
||||
{
|
||||
base::ScopedValue<bool> lockFlag(m_changeFromSlider, true, false);
|
||||
setValue(m_slider->getValue());
|
||||
setValue(m_slider.getValue());
|
||||
selectAllText();
|
||||
}
|
||||
|
||||
void IntEntry::onPopupClose(CloseEvent& ev)
|
||||
{
|
||||
removeSlider();
|
||||
|
||||
deselectText();
|
||||
releaseFocus();
|
||||
}
|
||||
|
||||
void IntEntry::removeSlider()
|
||||
{
|
||||
if (m_popupWindow &&
|
||||
m_slider.getParent() == m_popupWindow) {
|
||||
m_popupWindow->removeChild(&m_slider);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
|
@ -9,16 +9,16 @@
|
||||
#pragma once
|
||||
|
||||
#include "ui/entry.h"
|
||||
#include "ui/slider.h"
|
||||
|
||||
namespace ui {
|
||||
|
||||
class CloseEvent;
|
||||
class PopupWindow;
|
||||
class Slider;
|
||||
|
||||
class IntEntry : public Entry {
|
||||
public:
|
||||
IntEntry(int min, int max);
|
||||
IntEntry(int min, int max, SliderDelegate* sliderDelegate = nullptr);
|
||||
~IntEntry();
|
||||
|
||||
int getValue() const;
|
||||
@ -26,6 +26,7 @@ namespace ui {
|
||||
|
||||
protected:
|
||||
bool onProcessMessage(Message* msg) override;
|
||||
void onPreferredSize(PreferredSizeEvent& ev) override;
|
||||
void onEntryChange() override;
|
||||
|
||||
// New events
|
||||
@ -36,11 +37,12 @@ namespace ui {
|
||||
void closePopup();
|
||||
void onChangeSlider();
|
||||
void onPopupClose(CloseEvent& ev);
|
||||
void removeSlider();
|
||||
|
||||
int m_min;
|
||||
int m_max;
|
||||
Slider m_slider;
|
||||
PopupWindow* m_popupWindow;
|
||||
Slider* m_slider;
|
||||
bool m_changeFromSlider;
|
||||
};
|
||||
|
||||
|
@ -26,12 +26,13 @@ static int slider_press_x;
|
||||
static int slider_press_value;
|
||||
static bool slider_press_left;
|
||||
|
||||
Slider::Slider(int min, int max, int value)
|
||||
Slider::Slider(int min, int max, int value, SliderDelegate* delegate)
|
||||
: Widget(kSliderWidget)
|
||||
, m_min(min)
|
||||
, m_max(max)
|
||||
, m_value(MID(min, value, max))
|
||||
, m_readOnly(false)
|
||||
, m_delegate(delegate)
|
||||
{
|
||||
this->setFocusStop(true);
|
||||
initTheme();
|
||||
@ -58,13 +59,33 @@ void Slider::setValue(int value)
|
||||
// It DOES NOT emit CHANGE signal! to avoid recursive calls.
|
||||
}
|
||||
|
||||
void Slider::getSliderThemeInfo(int* min, int* max, int* value)
|
||||
void Slider::getSliderThemeInfo(int* min, int* max, int* value) const
|
||||
{
|
||||
if (min) *min = m_min;
|
||||
if (max) *max = m_max;
|
||||
if (value) *value = m_value;
|
||||
}
|
||||
|
||||
std::string Slider::convertValueToText(int value) const
|
||||
{
|
||||
if (m_delegate)
|
||||
return m_delegate->onGetTextFromValue(value);
|
||||
else {
|
||||
char buf[128];
|
||||
std::sprintf(buf, "%d", value);
|
||||
return buf;
|
||||
}
|
||||
}
|
||||
|
||||
int Slider::convertTextToValue(const std::string& text) const
|
||||
{
|
||||
if (m_delegate)
|
||||
return m_delegate->onGetValueFromText(text);
|
||||
else {
|
||||
return std::strtol(text.c_str(), NULL, 10);
|
||||
}
|
||||
}
|
||||
|
||||
bool Slider::onProcessMessage(Message* msg)
|
||||
{
|
||||
switch (msg->type()) {
|
||||
@ -194,12 +215,8 @@ not_used:;
|
||||
|
||||
void Slider::onPreferredSize(PreferredSizeEvent& ev)
|
||||
{
|
||||
char buf[256];
|
||||
std::sprintf(buf, "%d", m_min);
|
||||
int min_w = getFont()->textLength(buf);
|
||||
|
||||
std::sprintf(buf, "%d", m_max);
|
||||
int max_w = getFont()->textLength(buf);
|
||||
int min_w = getFont()->textLength(convertValueToText(m_min));
|
||||
int max_w = getFont()->textLength(convertValueToText(m_max));
|
||||
|
||||
int w = MAX(min_w, max_w);
|
||||
int h = getTextHeight();
|
||||
|
@ -13,9 +13,16 @@
|
||||
|
||||
namespace ui {
|
||||
|
||||
class SliderDelegate {
|
||||
public:
|
||||
virtual ~SliderDelegate() { }
|
||||
virtual std::string onGetTextFromValue(int value) = 0;
|
||||
virtual int onGetValueFromText(const std::string& text) = 0;
|
||||
};
|
||||
|
||||
class Slider : public Widget {
|
||||
public:
|
||||
Slider(int min, int max, int value);
|
||||
Slider(int min, int max, int value, SliderDelegate* delegate = nullptr);
|
||||
|
||||
int getMinValue() const { return m_min; }
|
||||
int getMaxValue() const { return m_max; }
|
||||
@ -27,7 +34,10 @@ namespace ui {
|
||||
bool isReadOnly() const { return m_readOnly; }
|
||||
void setReadOnly(bool readOnly) { m_readOnly = readOnly; }
|
||||
|
||||
void getSliderThemeInfo(int* min, int* max, int* value);
|
||||
void getSliderThemeInfo(int* min, int* max, int* value) const;
|
||||
|
||||
std::string convertValueToText(int value) const;
|
||||
int convertTextToValue(const std::string& text) const;
|
||||
|
||||
// Signals
|
||||
Signal0<void> Change;
|
||||
@ -50,6 +60,7 @@ namespace ui {
|
||||
int m_max;
|
||||
int m_value;
|
||||
bool m_readOnly;
|
||||
SliderDelegate* m_delegate;
|
||||
};
|
||||
|
||||
} // namespace ui
|
||||
|
@ -978,13 +978,16 @@ bool Widget::paintEvent(Graphics* graphics)
|
||||
|
||||
enableFlags(HIDDEN);
|
||||
|
||||
gfx::Region rgn(getParent()->getBounds());
|
||||
rgn.createIntersection(rgn,
|
||||
gfx::Region(
|
||||
graphics->getClipBounds().offset(
|
||||
graphics->getInternalDeltaX(),
|
||||
graphics->getInternalDeltaY())));
|
||||
getParent()->paint(graphics, rgn);
|
||||
if (getParent()) {
|
||||
gfx::Region rgn(getParent()->getBounds());
|
||||
rgn.createIntersection(
|
||||
rgn,
|
||||
gfx::Region(
|
||||
graphics->getClipBounds().offset(
|
||||
graphics->getInternalDeltaX(),
|
||||
graphics->getInternalDeltaY())));
|
||||
getParent()->paint(graphics, rgn);
|
||||
}
|
||||
|
||||
disableFlags(HIDDEN);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user