Skip to content

Commit

Permalink
Implementing view and element drop support
Browse files Browse the repository at this point in the history
  • Loading branch information
djowel committed Oct 11, 2023
1 parent 1d85cf8 commit e752884
Show file tree
Hide file tree
Showing 19 changed files with 388 additions and 43 deletions.
1 change: 1 addition & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ add_subdirectory(custom_control)
add_subdirectory(child_window)
add_subdirectory(sync_scrollbars)
add_subdirectory(icons_list)
add_subdirectory(drop_file)
31 changes: 31 additions & 0 deletions examples/drop_file/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
cmake_minimum_required(VERSION 3.9.6...3.15.0)
project(HelloUniverse LANGUAGES C CXX)

if (NOT ELEMENTS_ROOT)
message(FATAL_ERROR "ELEMENTS_ROOT is not set")
endif()

# Make sure ELEMENTS_ROOT is an absolute path to add to the CMake module path
get_filename_component(ELEMENTS_ROOT "${ELEMENTS_ROOT}" ABSOLUTE)
set (CMAKE_MODULE_PATH "${CMAKE_MODULE_PATH};${ELEMENTS_ROOT}/cmake")

# If we are building outside the project, you need to set ELEMENTS_ROOT:
if (NOT ELEMENTS_BUILD_EXAMPLES)
include(ElementsConfigCommon)
set(ELEMENTS_BUILD_EXAMPLES OFF)
add_subdirectory(${ELEMENTS_ROOT} elements)
endif()

set(ELEMENTS_APP_PROJECT "DropFile")
set(ELEMENTS_APP_TITLE "Drop File")
set(ELEMENTS_APP_COPYRIGHT "Copyright (c) 2023 Joel de Guzman")
set(ELEMENTS_APP_ID "com.cycfi.drop-file")
set(ELEMENTS_APP_VERSION "1.0")

set(ELEMENTS_APP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/main.cpp)
set(ELEMENTS_APP_RESOURCES ${CMAKE_CURRENT_SOURCE_DIR}/resources/space.jpg)

# For your custom application icon on macOS or Windows see cmake/AppIcon.cmake module
include(AppIcon)
include(ElementsConfigApp)

59 changes: 59 additions & 0 deletions examples/drop_file/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*=============================================================================
Copyright (c) 2016-2020 Joel de Guzman
Distributed under the MIT License (https://opensource.org/licenses/MIT)
=============================================================================*/
#include <elements.hpp>

using namespace cycfi::elements;

using cycfi::artist::rgba;

// Main window background color
auto constexpr bkd_color = rgba(35, 35, 37, 255);
auto background = box(bkd_color);

int main(int argc, char* argv[])
{
app _app(argc, argv, "Drop File", "com.cycfi.drop-file");
window _win(_app.name());
_win.on_close = [&_app]() { _app.stop(); };

view view_(_win);

auto image_ = share(image{ "space.jpg" });
auto drop_box_ = share(drop_box(scroller(hold(image_))));

drop_box_->on_drop = [image_ = get(image_), &view_](drop_info const& info)
{
if (info.paths.size() == 1) // We accept only one file
{
auto image_path = info.paths[0];
if (auto p = image_.lock())
{
try
{
auto img = image{image_path};
*p = img;
view_.refresh(*p);
}
catch (std::runtime_error const&)
{
// Invalid image
return false;
}
return true;
}
}
return false;
};

view_.content(
align_center_middle(label("Drop a picture here").font_size(20)),
margin({20, 20, 20, 20}, hold(drop_box_)),
share(background)
);

_app.run();
return 0;
}
Binary file added examples/drop_file/resources/space.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 14 additions & 6 deletions lib/host/macos/base_view.mm
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ -(void) makeDropInfo : (id <NSDraggingInfo>) sender : (ph::drop_info*) info
}
}

- (BOOL)performDragOperation : (id <NSDraggingInfo>) sender
- (BOOL) performDragOperation : (id <NSDraggingInfo>) sender
{
ph::drop_info info;
[self makeDropInfo : sender : &info];
Expand All @@ -701,29 +701,37 @@ - (BOOL)performDragOperation : (id <NSDraggingInfo>) sender
return NO;
}

- (BOOL)wantsPeriodicDraggingUpdates
- (BOOL) wantsPeriodicDraggingUpdates
{
return YES;
}

- (NSDragOperation)draggingEntered : (id <NSDraggingInfo>) sender
- (NSDragOperation) draggingEntered : (id <NSDraggingInfo>) sender
{
ph::drop_info info;
[self makeDropInfo : sender : &info];
if (info.paths.size())
_view->track_drop(info);
_view->track_drop(info, ph::cursor_tracking::entering);
return NSDragOperationGeneric;
}

- (NSDragOperation)draggingUpdated : (id<NSDraggingInfo>) sender
- (NSDragOperation) draggingUpdated : (id<NSDraggingInfo>) sender
{
ph::drop_info info;
[self makeDropInfo : sender : &info];
if (info.paths.size())
_view->track_drop(info);
_view->track_drop(info, ph::cursor_tracking::hovering);
return NSDragOperationGeneric;
}

- (void) draggingExited : (id <NSDraggingInfo>) sender
{
ph::drop_info info;
[self makeDropInfo : sender : &info];
if (info.paths.size())
_view->track_drop(info, ph::cursor_tracking::leaving);
}

@end // @implementation ElementsView

namespace cycfi { namespace elements
Expand Down
4 changes: 2 additions & 2 deletions lib/include/elements/base_view.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -321,7 +321,7 @@ namespace cycfi { namespace elements
virtual bool text(text_info const& info);
virtual void begin_focus();
virtual void end_focus();
virtual void track_drop(drop_info const& info);
virtual void track_drop(drop_info const& info, cursor_tracking status);
virtual bool drop(drop_info const& info);
virtual void poll();

Expand Down Expand Up @@ -349,7 +349,7 @@ namespace cycfi { namespace elements
inline bool base_view::text(text_info const& /* info */) { return false; }
inline void base_view::begin_focus() {}
inline void base_view::end_focus() {}
inline void base_view::track_drop(drop_info const& /*info*/) {}
inline void base_view::track_drop(drop_info const& /*info*/, cursor_tracking /* status */) {}
inline bool base_view::drop(drop_info const& /*info*/)
{
return false;
Expand Down
1 change: 1 addition & 0 deletions lib/include/elements/element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <elements/element/composite.hpp>
#include <elements/element/child_window.hpp>
#include <elements/element/dial.hpp>
#include <elements/element/drop.hpp>
#include <elements/element/dynamic_list.hpp>
#include <elements/element/floating.hpp>
#include <elements/element/flow.hpp>
Expand Down
3 changes: 3 additions & 0 deletions lib/include/elements/element/composite.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@ namespace cycfi { namespace elements
void focus(std::size_t index);
virtual void reset();

void track_drop(context const& ctx, drop_info const& info, cursor_tracking status) override;
bool drop(context const& ctx, drop_info const& info) override;

// Composite

using weak_element_ptr = std::weak_ptr<elements::element>;
Expand Down
83 changes: 83 additions & 0 deletions lib/include/elements/element/drop.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
/*=============================================================================
Copyright (c) 2016-2020 Joel de Guzman
Distributed under the MIT License [ https://opensource.org/licenses/MIT ]
=============================================================================*/
#if !defined(ELEMENTS_DROP_OCOBER_11_2023)
#define ELEMENTS_DROP_OCOBER_11_2023

#include <elements/element/proxy.hpp>
#include <functional>

namespace cycfi { namespace elements
{
template <typename Subject>
class drop_box : public proxy<Subject>
{
public:

using base_type = proxy<Subject>;
using on_drop_function = std::function<bool(drop_info const& info)>;

drop_box(Subject subject);
void draw(context const& ctx) override;
bool wants_control() const override;

void track_drop(context const& ctx, drop_info const& info, cursor_tracking status) override;
bool drop(context const& ctx, drop_info const& info) override;

on_drop_function on_drop = [](drop_info const&){ return false; };

private:

bool _is_tracking = false;
};

template <typename Subject>
drop_box<Subject>::drop_box(Subject subject)
: proxy<Subject>{std::move(subject)}
{}

template <typename Subject>
inline void drop_box<Subject>::draw(context const& ctx)
{
proxy<Subject>::draw(ctx);
if (_is_tracking)
{
auto& cnv = ctx.canvas;
auto& bounds = ctx.bounds;
cnv.stroke_style(get_theme().indicator_hilite_color.opacity(0.5));
cnv.line_width(2.0);
cnv.add_rect(bounds);
cnv.stroke();
}
}

template <typename Subject>
inline bool drop_box<Subject>::wants_control() const
{
return true;
}

template <typename Subject>
inline void drop_box<Subject>::track_drop(context const& ctx, drop_info const& /*info*/, cursor_tracking status)
{
auto new_is_tracking = status != cursor_tracking::leaving;
if (new_is_tracking != _is_tracking)
{
_is_tracking = new_is_tracking;
ctx.view.refresh(ctx.bounds);
}
}

template <typename Subject>
inline bool drop_box<Subject>::drop(context const& ctx, drop_info const& info)
{
bool r = on_drop(info);
_is_tracking = false;
ctx.view.refresh(ctx.bounds);
return r;
}
}}

#endif
3 changes: 3 additions & 0 deletions lib/include/elements/element/element.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ namespace cycfi { namespace elements
virtual element const* focus() const;
virtual element* focus();

virtual void track_drop(context const& ctx, drop_info const& info, cursor_tracking status);
virtual bool drop(context const& ctx, drop_info const& info);

enum tracking { none, begin_tracking, while_tracking, end_tracking };

protected:
Expand Down
16 changes: 16 additions & 0 deletions lib/include/elements/element/indirect.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,10 @@ namespace cycfi { namespace elements
void end_focus() override;
element const* focus() const override;
element* focus() override;

void track_drop(context const& ctx, drop_info const& info, cursor_tracking status) override;
bool drop(context const& ctx, drop_info const& info) override;

};

struct indirect_base : element
Expand Down Expand Up @@ -268,6 +272,18 @@ namespace cycfi { namespace elements
return this->get().focus();
}

template <typename Base>
inline void indirect<Base>::track_drop(context const& ctx, drop_info const& info, cursor_tracking status)
{
this->get().track_drop(ctx, info, status);
}

template <typename Base>
inline bool indirect<Base>::drop(context const& ctx, drop_info const& info)
{
return this->get().drop(ctx, info);
}

////////////////////////////////////////////////////////////////////////////
// reference (inline) implementation
////////////////////////////////////////////////////////////////////////////
Expand Down
Loading

0 comments on commit e752884

Please # to comment.