Thư viện Widget
Đề bài
Mô tả
Ta xây dựng giao diện đồ hoạ bằng cách lồng các widget vào nhau. Mỗi widget chiếm một hình chữ nhật trên màn hình, có chiều rộng và chiều cao. Có ba loại widget:
- Widget: một widget cơ bản với chiều rộng và chiều cao cố định.
- HBox: một hộp chứa, xếp các widget con theo chiều ngang (từ trái sang phải).
- VBox: một hộp chứa, xếp các widget con theo chiều dọc (từ trên xuống dưới).
HBox và VBox có thể đóng gói (pack) các widget khác vào bên trong. Một widget có thể được đóng gói nhiều lần vào cùng một hộp, khi đó nó xuất hiện nhiều lần theo đúng thứ tự được pack. Khi pack chỉ lưu liên kết tới widget, nên nếu widget con thay đổi kích thước thì hộp chứa nó cũng thay đổi theo.
Mỗi HBox và VBox có hai tham số nguyên không âm: border (viền bao quanh tất cả widget con) và spacing (khoảng cách giữa hai widget con liền kề), mặc định đều bằng .
Kích thước của một hộp chứa (HBox hoặc VBox) đang chứa các widget con () với chiều rộng và chiều cao được tính như sau:
- HBox (xếp ngang):
- Chiều rộng:
- Chiều cao:
- VBox (xếp dọc):
- Chiều rộng:
- Chiều cao:
Nếu một HBox hoặc VBox không chứa widget con nào thì kích thước của nó là , bất kể border và spacing.
Cho mã lệnh mô tả quá trình tạo và lồng các widget, hãy tính kích thước cuối cùng của mọi widget.
Dữ liệu vào
Dòng đầu chứa số nguyên là số lệnh. dòng tiếp theo, mỗi dòng là một lệnh thuộc một trong các dạng sau:
Widget [name]([x],[y])— tạo widget cơ bản tên[name]có chiều rộng[x], chiều cao[y].HBox [name]— tạo một HBox tên[name].VBox [name]— tạo một VBox tên[name].[name1].pack([name2])— đóng gói widget[name2]vào[name1]([name1]phải là HBox hoặc VBox).[name].set_border([x])— đặt border của[name]bằng[x]([name]phải là HBox hoặc VBox).[name].set_spacing([x])— đặt spacing của[name]bằng[x]([name]phải là HBox hoặc VBox).
Các từ trong một lệnh cách nhau đúng một dấu cách, không có dấu cách thừa. Tên widget gồm các chữ cái Latin thường, dài từ đến ký tự và đôi một khác nhau. Mọi số trong mã lệnh là số nguyên từ đến .
Dữ liệu vào đảm bảo hợp lệ: mọi thao tác với một widget đều xảy ra sau khi widget đó đã được tạo, và không có widget nào được đóng gói vào chính nó (trực tiếp hoặc gián tiếp). Có ít nhất một widget được tạo.
Dữ liệu ra
Với mỗi widget, in ra một dòng gồm tên, chiều rộng và chiều cao của nó, cách nhau bởi dấu cách. Các dòng được sắp xếp theo thứ tự từ điển của tên widget.
Ràng buộc
- Tên widget dài từ đến ký tự, gồm chữ cái Latin thường.
- Mọi số trong mã lệnh nằm trong đoạn .
- Kết quả có thể rất lớn, cần dùng kiểu số nguyên 64-bit.
Ví dụ
| Input | Output | Giải thích |
|---|---|---|
| 12 Widget me(50,40) VBox grandpa HBox father grandpa.pack(father) father.pack(me) grandpa.set_border(10) grandpa.set_spacing(20) Widget brother(30,60) father.pack(brother) Widget friend(20,60) Widget uncle(100,20) grandpa.pack(uncle) |
brother 30 60 father 80 60 friend 20 60 grandpa 120 120 me 50 40 uncle 100 20 |
father là HBox chứa me (50,40) và brother (30,60): rộng , cao . grandpa là VBox chứa father (80,60) và uncle (100,20) với border 10, spacing 20: rộng , cao . friend không được pack vào đâu nên giữ nguyên. |
| 15 Widget pack(10,10) HBox dummy HBox x VBox y y.pack(dummy) y.set_border(5) y.set_spacing(55) dummy.set_border(10) dummy.set_spacing(20) x.set_border(10) x.set_spacing(10) x.pack(pack) x.pack(dummy) x.pack(pack) x.set_border(0) |
dummy 0 0 pack 10 10 x 40 10 y 10 10 |
dummy là HBox rỗng nên có kích thước dù đã đặt border/spacing. x là HBox chứa pack, dummy, pack với spacing 10, border cuối cùng đặt lại về 0: rộng , cao . y là VBox chứa dummy (0,0) với border 5: rộng , cao . |
Bình luận