Trying to implement calendar
Moderators: FourthWorld, heatherlaine, Klaus, kevinmiller, robinmiller
Trying to implement calendar
I need a calendar view for my program and am trying to make it look like iCal in OS X. So it's a grid of 7*5 objects that I move and resize when the stack is resized. That logic is straightforward and I have my first implementation where the objects I have placed on the stack are buttons. Sizing to fit the window works perfectly.
My problem is how can I draw the content of the button? When programming with Visual C++ under Windows I would just handle the WM_DRAW message and draw whatever I want into the button. In essence I want an owner-drawn button.
I've tried to look, but I can't figure out if Revolution supports such a way to do it. What I want to draw is the day number in the top righthand corner and depending on if there are events for a certain day, I would draw a couple of rounded rectangles with text inside them.
I would appreciate any pointers on how to tackle this problem. I also tried placing fields and rounded rectangles on top of the button and then grouping them together. However that broke my resizing code as the grouped control doesn't seem to change size even though I change the dimensions through my window sizer handler. Just the position changes. Could I somehow change the grouped controls size from the stack script? I don't want to do it from the group control itself as there are 35 of them on my card (or is it enough to implement the code just once?).
My problem is how can I draw the content of the button? When programming with Visual C++ under Windows I would just handle the WM_DRAW message and draw whatever I want into the button. In essence I want an owner-drawn button.
I've tried to look, but I can't figure out if Revolution supports such a way to do it. What I want to draw is the day number in the top righthand corner and depending on if there are events for a certain day, I would draw a couple of rounded rectangles with text inside them.
I would appreciate any pointers on how to tackle this problem. I also tried placing fields and rounded rectangles on top of the button and then grouping them together. However that broke my resizing code as the grouped control doesn't seem to change size even though I change the dimensions through my window sizer handler. Just the position changes. Could I somehow change the grouped controls size from the stack script? I don't want to do it from the group control itself as there are 35 of them on my card (or is it enough to implement the code just once?).
-
- Posts: 111
- Joined: Sun Aug 23, 2009 7:48 am
- Contact:
I think you should have a look at the datagrid. The more I start to learn about it the more I appreciate it.
Take a look at the documentation over at screenstepslive.
Take a look at the documentation over at screenstepslive.
I started out hoping the datagrid would work. In the form mode I can have only one column. For my calendar I need 7 columns and 5 rows. Thus I'd need 7 forms and then I would have to rewrite keyboard movement so that navigating by keyboard would be logical. Also I'd have to handle focus in and out so that the focus is only on one cell at a time.
Then I tried to use the data grid in table form but couldn't figure out how to have cells that contain formlike data (ie. several rows). If someone knows how to have several rows inside a cell in table mode I would like to know how to do it.
I've been playing around with my approach of a button and fields set into a group. I realized where I went wrong with the resizing, in my code I had
set the width of group tVarName to item 3 of lButtonRect - item 1 of lButtonRect
when I should have been addressing the individual elements of the grouped control as in:
set the width of field "Date" of group tVarName to item 3 of lButtonRect - item 1 of lButtonRect
now I have the controls moving and resizing properly. Next I have to figure out how to handle mouseDown and mouseDoubleDown so that the code is at the card level, not inside the grouped control. The card would handle knowing which date is selected and set the event information for all the days. Also the code in the card script would set the correct day numbers and disable the controls that don't belong to that month.
Then I tried to use the data grid in table form but couldn't figure out how to have cells that contain formlike data (ie. several rows). If someone knows how to have several rows inside a cell in table mode I would like to know how to do it.
I've been playing around with my approach of a button and fields set into a group. I realized where I went wrong with the resizing, in my code I had
set the width of group tVarName to item 3 of lButtonRect - item 1 of lButtonRect
when I should have been addressing the individual elements of the grouped control as in:
set the width of field "Date" of group tVarName to item 3 of lButtonRect - item 1 of lButtonRect
now I have the controls moving and resizing properly. Next I have to figure out how to handle mouseDown and mouseDoubleDown so that the code is at the card level, not inside the grouped control. The card would handle knowing which date is selected and set the event information for all the days. Also the code in the card script would set the correct day numbers and disable the controls that don't belong to that month.
-
- Posts: 111
- Joined: Sun Aug 23, 2009 7:48 am
- Contact:
As the datagrid lets you add whatever control you like in the column template you can easily att several fields or a table, group or even another datagrid to the template so it should not be hard to add more than one control.
One solution might be to use a field for each entry and set the HTMLText of the field to get the look that you want.
Yet another solution might be to make a group with several (7) datagrids side by side and control them all with one scrollbar.
But maybe the solution to your original question is a group. By making a group you can set up the "drawing" in the way you want.
One solution might be to use a field for each entry and set the HTMLText of the field to get the look that you want.
Yet another solution might be to make a group with several (7) datagrids side by side and control them all with one scrollbar.
But maybe the solution to your original question is a group. By making a group you can set up the "drawing" in the way you want.
Edit: Added code to grab the current month and figure out the start day so I can quit changing it by hand. Oct starts on thursday! Can supply the additional code if needed.
As far as the datagrid goes, I think it probably will do what you need. I put together a quicky example for you to look at (in form mode not table mode), heres a screeny:
http://twitpic.com/n6fa3
At the moment theres not much to it, just a button with code I can modify to change the start day of the week, and number of days in the month, at which point it changes all the labels. For the schedule keeping area, I put a scrolling list for each day that should be easy enough to populate from an sqlite database, or array or properties or however you choose to do it. . Haven't implemented code for those parts yet, but shouldn't be too bad.
As you can see, my design skills aren't very good, and i'm still learning rev (will always still be learning rev)
In case you're interested, heres the code I put in the button to populate the calendar page. As I mentioned it doesn't yet handle events of any type, i'm just poking and prodding the datagrid form to learn. change currentDay for a different start day, sunday to saturday. 1 to 7, then increment the current day and use that mod 7 to control what goes where. If mod 7 is 0 then its saturday, increment to the next record (tRecord)
For your template, just put the controls you want for each day, 7 times across the template, then that becomes a weeks "record."
As far as the datagrid goes, I think it probably will do what you need. I put together a quicky example for you to look at (in form mode not table mode), heres a screeny:
http://twitpic.com/n6fa3
At the moment theres not much to it, just a button with code I can modify to change the start day of the week, and number of days in the month, at which point it changes all the labels. For the schedule keeping area, I put a scrolling list for each day that should be easy enough to populate from an sqlite database, or array or properties or however you choose to do it. . Haven't implemented code for those parts yet, but shouldn't be too bad.
As you can see, my design skills aren't very good, and i'm still learning rev (will always still be learning rev)
In case you're interested, heres the code I put in the button to populate the calendar page. As I mentioned it doesn't yet handle events of any type, i'm just poking and prodding the datagrid form to learn. change currentDay for a different start day, sunday to saturday. 1 to 7, then increment the current day and use that mod 7 to control what goes where. If mod 7 is 0 then its saturday, increment to the next record (tRecord)
For your template, just put the controls you want for each day, 7 times across the template, then that becomes a weeks "record."
Code: Select all
global theDataA
on mouseUp
put empty into theDataA
put 1 into tRecord
put 3 into currentDay
repeat with i = 1 to 31
switch currentDay mod 7
case 1
put i into theDataA[tRecord]["sunLabel"]
break
case 2
put i into theDataA[tRecord]["monLabel"]
break
case 3
put i into theDataA[tRecord]["tuesLabel"]
break
case 4
put i into theDataA[tRecord]["wedLabel"]
break
case 5
put i into theDataA[tRecord]["thurLabel"]
break
case 6
put i into theDataA[tRecord]["friLabel"]
break
case 0
put i into theDataA[tRecord]["satLabel"]
add 1 to tRecord
break
end switch
add 1 to currentDay
end repeat
lock screen
set the dgData of group "Datagrid 1" to theDataA
unlock screen
end mouseUp
ibe wrote:I started out hoping the datagrid would work. In the form mode I can have only one column. For my calendar I need 7 columns and 5 rows. Thus I'd need 7 forms and then I would have to rewrite keyboard movement so that navigating by keyboard would be logical. Also I'd have to handle focus in and out so that the focus is only on one cell at a time.
Then I tried to use the data grid in table form but couldn't figure out how to have cells that contain formlike data (ie. several rows). If someone knows how to have several rows inside a cell in table mode I would like to know how to do it.
I've been playing around with my approach of a button and fields set into a group. I realized where I went wrong with the resizing, in my code I had
set the width of group tVarName to item 3 of lButtonRect - item 1 of lButtonRect
when I should have been addressing the individual elements of the grouped control as in:
set the width of field "Date" of group tVarName to item 3 of lButtonRect - item 1 of lButtonRect
now I have the controls moving and resizing properly. Next I have to figure out how to handle mouseDown and mouseDoubleDown so that the code is at the card level, not inside the grouped control. The card would handle knowing which date is selected and set the event information for all the days. Also the code in the card script would set the correct day numbers and disable the controls that don't belong to that month.
-
- Posts: 111
- Joined: Sun Aug 23, 2009 7:48 am
- Contact:
If you just want a month layout you can also have a look at the first tutorials provided with Revolution. (The ones you have in the "Getting Started" tab of the red start up stack)
If you want to continue with your first implementation, it should be possible to create and draw into an image and then set the icon of your button to that image.
If you want to continue with your first implementation, it should be possible to create and draw into an image and then set the icon of your button to that image.
Thanks sturgis. Is your calendar a datagrid in form mode and each row in the calendar is a row template that has 7 buttons on it? If so, does it resize automatically?
I'm actually quite happy with my implementation where I have an array of grouped buttons with controls in them. As in iCal, it resizes properly. the current day is shown with a light blue background and user selected dates are shown with a light gray background. You can see what it looks like in two different sizes at my website:
http://www.bergroth.fi/tmp/cal1.jpg
http://www.bergroth.fi/tmp/cal2.jpg
I've moved on to my next user interface problem which I would want to solve using a datagrid. My need is the following:
1. Item Energy Fat Protein Carbs
2. Breakfast
3. Kellog's Corn Flakes 112 kcal 2 g 1 g 16 g
4. Milk, 2%, 2 dl 40 kcal 0 g 8 g 0g
5. Lunch or whatever kind of long text I want here
6. Big Mac Meal, 1 portion 564 kcal 3 g 10 g 20 g
7. ....
Line 1 is just the column headers. No problem they work.
Line 2 and 5 are captions that I would like to have a background color for the entire line and even better is the text could continue into the second column and there would be no column lines between cells.
Line 3, 4 and 6 are data lines where I have actual data in other columns than the first. Column lines between cells are not needed (but don't matter if they exist). Columns do not have to be enabled for sorting but they do have to be resizable.
And I need scroll bars. I can make a mockup of this if the explanation isn't enough.
As before, I truly appreciate any insights on how to do this.
Thanks,
Ismo
I'm actually quite happy with my implementation where I have an array of grouped buttons with controls in them. As in iCal, it resizes properly. the current day is shown with a light blue background and user selected dates are shown with a light gray background. You can see what it looks like in two different sizes at my website:
http://www.bergroth.fi/tmp/cal1.jpg
http://www.bergroth.fi/tmp/cal2.jpg
I've moved on to my next user interface problem which I would want to solve using a datagrid. My need is the following:
1. Item Energy Fat Protein Carbs
2. Breakfast
3. Kellog's Corn Flakes 112 kcal 2 g 1 g 16 g
4. Milk, 2%, 2 dl 40 kcal 0 g 8 g 0g
5. Lunch or whatever kind of long text I want here
6. Big Mac Meal, 1 portion 564 kcal 3 g 10 g 20 g
7. ....
Line 1 is just the column headers. No problem they work.
Line 2 and 5 are captions that I would like to have a background color for the entire line and even better is the text could continue into the second column and there would be no column lines between cells.
Line 3, 4 and 6 are data lines where I have actual data in other columns than the first. Column lines between cells are not needed (but don't matter if they exist). Columns do not have to be enabled for sorting but they do have to be resizable.
And I need scroll bars. I can make a mockup of this if the explanation isn't enough.
As before, I truly appreciate any insights on how to do this.
Thanks,
Ismo
Edit: put my first app (first real, functional one) on rev online. Its name is Fun Calc, and uses 2 datagrids, a form and a table if you wanted to poke around with it.
Yes, my datagrid is a form, I have 7 labels across the top, non-opaque with a background, and underneath i'm using a listfield that could be populated with events (no code for that yet) Its pretty nice actually since you only need to handle the 1 row.
As for managing resizes, the best option would be to take direct control. When you select your datagrid and edit the behaviors, there is a LayoutControl section. Since I don't know what else is on the card etc I of course can't specify exactly how you'd go about setting this up, but since you can get the size of the stack and all other controls, you can use this section to determine how each control in your row template will be sized in relation to each other. On window resize, adjust the rect of the datagrid to where you want it, if I understand how this works, this will change the values in pControlRect that you can then use to set the size and positioning of all controls within the rect of pcontrolrect.
I'm sure its possible to use the geometry manager to handle at least some of this (to control the size of the datagrid itself?) But i've never had much luck with the geo manager. Things never seemed to behave the way I expect.
As for handling your other project with a datagrid, i'm sure there are many many ways to solve, but.. well, if you want to do it with a form, rather than the table datagrid (I have more experience with forms) one method would be to build up row template with 3 groups, and perhaps an option control with 3 choices that can be set. Option 1 header, option 2 catagory, option 3 data. The option would also specify what data controls on your entry form are allowed to be used to avoid confusion. 3 groups here, each with its own set of input controls.
At this point as you're entering your data, you set the option, and in LayoutControl test to see which option was chosen for that data set, showing the controls you want. When you are building your data array, the option chosen is also used to control where in the array the data goes so that its associated with the correct controls.
I'm sure there are other, probably better ways to do this, but should give you a start.
Tons of useful info here.
http://revolution.screenstepslive.com/s ... s/datagrid
An example of how to do disclosure style data controls, also an example in the documentation somewhere. Not really what you were asking, but should be able to use similar methods to show or not show whatever controls you want for each row.
Yes, my datagrid is a form, I have 7 labels across the top, non-opaque with a background, and underneath i'm using a listfield that could be populated with events (no code for that yet) Its pretty nice actually since you only need to handle the 1 row.
As for managing resizes, the best option would be to take direct control. When you select your datagrid and edit the behaviors, there is a LayoutControl section. Since I don't know what else is on the card etc I of course can't specify exactly how you'd go about setting this up, but since you can get the size of the stack and all other controls, you can use this section to determine how each control in your row template will be sized in relation to each other. On window resize, adjust the rect of the datagrid to where you want it, if I understand how this works, this will change the values in pControlRect that you can then use to set the size and positioning of all controls within the rect of pcontrolrect.
I'm sure its possible to use the geometry manager to handle at least some of this (to control the size of the datagrid itself?) But i've never had much luck with the geo manager. Things never seemed to behave the way I expect.
As for handling your other project with a datagrid, i'm sure there are many many ways to solve, but.. well, if you want to do it with a form, rather than the table datagrid (I have more experience with forms) one method would be to build up row template with 3 groups, and perhaps an option control with 3 choices that can be set. Option 1 header, option 2 catagory, option 3 data. The option would also specify what data controls on your entry form are allowed to be used to avoid confusion. 3 groups here, each with its own set of input controls.
At this point as you're entering your data, you set the option, and in LayoutControl test to see which option was chosen for that data set, showing the controls you want. When you are building your data array, the option chosen is also used to control where in the array the data goes so that its associated with the correct controls.
I'm sure there are other, probably better ways to do this, but should give you a start.
Tons of useful info here.
http://revolution.screenstepslive.com/s ... s/datagrid
An example of how to do disclosure style data controls, also an example in the documentation somewhere. Not really what you were asking, but should be able to use similar methods to show or not show whatever controls you want for each row.
Code: Select all
if theDataA["Expanded"] then
set the label of button "discloseButton" of me to "-"
else
set the label of button "discloseButton" of me to "+"
end if
repeat with i = 1 to the number of items in "label1,label2,label3,label4,label5,label6"
if field ("label" & i) of me = "" then
set the visible of field ("field" & i) of me to false
set the visible of field ("label" & i ) of me to false
else
set the visible of field ("field" & i ) of me to true
set the visible of field ("label" & i ) of me to true
end if
end repeat
set the visible of group "entryGroup" of me to theDataA["Expanded"]
set the visible of button "answerButton" of me to theDataA["Expanded"]
ibe wrote:Thanks sturgis. Is your calendar a datagrid in form mode and each row in the calendar is a row template that has 7 buttons on it? If so, does it resize automatically?
I'm actually quite happy with my implementation where I have an array of grouped buttons with controls in them. As in iCal, it resizes properly. the current day is shown with a light blue background and user selected dates are shown with a light gray background. You can see what it looks like in two different sizes at my website:
http://www.bergroth.fi/tmp/cal1.jpg
http://www.bergroth.fi/tmp/cal2.jpg
I've moved on to my next user interface problem which I would want to solve using a datagrid. My need is the following:
1. Item Energy Fat Protein Carbs
2. Breakfast
3. Kellog's Corn Flakes 112 kcal 2 g 1 g 16 g
4. Milk, 2%, 2 dl 40 kcal 0 g 8 g 0g
5. Lunch or whatever kind of long text I want here
6. Big Mac Meal, 1 portion 564 kcal 3 g 10 g 20 g
7. ....
Line 1 is just the column headers. No problem they work.
Line 2 and 5 are captions that I would like to have a background color for the entire line and even better is the text could continue into the second column and there would be no column lines between cells.
Line 3, 4 and 6 are data lines where I have actual data in other columns than the first. Column lines between cells are not needed (but don't matter if they exist). Columns do not have to be enabled for sorting but they do have to be resizable.
And I need scroll bars. I can make a mockup of this if the explanation isn't enough.
As before, I truly appreciate any insights on how to do this.
Thanks,
Ismo
Seems like a hard way to implement what I want. I made a mockup of what I need and it can be seen at:
http://www.bergroth.fi/tmp/dg.jpg
So I just need captions and datalines. The data cannot be edited by the user. I will either add or remove it through interaction with other controls. Having now played more with the datagrid, an acceptable solution would be if I could just change the background color of certain lines. Then I could just choose not to use vertical column lines and be happy with something that looks like this:
http://www.bergroth.fi/tmp/dg2.jpg
Then I also wouldn't have to code the column headers myself
http://www.bergroth.fi/tmp/dg.jpg
So I just need captions and datalines. The data cannot be edited by the user. I will either add or remove it through interaction with other controls. Having now played more with the datagrid, an acceptable solution would be if I could just change the background color of certain lines. Then I could just choose not to use vertical column lines and be happy with something that looks like this:
http://www.bergroth.fi/tmp/dg2.jpg
Then I also wouldn't have to code the column headers myself

I managed to fiddle around with the datagrid and now have the functionality I described in my earlier post. All that needed to be done was basically added this to FillInData:
if the dgLine of me is a section line
set the opaque of me to true
set the backgroundColor of me to 152, 206, 131
else
set the backgroundColor of me to empty
end if
And then in the grid itself I added a handler for the selectionChanged which basically hops over section lines if they are selected and goes to the next/previous data line automatically by calling
set the dgHilitedIndex of me to pHilitedIndex+ or -1
depending on which way the cursor is moving thereby totally skipping the section lines.
One item I didn't get though was how to get rid of column dividers totally. According to the datagrid docs there is a property "show column dividers" which can be set to false, but I just don't understand how the call should be made,
if the dgLine of me is a section line
set the opaque of me to true
set the backgroundColor of me to 152, 206, 131
else
set the backgroundColor of me to empty
end if
And then in the grid itself I added a handler for the selectionChanged which basically hops over section lines if they are selected and goes to the next/previous data line automatically by calling
set the dgHilitedIndex of me to pHilitedIndex+ or -1
depending on which way the cursor is moving thereby totally skipping the section lines.
One item I didn't get though was how to get rid of column dividers totally. According to the datagrid docs there is a property "show column dividers" which can be set to false, but I just don't understand how the call should be made,
Code: Select all
set the dgProps["show column dividers"] of group "DataGrid 1" to false
Thats exactly what i did but it seems that it doesn't work if called in FillInData of the grid. If I call it from the card, it works. I would have preferred keeping all the grid-related code inside itself.
Well, works as a reminder to try the same call from different place if it doesn't work at first.
Well, works as a reminder to try the same call from different place if it doesn't work at first.
Just to mess around, I setup a stack to do what I think you're talking about using a datagrid form.
Its setup to manage stack resizes pretty easily using the resizeStack handler in a stack script, there is a button that populates or resets the sample data, and the rest is all handled in the datagrid behavior script.
Column widths are handled automatically based on width of the stack, a disclosure button is available to hide and display sections.
If you're interested in looking at it, the stack can be found at
Edit: Try http://bonkersonline.info/stacks/ Theres a screeny there, and a nutrition stack. Forgot you can't link directly on that site (yet directory browsing is on? Go figure)
Its setup to manage stack resizes pretty easily using the resizeStack handler in a stack script, there is a button that populates or resets the sample data, and the rest is all handled in the datagrid behavior script.
Column widths are handled automatically based on width of the stack, a disclosure button is available to hide and display sections.
If you're interested in looking at it, the stack can be found at
Edit: Try http://bonkersonline.info/stacks/ Theres a screeny there, and a nutrition stack. Forgot you can't link directly on that site (yet directory browsing is on? Go figure)
ibe wrote:Thats exactly what i did but it seems that it doesn't work if called in FillInData of the grid. If I call it from the card, it works. I would have preferred keeping all the grid-related code inside itself.
Well, works as a reminder to try the same call from different place if it doesn't work at first.
Hi Sturgis,
thank you for the well commented example. I try to get my head around the datagrid. That helps.
To access the nutrition example one can typeinto the message box and the stack opens directly in Rev.
You might want to post a zip version for download. The present version just puts the text into the browser.
In your stack in RevOnline FunCalc whenever I close it it complains thatcannot be found. Otherwise another nice example of datagrid. I still have to take it apart and understand.
Thanks again
Bernd
thank you for the well commented example. I try to get my head around the datagrid. That helps.
To access the nutrition example one can type
Code: Select all
go stack url "http://bonkersonline.info/stacks/nutritionStack.rev"
You might want to post a zip version for download. The present version just puts the text into the browser.
In your stack in RevOnline FunCalc whenever I close it it complains that
Code: Select all
close stack "splashStack"
Thanks again
Bernd