[Interest] QML select/drag/drop like a calendar.

Mark markg85 at gmail.com
Sun Jul 8 17:08:59 CEST 2012


On Sun, Jul 8, 2012 at 3:48 PM, Charley Bay <charleyb123 at gmail.com> wrote:
> ...(I left the whole post here, becuase IMHO it's very important for
> "context-to-the-question", and IMHO it's a good question.)
>
> Mark spaketh:
>
>> Hi,
>>
>> I'm developing a calendar in QML and thus far it seems to going quite
>> well.
>> Making a view with 12 months visible or a full month to select a day
>> isn't an issue. Works wonderful in QML.
>>
>> The place where i hit real big QML issues (or actually the lack of
>> components) is when i want to make the day overview. Go to google
>> calendar or the calendar in your emailing application and you notice
>> that you can select some cells in the day overview. Those selected
>> cells will become the "appointment" or event or whatever. That part is
>> close to impossible to implement in the current QML.
>>
>> Take this as an example if you don't know what i mean:
>> http://photos.appleinsider.com/Lionical4.png
>>
>> What i want to do is the following. I want users to be able to select
>> some cells in QML which will then be a event and stored somewhere.
>> Obviously the user can also have overlapping events or multiple events
>> at the same time - like other calendars allow as well.
>>
>> The issues i run into are:
>> - dynamic elements don't have a ID thus that can't be used. That
>> prevents selecting it and dragging/dropping the event on another date.
>> - there is no sane way to select some elements in a list or repeater
>> without doing all kinds of tricks
>> - once the selection is made, how can i lay an item on top of that
>> selection? Dynamic element?
>> - there don't seem to be any elements in QML that are suited for this
>>
>> So, is Qt 5 going to be of help here in making it easier? I doubt
>> that. Is there another way how i can make this work? Or do i need to
>> make special QML elements in C++ that are maintained in C++ as well
>> (id wise)? I'd hate to make that in C++ if it's even possible. It is
>> possible with QWidgets, but that kinda defeats the point of using QML.
>>
>> I hope this makes some sense since it's quite difficult to describe the
>> issue.
>> Incase you want to test my current testing code, clone:
>> git://gitorious.org/qmlcalendar/master.git
>>
>> in main.qml uncomment:
>>
>> CalendarDay
>> {
>>         anchors.fill: parent
>> }
>>
>> And comment the CalenderMonth part.
>>
>> Cheers,
>> Mark
>
>
> Very good overview.  Great question.
>
> I don't have a *specific* answer, but I have *specific* observations:
>
> (1) QML does this with properties.
> (2) Where is your "model"?

The model isn't there yet because i don't have a set of date to put
in, simple as that :)
The model isn't an issue, the issue is making a selection for a new
event that isn't in the model yet. If i try that i run in to all kind
of QML weirdness to even collect the data to put in the model. Like:
- Which cell is selected first?
- Are we moving up or down?
- What is the last selected cell?
- Once i do (magically) have the selection, how do i put a full blown
element on top of it?

What i would do if i can get the data reliable is making a model per
day that contains the events per day. Then probably something like
this for each entry:
- Start cell
- End cell
- various other info...

>
> Specifically, it takes time to "re-think" how to design without IDs.  You
> can implement a model and use IDs, but you actually don't need them.
> Rather, what you otherwise could achieve with IDs you can achieve with:

I though that as well.. Apparently QML has some measures in it to
prevent those things from happening. If i make something dynamically i
can't:
- place it one someone else as parent because i can't re-parent a
dynamic entry. No id which is needed for re-parenting.
>
> (a) properties on QML items/components (implies "categories-of-stuff",
> including "categories-of-one-item")
>
> (b) aggregation of QML items/components into "larger" items/components (a
> given "item" can have only one "parent", but it can have an infinite number
> of "step-parents"; for example, you could have a "step-parent" that
> "contains/references" all the
> "items-being-added-to-the-current-calendar-entry-being-created")
>
> The QML technology is "bound-properties-on-objects".  Because it's not (the
> historic) "imperative-actions/updates-after-user-event", everything you
> describe must be expressed declaratively.
>
> For example, the following might work, and is actually similar to how most
> "gestures" APIs work:
>
> (possible declarative assertions):
>
> *- "selected" things register themselves in the
> "current-transaction-(step-)parent" (NOTE: Unlike QWidgets, a QML "parent"
> has *no* direct implication for "child-placement" [e.g., like "layout"],
> although you can do that if you want.)
>
> *- "selected" things have a "front" Z-order
>
> *- "selected" things have a "highlight-decoration"
>
> ...You can even do something like,
>
> *- "selecting" this "cell" creates a "buddy" that references the
> originating-cell/item (and
> Z-order-placement-and-highlight-implied-by-the-original-item), and that
> "buddy" is part of the accumulated-items that will become the
> "calendar-event".
>
> Under a "gestures" API, a "gesture-event" accumulates all
> gesture-points-and-actions while the gesture is created, and when the
> gesture is "completed/recognized", the whole logical "gesture-event" is
> "popped" (processed, and converted into the logical action).
>
> For your model, you would incrementally
> accumulate-information-into-a-transaction (e.g., "for scheduling an event"),
> and when "done", the "MyCalendarEvent" would have all that information.
>

Read above :)

> That brings me to the second point:  You've got to have a model.  It sounds
> like you're "all-QML" at the moment (no C++).  That should be fine, but you
> must still code some kind of "data-structure(s)" to describe your
> calendar-and-events, *somewhat-independent* from the GUI components.  This
> "separation" gives you "room-to-breathe" as you perform lengthy
> transactions, permit "un-do", handle data-validation that permits you to
> "unwind" something that can't be completed, etc.

Well, i'm very much in favor of the hybrid solutions: QML and C++
where C++ feeds "ready to eat" data to QML. The model isn't there yet
because i'm having trouble even collecting all the data to put in the
model. Or in your terms, i'm having trouble connection all the dots
from the gestures ;)

>
> I tend to prefer my model in C++, because that gives me more expressive
> separation from the QML/GUI reflection/display.  The QML technology is
> fantastic for the "dynamic-property-reflection" to/from QML and my C++
> model.  Under this scenario, yes, it's code:  The C++ model has all the
> "atoms/classes" to fully describe the calendar, and the QML has all the
> "atoms/classes" to "represent" the calendar.  If you want to do it
> all-in-QML, that should work fine (you don't need C++), but I'd guess you'd
> need similar:
>
>   -- The QML "items" to represent the "view", and
>   -- the QML (or Javascript) "components" to represent the "model".
>
> Apologies if I misunderstood your question... ?  Specifically...
>
>> The issues i run into are:
>> - dynamic elements don't have a ID thus that can't be used. That
>> prevents selecting it and dragging/dropping the event on another date.
>
>
> You should set "properties" on those elements-selected-for-a-calendar-entry,
> or possibly have a "(step-)parent-aggregator" that accumulates all the
> "things" associated with that calendar-entry-being-defined.
>
>>
>> - there is no sane way to select some elements in a list or repeater
>> without doing all kinds of tricks
>
>
> Selecting an item can create a "buddy-item" that highlights the original
> item (e.g., "Z-order", alpha-blend), and that "buddy" can be parented by the
> "calendar-event-being-defined", while positioned based on its
> buddy-origin-item.

That "parented" part is the impossible one. Doing this calender stuff
required to make the objects (the selections) dynamically and those
can't be re-parented because they don't have an id. I can "fake
parent" them by just setting an X and Y, but that seems like to big of
a hack to me and very unreliable.
>
> Or, the "calendar-event-being-defined" can "imply" those things that should
> be "selected/decorated" within other lists and repeaters.
>
>>
>> - once the selection is made, how can i lay an item on top of that
>> selection? Dynamic element?
>
>
> You can set "properties" on the item-in-list-or-repeater (which probably
> "imply" decorations), or you can create a "buddy" and decorate the original
> (e.g., "Z-order" and "alpha-blend").
>
>> - there don't seem to be any elements in QML that are suited for this
>
>
> It seems like you need to
> "accumulate-a-bunch-of-stuff-while-you-define-a-calendar-entry", and at the
> end of this "transaction", you will have a "MyCalendarEntry".  That seems
> like "model" stuff to me, and you'd need to write that application-specific
> class/item (unless I misunderstand?)
>
> Good luck!
>
> --charley
>

Allow me to describe how i think this should work. That probably gives
a better view of how i'm trying to implement it in QML.

The user sees a list with a bunch of rectangles like you see in the
screenshot. The day overview. The user can then select some rectangles
which will become a new event. (this is where i am now which is
blocking me). Each new event should be placed in a Column container.
For one event it fills up the entire column, but if you have multiple
events starting on the same time they should all be placed in one
column next to each other. Here is some ascii art for that.

|--event--| |--event--| |--event--|
|              | |               | |              |
|              | |               | -------------
------------  |               |
                 |               |
                 --------------

Those are overlapping events starting at the same time.
The user can also have overlapping events that start at a time when
another event is already occurring. That's a bit tricky to make in
ascii art, but i will try..
|--event--|
  |--event--|
....

Both cases are Columns, but overlapping events with a different
starting time will simply have a small X offset.

I hope that helps a bit to see in which direction i want to go with
QML. The C++ side will simply store a model per day with all the event
details in it along with the cell at which it begins and ends. The QML
side should place them in the right places in in Column elements. The
point where i'm stuck is just collecting the data where an event
should be placed and placing an actual overlay on that place
dynamically.

Cheers,
Mark



More information about the Interest mailing list