extends Popup enum Position { ABOVE, BELOW } var line_edit : LineEdit setget _set_line_edit export(Position) var position = Position.BELOW ############# # overrides # ############# func _ready(): call_deferred("__setup") ################# # private stuff # ################# func __setup(): __connect() func __connect(): if !line_edit: return line_edit.connect("focus_entered", self, "_on_line_edit_focus_entered") line_edit.connect("focus_exited", self, "_on_line_edit_focus_exited") line_edit.connect("item_rect_changed", self, "_on_line_edit_item_rect_changed") line_edit.connect("resized", self, "_on_line_edit_resized") func __disconnect(): if !line_edit: return line_edit.disconnect("focus_entered", self, "_on_line_edit_focus_entered") line_edit.disconnect("focus_exited", self, "_on_line_edit_focus_exited") line_edit.disconnect("item_rect_changed", self, "_on_line_edit_item_rect_changed") line_edit.disconnect("resized", self, "_on_line_edit_resized") func __calc_rect() -> Rect2: var position_ = position var pos := line_edit.rect_global_position var vp_pos = get_viewport_rect().position var vp_size = get_viewport_rect().size var size := rect_min_size var le_size := line_edit.rect_size var max_height : float if pos.y + size.y > vp_size.y: position_ = Position.ABOVE elif pos.y < vp_pos.y: position_ = Position.BELOW if position_ == Position.ABOVE: max_height = pos.y - vp_pos.y else: max_height = (vp_pos.y + vp_size.y) - (pos.y + size.y) var res_size = Vector2(le_size.x, 100.0) if position_ == Position.ABOVE: return Rect2(pos - Vector2(0.0, res_size.y), res_size) else: return Rect2(pos + Vector2(0.0, size.y), res_size) func __update(): var should_be_visible = line_edit.has_focus() if !should_be_visible: hide() else: var rect := __calc_rect() if visible: rect_position = rect.position rect_size = rect.size else: popup(rect) ############ # handlers # ############ func _on_line_edit_focus_entered(): __update() func _on_line_edit_focus_exited(): hide() func _on_line_edit_item_rect_changed(): __update() func _on_line_edit_resized(): __update() ########### # setters # ########### func _set_line_edit(value : LineEdit): if value != line_edit: __disconnect() line_edit = value __connect()