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

Missing functionality? Clickline? Backgrounds? Shared Text fields #19

Open
everythingability opened this issue Oct 13, 2024 · 12 comments
Open

Comments

@everythingability
Copy link

While trying out Cardstock I notice a lot of the feaures of HyperCard that are missing...

OR I haven't rejigged my brain from gode ole HyperTalk into Python maybe? Dunno...

I mean it was a long time ago, but one of the things I did a lot with HyperCard was use it to create sort of "Note" collections and I would have a non-editable text field (on the background) and create a button to prompt for a card name, which then created that card, and then the code in the scrollable text field, when clicked would get the clicked line, pickup the text of that line and go to that card.

This way I could create a sort of indexed notepad...

From what I can see, the methods clickedLine, or get text of line field_1.clickedLine of field_1 doesn't really sort of exist in CardStock yet do they?

And also, there is no backgrounds are they? And so no "Shared text fields" to sort of remain on each background.

NOW I'M NOT SAYING that you should slavishly follow the make up and design of HyperCard, but there are some bits I think are worth not losing... which might include...

  • A sort of paint canvas - so I can use dithered fill tool - I know this is super retro, but some sort of "homage" or fun retro tools/effects might be good - (I think Decker goes too far in my opinion though)
  • A sort of collection of icons/resources in general for buttons etc.
  • Being able to set the fill_color of buttons, borderwidth etc would be nice
@benjie-git
Copy link
Owner

Great ideas, thank you!

• I love your point about getting text position of TextField clicks. I'm a little hesitant to just default to adding more event handlers, since a big goal of CardStock is simplicity and low barrier to entry. But maybe a good way to accomplish this would be a method on TextFields that converts a mouse position into a (line,position) tuple, with the idea that you could use this easily from inside an on_mouse_press(mouse_pos). I also realize that I should update TextField.selection to include line information instead of just a single character position value each for start and end positions of the current selection.

• I'll leave comments on the paint/canvas ideas on your previous issue.

• I completely agree on the collection of icons. I added integration with openclipart.org, but it's only an OK resource. I'd love to include a curated collection of icons to allow using in buttons, etc. But I'd need to find someone to help curate that collection. That's not a skill within my core competencies, as it were.

• I agree that it would be nice to allow buttons to have full color control. I held back on that due to thinking that maybe instead I should merge Rectangles, Round Rectangels, and Buttons into one object type. The downside would be that then I don't know where to fit in Radio and Checkbox buttons. Do you have thoughts on any of that?

@everythingability
Copy link
Author

Re: ClickLine: For the, the simplicity comes from the type ahead method suggestions. I guess it needs saying that a field also needs a text is selectable feature (so it can accept a click and hilite that line). I don't want to stress this too much. Maybe there's another way to do this, but the old HyperCard way worked well enough. i.e When you create a new card (with this button -> ask the card name, name the card, add that to a list of card (or go get the names of all the cards) and set the text of an indexListing field that can workout what line/text was clicked and then go to that line.

I guess it perhaps calls for a separate list object - which could be like a locked/clickable scroll text, or maybe a dropdown...tabs? That sort of thing.

Re: Paint canvas: I see you've looked at this elsewhere. My obvious use cases for the drawing areas are.

  • I just want to draw like a kid ... in a MacPaint-ish way. Simple...
  • I have some data (for example) and want to programmatically draw lines into a chart, or something - for example.

Re: Curated icons. Yeah. This is a tough one. The open clip art imo is a bit er, naff... In my head, I quite like the aesthetic of Susan Kare's stuff, in part because they're cohesive (whereas the open clip art is the opposite). Again, whilst wanting to ape what was great about HyperCard, it'd be daft to slavishly follow HyperCard, and maybe miss massive opportunities. For example, one might use spritesheets (something that are out there) or themes, or even sort of formulas for building components somehow. You might do a "deal" with the NounProject or similar? Maybe making this REALLY easy to extend so that someone like this https://egardepe.itch.io/hypercardgraphics might make a theme or collection like these https://itch.io/game-assets/free/tag-black-and-white or some such?

Incidentally, I "made" a HyperCard-like dithering app on websim. You're welcome to rip that off. When you import a pic, there could be a checkbox to go old skool maybe.

Re: Full color and button styling: The standard interface-ness of the radio/checkbox buttons suffer from not inheriting more properties, for example, I'd like to make the fontsize of all my radio buttons to be much bigger.

Once I discovered I could use a round rect, and group a text with it... to make a button, with text, with a nice fat border in yellow and purple, I realised I could kind of fake my way to what I wanted.

Sorry, banged on a bit. Great work. One last thing though... For me, the mistake most HyperCard clones make is sticking to the original too much... and not sort of continuing the work of Bill Atkinson, and sort of saying "What would would a HyperCard-ish software erector kit be today?". HyperCard never really handled HyperText, as in clickable links, and yet they came along and took over the world.... We have so many new concepts "just lying around" like authentication, APIs... type-ahead scrolling... touch support... desktop notiifcations, sending email even.

Did you ever play with RunRev's Revolution? It had some newer features, but got bogged down in them I think. They had sort of Groups which could behave like backgrounds, and whilst it was more powerful than HyperCard's backgrounds, they had odd side effects that I could never figure out. I used to use Revolution with students about 10 years ago to make Heritage museum / game things... and even then the verbosity of HyperTalk would at times piss me off - when simplicity becomes too complicated to deal with. :-)

@everythingability
Copy link
Author

image

Ah. On the subject of openclip art, I don't think it works in the web editor. I searched for "tree" and got...

image

@benjie-git
Copy link
Owner

This is an openclipart bug, where a search will return a bunch of pages of results, and the first few pages are blank. If you click '>>' a few times, you'll start to see results. Obviously this is not great. Maybe I could at least add in some messaging explaining this. I was planning to build a custom interface to openclipart, but was not sure I actually wanted to stick with that provider.

@benjie-git
Copy link
Owner

On the click line issue. I added text field methods to allow your use case:

  i = text_field.point_to_index(pt)
  pt = text_field.index_to_point(i)
  (r, c) = text_field.index_to_row_col(i)
  i = text_field.row_col_to_index(r, c)

so in an on_mouse_release handler, you could, for example:

on_mouse_release(mouse_pos):
  i = self.point_to_index(mouse_pos)  # get the index of the character clicked
  r,c = self.index_to_row_col(i)  # convert index to row (line number) and column (char index on that line)
  # then set the selection to go from the beginning of the clicked row, to the end of that row (one less than the index of the start of the next row)
  self.selection = (self.row_col_to_index(r,0), self.row_col_to_index(r+1,0)-1)

I hope this will allow you to build what you were aiming for!

Note that this is available in git, but not in a release yet, and is not up and running on the web version yet.

@everythingability
Copy link
Author

I will have a bash at compiling... see how I get on.

Am I correct that that code doesn't quite go the last mile, and change cards based on what line was clicked, is "i" the variable that would be the clickLine? in the top code block... it seems a long way from ...

on mouseup
    get the text of the clickline
    go to card result
end mouseup

That may be fantasy code, it was a long time ago... Also... Because you have no notion of a background, or shared fields I wouldn't be able to implement this as an index list navigator widget.

@benjie-git
Copy link
Owner

benjie-git commented Oct 18, 2024

I just added a new preview release including these changes here:
https://github.com/benjie-git/CardStock/releases/tag/v0.99.7_pre2

The following code will go to the card number of the clicked line+2 (which assumes that the first line (line 0) should go to card 2)

on_mouse_release(mouse_pos):
  (line, char) = self.index_to_row_col(self.point_to_index(mouse_pos))
  # first line is 0, second is 1.  Assume this list page is card 1, so a click on the first line should go to card 2
  goto_card(line+2)

Also, instead of the concept of card backgrounds, CardStock allows you to duplicate a card, and then edit it, all programmatically. Here's an example of what I think you're trying to do:

https://cardstock.run/stack/benjie/Diary

You can click [Edit] in the header to edit it, and can download it from there to run locally in the CardStock mac app.

@everythingability
Copy link
Author

Using the compiled from source version I tried to create my notional project...

A button with the onclick method of

def onclick(self):card_name = ask_text("New card...")
  index_list.text = index_list.text + "\n" + card_name
  
  card = stack.add_card(card_name)
  card.data['name'] = card_name # Can I use this later to lookup this card?
  goto_card(card)
  
  # create a back button
  y = stack.size.height - 50
  # 🔙
  back_button = card.add_button(name="Back", position=(10, 10), size=(48, 48))
  # set the script to go to card 1.
  
  #create title label field
  pos = (80, y)
  field = card.add_text_label(name="title", position=pos, size=(700, 80))
  field.text = card_name
  field.font_size = 42
  
  print("Creating card: ", card_name)
  
  # save Stack?

But it leaves me with some issues that may be unresolvable.
Firstly, there doesn't seems to be a stack.save() command - so that having created a card and added data (programmatically) I can save the stack.

  • Secondly, I don't know whether it'd be better to have a template card and duplicate that, or create a card and create all the objects on it. If I have to create everything with code, I will need to be able to add code to a newly created button, for example ...
back_button = card.add_button(name=" 🔙 ", position=(10, 10), size=(48, 48))
back_button.script.on_mouseup = "go_card(1)"

Note, the index_field code is now...

def on_mouse_release( self, mouse_pos):
  (line, char) = self.index_to_row_col(self.point_to_index(mouse_pos))
  goto_card(line+1)

So my notional app ALMOST works but hits the issues of ...

  • I can't save my stack - this is "the best bit" of HyperCard... that entered data/drawings etc can be saved.
  • I can't either use a template card (I don't think) or add code to a newly added object.
  • I can't set the name of a card. If I can't set the name of a card, how can I go to a card called "x"? If this is the case I can't alphabetize my index_list of card names because they can only go to card based on index of the clickedLIne . I looked at the card's data attribute so I might ...

card.data['name'] = card_name

But later on, would it be easy in the index_field to have code something like this...

def on_mouse_released( self, mouse_pos):
  (line, char) = self.index_to_row_col(self.point_to_index(mouse_pos))
  the_text_clicked = index_field.getLine( line) 
  goto_card(lthe_text_clicked)](url)

...if you get what I mean.

@everythingability
Copy link
Author

Another issue raised is... how might I add a stack script that watched for keydown... for example...

def on_keydown(self, key):
if key == NEXT_ARROW:
 go_next_card()
elif key == BACK_ARROW:
go_previous_card()
elif key == UP_ARROW:
  go_card(1)

@benjie-git
Copy link
Owner

There's no stack.save() function but if you set stack.can_save to True in the Designer, then when you run the stack, it will allow saving, and will prompt you to save when quitting, if there have been any changes. You can get to the stack's properties by clicking the Stack button in the Designer toolbar.

@benjie-git
Copy link
Owner

The current card receives on_key_press() events. So you can add code to those in your cards.

You can set up a card as a template card, and then run new_card = template_card.clone() to make a copy of it. This will add it immediately after the original card. You can then reorder the card with something like new_card.order_to_index(0)

You can add code to an object programmatically by calling, for example, my_button.set_code_for_event("on_click", "print('Click!')")

@benjie-git
Copy link
Owner

Currently you can set the name of a new object by including name="desired_name" in the call to card.clone() or stack.add_card(). But changing an object's name at runtime is not currently supported.

You could reorder the cards to be in alphabetic order by some common field's text. Or you could set up a card_map dictionary with a name -> index mapping, and use it to know which card to go to when a name is clicked.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants