def loaded_file_on_mouse_motion(self, event):
        """Act based on mouse motion event.

        Parameters
        ==========
        event
            pygame.event.Event object of type pygame.MOUSEMOTION
            or similar object.

        About the 'mouse_click_target' attribute
        ========================================

        Since we don't keep track of when the mouse
        leaves the boundaries of nodes or text blocks,
        in some rare cases the user might click one of
        these objects and immediately move the cursor
        away from the obj, making it so this attribute
        is left set to True, instead of being set to
        False and triggering the movement of objects.

        The only effect this will have is that the next
        time the user hover that object the movement
        will be triggered, but this is really rare
        behaviour and otherwise not considered
        bothersome enough to justify redesigning the
        app to track when the cursor exits the boundaries
        of such objects.
        """
        ### retrieve the mouse position
        mouse_pos = event.pos

        ### if the menu is hovered, we use it as the
        ### new loop holder in the application loop,
        ### by raising a special method, after we set
        ### the clicked_mouse flag to False, as an admin
        ### task

        if self.menubar.get_hovered_menu(mouse_pos):

            self.clicked_mouse = False

            raise SwitchLoopException(self.menubar)

        ### iterate over objects to check whether any of
        ### them was...
        ###
        ### - hovered by the mouse in this mouse motion event;
        ### - target of a previous mouse click event.
        ###
        ### if we find such object, we'll start moving it after
        ### we exit the for-loop
        ###
        ### for more information about the 'mouse_click_target' attribute
        ### of nodes and text blocks, used here, check the docstring of
        ### this method

        ## first, a few admin tasks

        # grab and populate a list of nodes that are on the screen

        nodes_on_screen = APP_REFS.gm.nodes_on_screen
        nodes_on_screen.extend(APP_REFS.gm.nodes.get_on_screen())

        # create a variable to hold the object if we find it
        obj_to_move = None

        ## now look for the object

        for obj in chain(
            nodes_on_screen,
            APP_REFS.gm.text_blocks.get_on_screen(),
        ):

            if (
                obj.rect.collidepoint(mouse_pos)
                and obj.mouse_click_target
            ):
                obj_to_move = obj
                break

        ### if we found such obj, start moving it after performing
        ### a few admin tasks

        if obj_to_move:

            # clean the collection of nodes on screen
            nodes_on_screen.clear()

            ## set the flag to False
            obj.mouse_click_target = False

            ## move object considering it is an target of a
            ## click and drag action
            APP_REFS.ea.move_from_click_and_drag(obj)

        ### if we reach this point in the method we know that objects
        ### weren't hovered in the "for loop" above because
        ### APP_REFS.ea.move_from_click_and_drag, among other things,
        ### also calls a method that raises an exception, causing the
        ### execution flow to leave this method when executed

        ### if neither the menu nor any object is hovered by the mouse,
        ### but the mouse was clicked before, it means we are dragging
        ### the mouse;
        ###
        ### depending on the state of modifier keys, this means the user
        ### wants to either:
        ###
        ### - cut segments between sockets
        ### - or begin defining a new segment between sockets
        ### - or perform a box selection

        if self.clicked_mouse:

            ## set the clicked_mouse flag to False,
            ## since we use it only to determine when
            ## we are dragging the mouse
            self.clicked_mouse = False

            ## obtain a bitmask which you'll use to check
            ## the state of modifier keys along the method
            bitmask = SERVICES_NS.get_pressed_mod_keys()

            ## if shift is pressed, exit method earlier, by returning,
            ## since there's nothing to be done in this scenario
            if bitmask & KMOD_SHIFT: return

            ## if ctrl is pressed, the user wants to cut segments between
            ## nodes

            if bitmask & KMOD_CTRL:
                APP_REFS.gm.trigger_segments_severance(mouse_pos)

            ## otherwise we must perform additional checks to determine
            ## what the user wants to do

            else:

                # if the periphery of a node collided with the mouse and
                # there was a socket close enough, we assume the user may
                # want to start defining a segment from the that socket
                #
                # if this is indeed the case, an exception will be raised on
                # purpose and the method will finish executing here
                APP_REFS.gm.start_defining_segment_if_close_to_socket(mouse_pos)

                # otherwise, we just assume the user wants to perform a box
                # selection
                APP_REFS.ea.start_box_selection()

        ### if the mouse wasn't clicked before, all that's left is to
        ### clear the collection of nodes on screen

        else:
            nodes_on_screen.clear()
Act based on mouse motion event.

        Parameters
        ==========
        event
            pygame.event.Event object of type pygame.MOUSEMOTION
            or similar object.

        About the 'mouse_click_target' attribute
        ========================================

        Since we don't keep track of when the mouse
        leaves the boundaries of nodes or text blocks,
        in some rare cases the user might click one of
        these objects and immediately move the cursor
        away from the obj, making it so this attribute
        is left set to True, instead of being set to
        False and triggering the movement of objects.

        The only effect this will have is that the next
        time the user hover that object the movement
        will be triggered, but this is really rare
        behaviour and otherwise not considered
        bothersome enough to justify redesigning the
        app to track when the cursor exits the boundaries
        of such objects.
        
nodezator/winman/states/loadedfile.py