Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added option for detecting window close (pressing X button) #104

Open
wants to merge 5 commits into
base: dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .github/FUNDING.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
# These are supported funding model platforms

github: [dovyski]
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Changelog
All notable changes to this project are documented in this file. The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).

## [2.7.0-BETA](https://github.com/Dovyski/cvui/releases/tag/v2.7.0-BETA) - 2018-06-26
## [2.7.0](https://github.com/Dovyski/cvui/releases/tag/v2.7.0) - 2018-10-08
### Added
- Python implementation of cvui, i.e. `cvui.py` ([read more](https://dovyski.github.io/cvui/usage/))
- [Python examples](https://github.com/Dovyski/cvui/tree/master/example/) ported from the already existing C++ ones.
Expand Down
146 changes: 146 additions & 0 deletions EnhancedWindow.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
#ifndef _ENHANCED_WINDOW_H_
#define _ENHANCED_WINDOW_H_

/*
This class enhances the window component of cvui by making it movable and minimizable.

Authors:
ShengYu - https://github.com/shengyu7697
Amaury Br�h�ret - https://github.com/abreheret

Contributions:
Fernando Bevilacqua <[email protected]>

Code licensed under the MIT license.
*/
class EnhancedWindow
{
private:
int mX;
int mY;
int mWidth;
int mHeight;
int mHeightNotMinimized;
cv::String mTitle;
int mDeltaY;
int mDeltaX;
bool mIsMoving;
bool mMinimized;
bool mMinimizable;
double mFontScale;

public:
EnhancedWindow(int x, int y, int width, int height, const cv::String& title, bool minimizable = true, double theFontScale = cvui::DEFAULT_FONT_SCALE):
mX(x),
mY(y),
mWidth(width),
mHeight(height),
mHeightNotMinimized(height),
mTitle(title),
mDeltaY(0),
mDeltaX(0),
mIsMoving(false),
mMinimized(false),
mMinimizable(minimizable),
mFontScale(theFontScale) {
}

void begin(cv::Mat &frame) {
int scaledTitleHeight = std::lround(20*mFontScale/cvui::DEFAULT_FONT_SCALE);
bool mouseInsideTitleArea = cvui::mouse().inside(cv::Rect(mX, mY, mWidth, scaledTitleHeight));
mHeight = mMinimized ? scaledTitleHeight : mHeightNotMinimized;

if (mIsMoving == false && cvui::mouse(cvui::DOWN) && mouseInsideTitleArea) {
mDeltaX = cvui::mouse().x - mX;
mDeltaY = cvui::mouse().y - mY;
mIsMoving = true;

} else if (mIsMoving && cvui::mouse(cvui::IS_DOWN)) {
mX = cvui::mouse().x - mDeltaX;
mY = cvui::mouse().y - mDeltaY;

} else {
mIsMoving = false;
mX = std::max(0, mX);
mY = std::max(0, mY);
mX = std::min(frame.cols - mWidth, mX);
mY = std::min(frame.rows - scaledTitleHeight, mY);
}

cvui::window(frame, mX, mY, mWidth, mHeight, mTitle, mFontScale);
if (mMinimizable && cvui::button(frame, mX + mWidth - scaledTitleHeight, mY + 1, scaledTitleHeight-1, scaledTitleHeight-1, mMinimized ? "+" : "-", mFontScale)) {
mMinimized = !mMinimized;
}
cvui::beginRow(frame, mX + std::lround(10*mFontScale/cvui::DEFAULT_FONT_SCALE), mY + std::lround(30*mFontScale/cvui::DEFAULT_FONT_SCALE), mWidth - scaledTitleHeight, mHeight - scaledTitleHeight);
cvui::beginColumn(mWidth - std::lround(10*mFontScale/cvui::DEFAULT_FONT_SCALE), mHeight - scaledTitleHeight);
}

/**
Use this function to get the maximum width of a child widget of EnhancedWindow.

\return the width of the EnhancedWindow without the inner borders that are automatically added
*/
int widthWithoutBorders() {
return mWidth - std::lround(20*mFontScale/cvui::DEFAULT_FONT_SCALE);
}

/**
Use this function to get the maximum height of a child widget of EnhancedWindow.

\return the height of the EnhancedWindow without title and inner borders that are automatically added
*/
int heightWithoutBorders() {
return mHeight - std::lround(40*mFontScale/cvui::DEFAULT_FONT_SCALE);
}

void end() {
cvui::endColumn();
cvui::endRow();
}

int posX() const {
return mX;
}

int posY() const {
return mY;
}

void setPosX(int posX) {
mX = posX;
}

void setPosY(int posY) {
mY = posY;
}

int width() const {
return mWidth;
}

int height() const {
return mHeight;
}

void setWidth(int w) {
mWidth = w;
}

void setHeight(int h) {
mHeight = mHeightNotMinimized = h;
}

double fontScale() const {
return mFontScale;
}

void setFontScale(double fontScale) {
mFontScale = fontScale;
}

bool isMinimized() const {
return mMinimized;
}
};

#endif // _ENHANCED_WINDOW_H_
File renamed without changes.
368 changes: 225 additions & 143 deletions cvui.h
100644 → 100755

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion docs/usage.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ int main() {
// Show window content
cvui::imshow(WINDOW1_NAME, frame);

if (cv::waitKey(20) == 27) {
if (cv::waitKey(20) == 27 || cv::getWindowProperty(WINDOW_NAME, cv::WND_PROP_ASPECT_RATIO) < 0) {
break;
}
}
Expand Down
2 changes: 1 addition & 1 deletion example/src/button-shortcut/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()

2 changes: 1 addition & 1 deletion example/src/canny/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
6 changes: 3 additions & 3 deletions example/src/canny/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ int main(int argc, const char *argv[])
// Should we apply Canny edge?
if (use_canny) {
// Yes, we should apply it.
cv::cvtColor(lena, frame, CV_BGR2GRAY);
cv::cvtColor(lena, frame, cv::COLOR_BGR2GRAY);
cv::Canny(frame, frame, low_threshold, high_threshold, 3);
cv::cvtColor(frame, frame, CV_GRAY2BGR);
cv::cvtColor(frame, frame, cv::COLOR_GRAY2BGR);
} else {
// No, so just copy the original image to the displaying frame.
lena.copyTo(frame);
Expand Down Expand Up @@ -60,4 +60,4 @@ int main(int argc, const char *argv[])
}

return 0;
}
}
2 changes: 1 addition & 1 deletion example/src/complext-layout/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
2 changes: 1 addition & 1 deletion example/src/hello-world/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
2 changes: 1 addition & 1 deletion example/src/image-button/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
2 changes: 1 addition & 1 deletion example/src/interaction-area/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
2 changes: 1 addition & 1 deletion example/src/main-app/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
41 changes: 25 additions & 16 deletions example/src/main-app/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,76 +16,85 @@ Licensed under the MIT license.

int main(int argc, const char *argv[])
{
cv::Mat frame = cv::Mat(300, 600, CV_8UC3);
bool checked = false;
bool checked2 = true;
int count = 0;
double countFloat = 0.0;
double trackbarValue = 0.0;

// Init cvui and tell it to create a OpenCV window, i.e. cv::namedWindow(WINDOW_NAME).
cvui::init(WINDOW_NAME);

double scaling = 1.0;
double currentScaling = -1;
cv::Mat frame;

while (true) {
if (scaling != currentScaling) {
frame = cv::Mat(std::lround(scaling * 300), std::lround(scaling * 600), CV_8UC3);
currentScaling = scaling;
}

// Fill the frame with a nice color
frame = cv::Scalar(49, 52, 49);

// Show some pieces of text.
cvui::text(frame, 50, 30, "Hey there!");
cvui::text(frame, std::lround(scaling * 50), std::lround(scaling * 30), "Hey there!", scaling*cvui::DEFAULT_FONT_SCALE);

// You can also specify the size of the text and its color
// using hex 0xRRGGBB CSS-like style.
cvui::text(frame, 200, 30, "Use hex 0xRRGGBB colors easily", 0.4, 0xff0000);
cvui::text(frame, std::lround(scaling * 200), std::lround(scaling * 30), "Use hex 0xRRGGBB colors easily", scaling*cvui::DEFAULT_FONT_SCALE, 0xff0000);

// Sometimes you want to show text that is not that simple, e.g. strings + numbers.
// You can use cvui::printf for that. It accepts a variable number of parameter, pretty
// much like printf does.
cvui::printf(frame, 200, 50, 0.4, 0x00ff00, "Use printf formatting: %d + %.2f = %f", 2, 3.2, 5.2);
cvui::printf(frame, std::lround(scaling * 200), std::lround(scaling * 50), scaling*cvui::DEFAULT_FONT_SCALE, 0x00ff00, "Use printf formatting: %d + %.2f = %f", 2, 3.2, 5.2);

// Buttons will return true if they were clicked, which makes
// handling clicks a breeze.
if (cvui::button(frame, 50, 60, "Button")) {
if (cvui::button(frame, std::lround(scaling * 50), std::lround(scaling * 60), "Colored Button", scaling*cvui::DEFAULT_FONT_SCALE, 0xa05050)) {
std::cout << "Button clicked" << std::endl;
}

// If you do not specify the button width/height, the size will be
// automatically adjusted to properly house the label.
cvui::button(frame, 200, 70, "Button with large label");
cvui::button(frame, std::lround(scaling * 200), std::lround(scaling * 70), "Button with large label", scaling*cvui::DEFAULT_FONT_SCALE);

// You can tell the width and height you want
cvui::button(frame, 410, 70, 15, 15, "x");
cvui::button(frame, std::lround(scaling * 410), std::lround(scaling * 70), std::lround(scaling * 15), std::lround(scaling * 15), "x", scaling*cvui::DEFAULT_FONT_SCALE);

// Window components are useful to create HUDs and similars. At the
// moment, there is no implementation to constraint content within a
// a window.
cvui::window(frame, 50, 120, 120, 100, "Window");
cvui::window(frame, std::lround(scaling * 50), std::lround(scaling * 120), std::lround(scaling * 120), std::lround(scaling * 100), "Window", scaling*cvui::DEFAULT_FONT_SCALE);

// The counter component can be used to alter int variables. Use
// the 4th parameter of the function to point it to the variable
// to be changed.
cvui::counter(frame, 200, 120, &count);
cvui::counter(frame, std::lround(scaling * 200), std::lround(scaling * 120), &count, 1, "%d", scaling*cvui::DEFAULT_FONT_SCALE);

// Counter can be used with doubles too. You can also specify
// the counter's step (how much it should change
// its value after each button press), as well as the format
// used to print the value.
cvui::counter(frame, 320, 120, &countFloat, 0.1, "%.1f");
cvui::counter(frame, std::lround(scaling * 320), std::lround(scaling * 120), &scaling, 0.1, "%.1f", scaling*cvui::DEFAULT_FONT_SCALE, 0x50a050);

cvui::printf(frame, std::lround(scaling * 340), std::lround(scaling * 150), scaling*cvui::DEFAULT_FONT_SCALE, 0xCECECE, "Scaling");

// The trackbar component can be used to create scales.
// It works with all numerical types (including chars).
cvui::trackbar(frame, 420, 110, 150, &trackbarValue, 0., 50.);
cvui::trackbar(frame, std::lround(scaling * 420), std::lround(scaling * 110), std::lround(scaling * 150), &trackbarValue, 0., 50., 1, "%.1Lf", 0, 1.0, scaling*cvui::DEFAULT_FONT_SCALE);

// Checkboxes also accept a pointer to a variable that controls
// the state of the checkbox (checked or not). cvui::checkbox() will
// automatically update the value of the boolean after all
// interactions, but you can also change it by yourself. Just
// do "checked = true" somewhere and the checkbox will change
// its appearance.
cvui::checkbox(frame, 200, 160, "Checkbox", &checked);
cvui::checkbox(frame, 200, 190, "A checked checkbox", &checked2);
cvui::checkbox(frame, std::lround(scaling * 200), std::lround(scaling * 190), "Checkbox", &checked, 0x000000, scaling*cvui::DEFAULT_FONT_SCALE);
cvui::checkbox(frame, std::lround(scaling * 200), std::lround(scaling * 220), "A checked checkbox", &checked2, 0x000000, scaling*cvui::DEFAULT_FONT_SCALE);

// Display the lib version at the bottom of the screen
cvui::printf(frame, frame.cols - 80, frame.rows - 20, 0.4, 0xCECECE, "cvui v.%s", cvui::VERSION);
cvui::printf(frame, frame.cols - std::lround(scaling * 80), frame.rows - std::lround(scaling * 20), scaling*cvui::DEFAULT_FONT_SCALE, 0xCECECE, "cvui v.%s", cvui::VERSION);

// This function must be called *AFTER* all UI components. It does
// all the behind the scenes magic to handle mouse clicks, etc.
Expand All @@ -101,4 +110,4 @@ int main(int argc, const char *argv[])
}

return 0;
}
}
2 changes: 1 addition & 1 deletion example/src/mouse-complex-buttons/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
2 changes: 1 addition & 1 deletion example/src/mouse-complex/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
2 changes: 1 addition & 1 deletion example/src/mouse/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
2 changes: 1 addition & 1 deletion example/src/multiple-files/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ if(ADD_PYTHON_EXAMPLES)
add_custom_command(
TARGET ${ApplicationName}
POST_BUILD
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_CURRENT_SOURCE_DIR}/*.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
COMMAND ${CMAKE_COMMAND} -E copy_if_different ${CMAKE_SOURCE_DIR}/EnhancedWindow.py ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}
)
endif()
Loading